Changeset 173269 in webkit


Ignore:
Timestamp:
Sep 4, 2014, 12:10:36 PM (11 years ago)
Author:
mark.lam@apple.com
Message:

Fixed indentations and some style warnings in JavaScriptCore/runtime.
<https://webkit.org/b/136518>

Reviewed by Michael Saboff.

Also removed some superflous spaces. There are no semantic changes.

  • runtime/Completion.h:
  • runtime/ConstructData.h:
  • runtime/DateConstructor.h:
  • runtime/DateInstance.h:
  • runtime/DateInstanceCache.h:
  • runtime/DatePrototype.h:
  • runtime/Error.h:
  • runtime/ErrorConstructor.h:
  • runtime/ErrorInstance.h:
  • runtime/ErrorPrototype.h:
  • runtime/FunctionConstructor.h:
  • runtime/FunctionPrototype.h:
  • runtime/GetterSetter.h:
  • runtime/Identifier.h:
  • runtime/InitializeThreading.h:
  • runtime/InternalFunction.h:
  • runtime/JSAPIValueWrapper.h:
  • runtime/JSFunction.h:
  • runtime/JSLock.h:
  • runtime/JSNotAnObject.h:
  • runtime/JSONObject.h:
  • runtime/JSString.h:
  • runtime/JSTypeInfo.h:
  • runtime/JSWrapperObject.h:
  • runtime/Lookup.h:
  • runtime/MathObject.h:
  • runtime/NativeErrorConstructor.h:
  • runtime/NativeErrorPrototype.h:
  • runtime/NumberConstructor.h:
  • runtime/NumberObject.h:
  • runtime/NumberPrototype.h:
  • runtime/NumericStrings.h:
  • runtime/ObjectConstructor.h:
  • runtime/ObjectPrototype.h:
  • runtime/PropertyDescriptor.h:
  • runtime/Protect.h:
  • runtime/PutPropertySlot.h:
  • runtime/RegExp.h:
  • runtime/RegExpCachedResult.h:
  • runtime/RegExpConstructor.h:
  • runtime/RegExpMatchesArray.h:
  • runtime/RegExpObject.h:
  • runtime/RegExpPrototype.h:
  • runtime/SmallStrings.h:
  • runtime/StringConstructor.h:
  • runtime/StringObject.h:
  • runtime/StringPrototype.h:
  • runtime/StructureChain.h:
  • runtime/VM.h:
Location:
trunk/Source/JavaScriptCore
Files:
50 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r173268 r173269  
     12014-09-04  Mark Lam  <mark.lam@apple.com>
     2
     3        Fixed indentations and some style warnings in JavaScriptCore/runtime.
     4        <https://webkit.org/b/136518>
     5
     6        Reviewed by Michael Saboff.
     7
     8        Also removed some superflous spaces.  There are no semantic changes.
     9
     10        * runtime/Completion.h:
     11        * runtime/ConstructData.h:
     12        * runtime/DateConstructor.h:
     13        * runtime/DateInstance.h:
     14        * runtime/DateInstanceCache.h:
     15        * runtime/DatePrototype.h:
     16        * runtime/Error.h:
     17        * runtime/ErrorConstructor.h:
     18        * runtime/ErrorInstance.h:
     19        * runtime/ErrorPrototype.h:
     20        * runtime/FunctionConstructor.h:
     21        * runtime/FunctionPrototype.h:
     22        * runtime/GetterSetter.h:
     23        * runtime/Identifier.h:
     24        * runtime/InitializeThreading.h:
     25        * runtime/InternalFunction.h:
     26        * runtime/JSAPIValueWrapper.h:
     27        * runtime/JSFunction.h:
     28        * runtime/JSLock.h:
     29        * runtime/JSNotAnObject.h:
     30        * runtime/JSONObject.h:
     31        * runtime/JSString.h:
     32        * runtime/JSTypeInfo.h:
     33        * runtime/JSWrapperObject.h:
     34        * runtime/Lookup.h:
     35        * runtime/MathObject.h:
     36        * runtime/NativeErrorConstructor.h:
     37        * runtime/NativeErrorPrototype.h:
     38        * runtime/NumberConstructor.h:
     39        * runtime/NumberObject.h:
     40        * runtime/NumberPrototype.h:
     41        * runtime/NumericStrings.h:
     42        * runtime/ObjectConstructor.h:
     43        * runtime/ObjectPrototype.h:
     44        * runtime/PropertyDescriptor.h:
     45        * runtime/Protect.h:
     46        * runtime/PutPropertySlot.h:
     47        * runtime/RegExp.h:
     48        * runtime/RegExpCachedResult.h:
     49        * runtime/RegExpConstructor.h:
     50        * runtime/RegExpMatchesArray.h:
     51        * runtime/RegExpObject.h:
     52        * runtime/RegExpPrototype.h:
     53        * runtime/SmallStrings.h:
     54        * runtime/StringConstructor.h:
     55        * runtime/StringObject.h:
     56        * runtime/StringPrototype.h:
     57        * runtime/StructureChain.h:
     58        * runtime/VM.h:
     59
    1602014-09-04  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
    261
  • trunk/Source/JavaScriptCore/runtime/Completion.h

    r149130 r173269  
    2828namespace JSC {
    2929   
    30     struct ParserError;
    31     class ExecState;
    32     class JSScope;
    33     class SourceCode;
    34     class VM;
     30struct ParserError;
     31class ExecState;
     32class JSScope;
     33class SourceCode;
     34class VM;
    3535
    36     JS_EXPORT_PRIVATE bool checkSyntax(VM&, const SourceCode&, ParserError&);
    37     JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
    38     JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue = JSValue(), JSValue* exception = 0);
     36JS_EXPORT_PRIVATE bool checkSyntax(VM&, const SourceCode&, ParserError&);
     37JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0);
     38JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue = JSValue(), JSValue* exception = 0);
    3939
    4040} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ConstructData.h

    r165676 r173269  
    3535namespace JSC {
    3636
    37     class ArgList;
    38     class ExecState;
    39     class FunctionExecutable;
    40     class JSObject;
    41     class JSScope;
     37class ArgList;
     38class ExecState;
     39class FunctionExecutable;
     40class JSObject;
     41class JSScope;
    4242
    43     enum ConstructType {
    44         ConstructTypeNone,
    45         ConstructTypeHost,
    46         ConstructTypeJS
    47     };
     43enum ConstructType {
     44    ConstructTypeNone,
     45    ConstructTypeHost,
     46    ConstructTypeJS
     47};
    4848
    49     union ConstructData {
    50         struct {
    51             NativeFunction function;
    52         } native;
    53         struct {
    54             FunctionExecutable* functionExecutable;
    55             JSScope* scope;
    56         } js;
    57     };
     49union ConstructData {
     50    struct {
     51        NativeFunction function;
     52    } native;
     53    struct {
     54        FunctionExecutable* functionExecutable;
     55        JSScope* scope;
     56    } js;
     57};
    5858
    59     JS_EXPORT_PRIVATE JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);
     59JS_EXPORT_PRIVATE JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);
    6060
    6161} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/DateConstructor.h

    r156624 r173269  
    2626namespace JSC {
    2727
    28     class DatePrototype;
     28class DatePrototype;
    2929
    30     class DateConstructor : public InternalFunction {
    31     public:
    32         typedef InternalFunction Base;
     30class DateConstructor : public InternalFunction {
     31public:
     32    typedef InternalFunction Base;
    3333
    34         static DateConstructor* create(VM& vm, Structure* structure, DatePrototype* datePrototype)
    35         {
    36             DateConstructor* constructor = new (NotNull, allocateCell<DateConstructor>(vm.heap)) DateConstructor(vm, structure);
    37             constructor->finishCreation(vm, datePrototype);
    38             return constructor;
    39         }
     34    static DateConstructor* create(VM& vm, Structure* structure, DatePrototype* datePrototype)
     35    {
     36        DateConstructor* constructor = new (NotNull, allocateCell<DateConstructor>(vm.heap)) DateConstructor(vm, structure);
     37        constructor->finishCreation(vm, datePrototype);
     38        return constructor;
     39    }
    4040
    41         DECLARE_INFO;
     41    DECLARE_INFO;
    4242
    43         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    44         {
    45             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    46         }
     43    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     44    {
     45        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     46    }
    4747
    48     protected:
    49         void finishCreation(VM&, DatePrototype*);
    50         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
     48protected:
     49    void finishCreation(VM&, DatePrototype*);
     50    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
    5151
    52     private:
    53         DateConstructor(VM&, Structure*);
    54         static ConstructType getConstructData(JSCell*, ConstructData&);
    55         static CallType getCallData(JSCell*, CallData&);
     52private:
     53    DateConstructor(VM&, Structure*);
     54    static ConstructType getConstructData(JSCell*, ConstructData&);
     55    static CallType getCallData(JSCell*, CallData&);
    5656
    57         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    58     };
     57    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     58};
    5959
    60     JSObject* constructDate(ExecState*, JSGlobalObject*, const ArgList&);
     60JSObject* constructDate(ExecState*, JSGlobalObject*, const ArgList&);
    6161
    6262} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/DateInstance.h

    r171391 r173269  
    2626namespace JSC {
    2727
    28     class DateInstance : public JSWrapperObject {
    29     protected:
    30         JS_EXPORT_PRIVATE DateInstance(VM&, Structure*);
    31         void finishCreation(VM&);
    32         JS_EXPORT_PRIVATE void finishCreation(VM&, double);
     28class DateInstance : public JSWrapperObject {
     29protected:
     30    JS_EXPORT_PRIVATE DateInstance(VM&, Structure*);
     31    void finishCreation(VM&);
     32    JS_EXPORT_PRIVATE void finishCreation(VM&, double);
    3333
    34         JS_EXPORT_PRIVATE static void destroy(JSCell*);
    35  
    36     public:
    37         typedef JSWrapperObject Base;
     34    JS_EXPORT_PRIVATE static void destroy(JSCell*);
    3835
    39         static DateInstance* create(VM& vm, Structure* structure, double date)
    40         {
    41             DateInstance* instance = new (NotNull, allocateCell<DateInstance>(vm.heap)) DateInstance(vm, structure);
    42             instance->finishCreation(vm, date);
    43             return instance;
    44         }
     36public:
     37    typedef JSWrapperObject Base;
    4538
    46         static DateInstance* create(VM& vm, Structure* structure)
    47         {
    48             DateInstance* instance = new (NotNull, allocateCell<DateInstance>(vm.heap)) DateInstance(vm, structure);
    49             instance->finishCreation(vm);
    50             return instance;
    51         }
     39    static DateInstance* create(VM& vm, Structure* structure, double date)
     40    {
     41        DateInstance* instance = new (NotNull, allocateCell<DateInstance>(vm.heap)) DateInstance(vm, structure);
     42        instance->finishCreation(vm, date);
     43        return instance;
     44    }
    5245
    53         double internalNumber() const { return internalValue().asNumber(); }
     46    static DateInstance* create(VM& vm, Structure* structure)
     47    {
     48        DateInstance* instance = new (NotNull, allocateCell<DateInstance>(vm.heap)) DateInstance(vm, structure);
     49        instance->finishCreation(vm);
     50        return instance;
     51    }
    5452
    55         DECLARE_EXPORT_INFO;
     53    double internalNumber() const { return internalValue().asNumber(); }
    5654
    57         const GregorianDateTime* gregorianDateTime(ExecState* exec) const
    58         {
    59             if (m_data && m_data->m_gregorianDateTimeCachedForMS == internalNumber())
    60                 return &m_data->m_cachedGregorianDateTime;
    61             return calculateGregorianDateTime(exec);
    62         }
    63        
    64         const GregorianDateTime* gregorianDateTimeUTC(ExecState* exec) const
    65         {
    66             if (m_data && m_data->m_gregorianDateTimeUTCCachedForMS == internalNumber())
    67                 return &m_data->m_cachedGregorianDateTimeUTC;
    68             return calculateGregorianDateTimeUTC(exec);
    69         }
     55    DECLARE_EXPORT_INFO;
    7056
    71         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    72         {
    73             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    74         }
     57    const GregorianDateTime* gregorianDateTime(ExecState* exec) const
     58    {
     59        if (m_data && m_data->m_gregorianDateTimeCachedForMS == internalNumber())
     60            return &m_data->m_cachedGregorianDateTime;
     61        return calculateGregorianDateTime(exec);
     62    }
    7563
    76     private:
    77         JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTime(ExecState*) const;
    78         JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const;
     64    const GregorianDateTime* gregorianDateTimeUTC(ExecState* exec) const
     65    {
     66        if (m_data && m_data->m_gregorianDateTimeUTCCachedForMS == internalNumber())
     67            return &m_data->m_cachedGregorianDateTimeUTC;
     68        return calculateGregorianDateTimeUTC(exec);
     69    }
    7970
    80         mutable RefPtr<DateInstanceData> m_data;
    81     };
     71    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     72    {
     73        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     74    }
    8275
    83     DateInstance* asDateInstance(JSValue);
     76private:
     77    JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTime(ExecState*) const;
     78    JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const;
    8479
    85     inline DateInstance* asDateInstance(JSValue value)
    86     {
    87         ASSERT(asObject(value)->inherits(DateInstance::info()));
    88         return static_cast<DateInstance*>(asObject(value));
    89     }
     80    mutable RefPtr<DateInstanceData> m_data;
     81};
     82
     83DateInstance* asDateInstance(JSValue);
     84
     85inline DateInstance* asDateInstance(JSValue value)
     86{
     87    ASSERT(asObject(value)->inherits(DateInstance::info()));
     88    return static_cast<DateInstance*>(asObject(value));
     89}
    9090
    9191} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/DateInstanceCache.h

    r167394 r173269  
    3636namespace JSC {
    3737
    38     class DateInstanceData : public RefCounted<DateInstanceData> {
    39     public:
    40         static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); }
     38class DateInstanceData : public RefCounted<DateInstanceData> {
     39public:
     40    static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); }
    4141
    42         double m_gregorianDateTimeCachedForMS;
    43         GregorianDateTime m_cachedGregorianDateTime;
    44         double m_gregorianDateTimeUTCCachedForMS;
    45         GregorianDateTime m_cachedGregorianDateTimeUTC;
     42    double m_gregorianDateTimeCachedForMS;
     43    GregorianDateTime m_cachedGregorianDateTime;
     44    double m_gregorianDateTimeUTCCachedForMS;
     45    GregorianDateTime m_cachedGregorianDateTimeUTC;
    4646
    47     private:
    48         DateInstanceData()
    49             : m_gregorianDateTimeCachedForMS(PNaN)
    50             , m_gregorianDateTimeUTCCachedForMS(PNaN)
    51         {
    52         }
     47private:
     48    DateInstanceData()
     49        : m_gregorianDateTimeCachedForMS(PNaN)
     50        , m_gregorianDateTimeUTCCachedForMS(PNaN)
     51    {
     52    }
     53};
     54
     55class DateInstanceCache {
     56public:
     57    DateInstanceCache()
     58    {
     59        reset();
     60    }
     61
     62    void reset()
     63    {
     64        for (size_t i = 0; i < cacheSize; ++i)
     65            m_cache[i].key = PNaN;
     66    }
     67
     68    DateInstanceData* add(double d)
     69    {
     70        CacheEntry& entry = lookup(d);
     71        if (d == entry.key)
     72            return entry.value.get();
     73
     74        entry.key = d;
     75        entry.value = DateInstanceData::create();
     76        return entry.value.get();
     77    }
     78
     79private:
     80    static const size_t cacheSize = 16;
     81
     82    struct CacheEntry {
     83        double key;
     84        RefPtr<DateInstanceData> value;
    5385    };
    5486
    55     class DateInstanceCache {
    56     public:
    57         DateInstanceCache()
    58         {
    59             reset();
    60         }
    61        
    62         void reset()
    63         {
    64             for (size_t i = 0; i < cacheSize; ++i)
    65                 m_cache[i].key = PNaN;
    66         }
    67        
    68         DateInstanceData* add(double d)
    69         {
    70             CacheEntry& entry = lookup(d);
    71             if (d == entry.key)
    72                 return entry.value.get();
     87    CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
    7388
    74             entry.key = d;
    75             entry.value = DateInstanceData::create();
    76             return entry.value.get();
    77         }
    78 
    79     private:
    80         static const size_t cacheSize = 16;
    81 
    82         struct CacheEntry {
    83             double key;
    84             RefPtr<DateInstanceData> value;
    85         };
    86 
    87         CacheEntry& lookup(double d) { return m_cache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
    88 
    89         std::array<CacheEntry, cacheSize> m_cache;
    90     };
     89    std::array<CacheEntry, cacheSize> m_cache;
     90};
    9191
    9292} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/DatePrototype.h

    r156620 r173269  
    2626namespace JSC {
    2727
    28     class ObjectPrototype;
     28class ObjectPrototype;
    2929
    30     class DatePrototype : public DateInstance {
    31     private:
    32         DatePrototype(VM&, Structure*);
     30class DatePrototype : public DateInstance {
     31private:
     32    DatePrototype(VM&, Structure*);
    3333
    34     public:
    35         typedef DateInstance Base;
     34public:
     35    typedef DateInstance Base;
    3636
    37         static DatePrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
    38         {
    39             DatePrototype* prototype = new (NotNull, allocateCell<DatePrototype>(vm.heap)) DatePrototype(vm, structure);
    40             prototype->finishCreation(vm, globalObject);
    41             return prototype;
    42         }
    43         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     37    static DatePrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     38    {
     39        DatePrototype* prototype = new (NotNull, allocateCell<DatePrototype>(vm.heap)) DatePrototype(vm, structure);
     40        prototype->finishCreation(vm, globalObject);
     41        return prototype;
     42    }
     43    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    4444
    45         DECLARE_INFO;
     45    DECLARE_INFO;
    4646
    47         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    48         {
    49             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    50         }
     47    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     48    {
     49        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     50    }
    5151
    52     protected:
    53         void finishCreation(VM&, JSGlobalObject*);
    54         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags;
    55     };
     52protected:
     53    void finishCreation(VM&, JSGlobalObject*);
     54    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags;
     55};
    5656
    5757} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/Error.h

    r165640 r173269  
    3131namespace JSC {
    3232
    33     class ExecState;
    34     class VM;
    35     class JSGlobalObject;
    36     class JSObject;
    37     class SourceCode;
    38     class Structure;
     33class ExecState;
     34class VM;
     35class JSGlobalObject;
     36class JSObject;
     37class SourceCode;
     38class Structure;
    3939
    40     // Methods to create a range of internal errors.
    41     JSObject* createError(JSGlobalObject*, const String&);
    42     JSObject* createEvalError(JSGlobalObject*, const String&);
    43     JSObject* createRangeError(JSGlobalObject*, const String&);
    44     JSObject* createReferenceError(JSGlobalObject*, const String&);
    45     JSObject* createSyntaxError(JSGlobalObject*, const String&);
    46     JSObject* createTypeError(JSGlobalObject*, const String&);
    47     JSObject* createNotEnoughArgumentsError(JSGlobalObject*);
    48     JSObject* createURIError(JSGlobalObject*, const String&);
    49     // ExecState wrappers.
    50     JS_EXPORT_PRIVATE JSObject* createError(ExecState*, const String&);
    51     JSObject* createEvalError(ExecState*, const String&);
    52     JS_EXPORT_PRIVATE JSObject* createRangeError(ExecState*, const String&);
    53     JS_EXPORT_PRIVATE JSObject* createReferenceError(ExecState*, const String&);
    54     JS_EXPORT_PRIVATE JSObject* createSyntaxError(ExecState*, const String&);
    55     JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*, const String&);
    56     JS_EXPORT_PRIVATE JSObject* createNotEnoughArgumentsError(ExecState*);
    57     JSObject* createURIError(ExecState*, const String&);
     40// Methods to create a range of internal errors.
     41JSObject* createError(JSGlobalObject*, const String&);
     42JSObject* createEvalError(JSGlobalObject*, const String&);
     43JSObject* createRangeError(JSGlobalObject*, const String&);
     44JSObject* createReferenceError(JSGlobalObject*, const String&);
     45JSObject* createSyntaxError(JSGlobalObject*, const String&);
     46JSObject* createTypeError(JSGlobalObject*, const String&);
     47JSObject* createNotEnoughArgumentsError(JSGlobalObject*);
     48JSObject* createURIError(JSGlobalObject*, const String&);
     49// ExecState wrappers.
     50JS_EXPORT_PRIVATE JSObject* createError(ExecState*, const String&);
     51JSObject* createEvalError(ExecState*, const String&);
     52JS_EXPORT_PRIVATE JSObject* createRangeError(ExecState*, const String&);
     53JS_EXPORT_PRIVATE JSObject* createReferenceError(ExecState*, const String&);
     54JS_EXPORT_PRIVATE JSObject* createSyntaxError(ExecState*, const String&);
     55JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*, const String&);
     56JS_EXPORT_PRIVATE JSObject* createNotEnoughArgumentsError(ExecState*);
     57JSObject* createURIError(ExecState*, const String&);
    5858
    59     // Methods to add
    60     bool hasErrorInfo(ExecState*, JSObject* error);
    61     // ExecState wrappers.
    62     JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&);
     59// Methods to add
     60bool hasErrorInfo(ExecState*, JSObject* error);
     61// ExecState wrappers.
     62JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&);
    6363
    64     // Methods to throw Errors.
     64// Methods to throw Errors.
    6565
    66     // Convenience wrappers, create an throw an exception with a default message.
    67     JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*);
    68     JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*);
     66// Convenience wrappers, create an throw an exception with a default message.
     67JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*);
     68JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*);
    6969
    70     // Convenience wrappers, wrap result as an EncodedJSValue.
    71     inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(exec->vm().throwException(exec, error)); }
    72     inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); }
    73     inline EncodedJSValue throwVMTypeError(ExecState* exec, const String& errorMessage) { return JSValue::encode(throwTypeError(exec, errorMessage)); }
    74    
    75     class StrictModeTypeErrorFunction : public InternalFunction {
    76     private:
    77         StrictModeTypeErrorFunction(VM& vm, Structure* structure, const String& message)
    78             : InternalFunction(vm, structure)
    79             , m_message(message)
    80         {
    81         }
     70// Convenience wrappers, wrap result as an EncodedJSValue.
     71inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(exec->vm().throwException(exec, error)); }
     72inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); }
     73inline EncodedJSValue throwVMTypeError(ExecState* exec, const String& errorMessage) { return JSValue::encode(throwTypeError(exec, errorMessage)); }
    8274
    83         static void destroy(JSCell*);
     75class StrictModeTypeErrorFunction : public InternalFunction {
     76private:
     77    StrictModeTypeErrorFunction(VM& vm, Structure* structure, const String& message)
     78        : InternalFunction(vm, structure)
     79        , m_message(message)
     80    {
     81    }
    8482
    85     public:
    86         typedef InternalFunction Base;
     83    static void destroy(JSCell*);
    8784
    88         static StrictModeTypeErrorFunction* create(VM& vm, Structure* structure, const String& message)
    89         {
    90             StrictModeTypeErrorFunction* function = new (NotNull, allocateCell<StrictModeTypeErrorFunction>(vm.heap)) StrictModeTypeErrorFunction(vm, structure, message);
    91             function->finishCreation(vm, String());
    92             return function;
    93         }
    94    
    95         static EncodedJSValue JSC_HOST_CALL constructThrowTypeError(ExecState* exec)
    96         {
    97             throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
    98             return JSValue::encode(jsNull());
    99         }
    100    
    101         static ConstructType getConstructData(JSCell*, ConstructData& constructData)
    102         {
    103             constructData.native.function = constructThrowTypeError;
    104             return ConstructTypeHost;
    105         }
    106    
    107         static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec)
    108         {
    109             throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
    110             return JSValue::encode(jsNull());
    111         }
     85public:
     86    typedef InternalFunction Base;
    11287
    113         static CallType getCallData(JSCell*, CallData& callData)
    114         {
    115             callData.native.function = callThrowTypeError;
    116             return CallTypeHost;
    117         }
     88    static StrictModeTypeErrorFunction* create(VM& vm, Structure* structure, const String& message)
     89    {
     90        StrictModeTypeErrorFunction* function = new (NotNull, allocateCell<StrictModeTypeErrorFunction>(vm.heap)) StrictModeTypeErrorFunction(vm, structure, message);
     91        function->finishCreation(vm, String());
     92        return function;
     93    }
    11894
    119         DECLARE_INFO;
     95    static EncodedJSValue JSC_HOST_CALL constructThrowTypeError(ExecState* exec)
     96    {
     97        throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
     98        return JSValue::encode(jsNull());
     99    }
    120100
    121         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    122         {
    123             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    124         }
     101    static ConstructType getConstructData(JSCell*, ConstructData& constructData)
     102    {
     103        constructData.native.function = constructThrowTypeError;
     104        return ConstructTypeHost;
     105    }
    125106
    126     private:
    127         String m_message;
    128     };
     107    static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec)
     108    {
     109        throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
     110        return JSValue::encode(jsNull());
     111    }
     112
     113    static CallType getCallData(JSCell*, CallData& callData)
     114    {
     115        callData.native.function = callThrowTypeError;
     116        return CallTypeHost;
     117    }
     118
     119    DECLARE_INFO;
     120
     121    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     122    {
     123        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     124    }
     125
     126private:
     127    String m_message;
     128};
    129129
    130130} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ErrorConstructor.h

    r156624 r173269  
    2727namespace JSC {
    2828
    29     class ErrorPrototype;
     29class ErrorPrototype;
    3030
    31     class ErrorConstructor : public InternalFunction {
    32     public:
    33         typedef InternalFunction Base;
     31class ErrorConstructor : public InternalFunction {
     32public:
     33    typedef InternalFunction Base;
    3434
    35         static ErrorConstructor* create(VM& vm, Structure* structure, ErrorPrototype* errorPrototype)
    36         {
    37             ErrorConstructor* constructor = new (NotNull, allocateCell<ErrorConstructor>(vm.heap)) ErrorConstructor(vm, structure);
    38             constructor->finishCreation(vm, errorPrototype);
    39             return constructor;
    40         }
     35    static ErrorConstructor* create(VM& vm, Structure* structure, ErrorPrototype* errorPrototype)
     36    {
     37        ErrorConstructor* constructor = new (NotNull, allocateCell<ErrorConstructor>(vm.heap)) ErrorConstructor(vm, structure);
     38        constructor->finishCreation(vm, errorPrototype);
     39        return constructor;
     40    }
    4141
    42         DECLARE_INFO;
     42    DECLARE_INFO;
    4343
    44         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    45         {
    46             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    47         }
     44    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     45    {
     46        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     47    }
    4848
    49     protected:
    50         void finishCreation(VM&, ErrorPrototype*);
     49protected:
     50    void finishCreation(VM&, ErrorPrototype*);
    5151       
    52     private:
    53         ErrorConstructor(VM&, Structure*);
    54         static ConstructType getConstructData(JSCell*, ConstructData&);
    55         static CallType getCallData(JSCell*, CallData&);
    56     };
     52private:
     53    ErrorConstructor(VM&, Structure*);
     54    static ConstructType getConstructData(JSCell*, ConstructData&);
     55    static CallType getCallData(JSCell*, CallData&);
     56};
    5757
    5858} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ErrorInstance.h

    r154038 r173269  
    2828namespace JSC {
    2929
    30     class ErrorInstance : public JSNonFinalObject {
    31     public:
    32         typedef JSNonFinalObject Base;
     30class ErrorInstance : public JSNonFinalObject {
     31public:
     32    typedef JSNonFinalObject Base;
    3333
    34         DECLARE_INFO;
     34    DECLARE_INFO;
    3535
    36         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    37         {
    38             return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
    39         }
     36    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     37    {
     38        return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
     39    }
    4040
    41         static ErrorInstance* create(VM& vm, Structure* structure, const String& message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
    42         {
    43             ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure);
    44             instance->finishCreation(vm, message, stackTrace);
    45             return instance;
    46         }
     41    static ErrorInstance* create(VM& vm, Structure* structure, const String& message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
     42    {
     43        ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure);
     44        instance->finishCreation(vm, message, stackTrace);
     45        return instance;
     46    }
    4747
    48         static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
    49         {
    50             return create(exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec), stackTrace);
    51         }
     48    static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message, Vector<StackFrame> stackTrace = Vector<StackFrame>())
     49    {
     50        return create(exec->vm(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec), stackTrace);
     51    }
    5252
    53         bool appendSourceToMessage() { return m_appendSourceToMessage; }
    54         void setAppendSourceToMessage() { m_appendSourceToMessage = true; }
    55         void clearAppendSourceToMessage() { m_appendSourceToMessage = false; }
     53    bool appendSourceToMessage() { return m_appendSourceToMessage; }
     54    void setAppendSourceToMessage() { m_appendSourceToMessage = true; }
     55    void clearAppendSourceToMessage() { m_appendSourceToMessage = false; }
    5656
    57     protected:
    58         explicit ErrorInstance(VM&, Structure*);
     57protected:
     58    explicit ErrorInstance(VM&, Structure*);
    5959
    60         void finishCreation(VM&, const String&, Vector<StackFrame> = Vector<StackFrame>());
     60    void finishCreation(VM&, const String&, Vector<StackFrame> = Vector<StackFrame>());
    6161
    62         bool m_appendSourceToMessage;
    63     };
     62    bool m_appendSourceToMessage;
     63};
    6464
    6565} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ErrorPrototype.h

    r156620 r173269  
    2626namespace JSC {
    2727
    28     class ObjectPrototype;
     28class ObjectPrototype;
    2929
    30     class ErrorPrototype : public ErrorInstance {
    31     public:
    32         typedef ErrorInstance Base;
     30class ErrorPrototype : public ErrorInstance {
     31public:
     32    typedef ErrorInstance Base;
    3333
    34         static ErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
    35         {
    36             ErrorPrototype* prototype = new (NotNull, allocateCell<ErrorPrototype>(vm.heap)) ErrorPrototype(vm, structure);
    37             prototype->finishCreation(vm, globalObject);
    38             return prototype;
    39         }
    40        
    41         DECLARE_INFO;
     34    static ErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     35    {
     36        ErrorPrototype* prototype = new (NotNull, allocateCell<ErrorPrototype>(vm.heap)) ErrorPrototype(vm, structure);
     37        prototype->finishCreation(vm, globalObject);
     38        return prototype;
     39    }
    4240
    43         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    44         {
    45             return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
    46         }
     41    DECLARE_INFO;
    4742
    48     protected:
    49         ErrorPrototype(VM&, Structure*);
    50         void finishCreation(VM&, JSGlobalObject*);
     43    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     44    {
     45        return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
     46    }
    5147
    52         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ErrorInstance::StructureFlags;
     48protected:
     49    ErrorPrototype(VM&, Structure*);
     50    void finishCreation(VM&, JSGlobalObject*);
    5351
    54     private:
    55         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    56     };
     52    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ErrorInstance::StructureFlags;
     53
     54private:
     55    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     56};
    5757
    5858} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/FunctionConstructor.h

    r156624 r173269  
    3030namespace JSC {
    3131
    32     class FunctionPrototype;
     32class FunctionPrototype;
    3333
    34     class FunctionConstructor : public InternalFunction {
    35     public:
    36         typedef InternalFunction Base;
     34class FunctionConstructor : public InternalFunction {
     35public:
     36    typedef InternalFunction Base;
    3737
    38         static FunctionConstructor* create(VM& vm, Structure* structure, FunctionPrototype* functionPrototype)
    39         {
    40             FunctionConstructor* constructor = new (NotNull, allocateCell<FunctionConstructor>(vm.heap)) FunctionConstructor(vm, structure);
    41             constructor->finishCreation(vm, functionPrototype);
    42             return constructor;
    43         }
     38    static FunctionConstructor* create(VM& vm, Structure* structure, FunctionPrototype* functionPrototype)
     39    {
     40        FunctionConstructor* constructor = new (NotNull, allocateCell<FunctionConstructor>(vm.heap)) FunctionConstructor(vm, structure);
     41        constructor->finishCreation(vm, functionPrototype);
     42        return constructor;
     43    }
    4444
    45         DECLARE_INFO;
     45    DECLARE_INFO;
    4646
    47         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    48         {
    49             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    50         }
     47    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     48    {
     49        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     50    }
    5151
    52     private:
    53         FunctionConstructor(VM&, Structure*);
    54         void finishCreation(VM&, FunctionPrototype*);
    55         static ConstructType getConstructData(JSCell*, ConstructData&);
    56         static CallType getCallData(JSCell*, CallData&);
    57     };
     52private:
     53    FunctionConstructor(VM&, Structure*);
     54    void finishCreation(VM&, FunctionPrototype*);
     55    static ConstructType getConstructData(JSCell*, ConstructData&);
     56    static CallType getCallData(JSCell*, CallData&);
     57};
    5858
    59     JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const String& sourceURL, const WTF::TextPosition&);
    60     JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&);
     59JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const String& sourceURL, const WTF::TextPosition&);
     60JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&);
    6161
    62     JS_EXPORT_PRIVATE JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, const String&, const WTF::TextPosition&);
     62JS_EXPORT_PRIVATE JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, const String&, const WTF::TextPosition&);
    6363
    6464} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/FunctionPrototype.h

    r156624 r173269  
    2626namespace JSC {
    2727
    28     class FunctionPrototype : public InternalFunction {
    29     public:
    30         typedef InternalFunction Base;
     28class FunctionPrototype : public InternalFunction {
     29public:
     30    typedef InternalFunction Base;
    3131
    32         static FunctionPrototype* create(VM& vm, Structure* structure)
    33         {
    34             FunctionPrototype* prototype = new (NotNull, allocateCell<FunctionPrototype>(vm.heap)) FunctionPrototype(vm, structure);
    35             prototype->finishCreation(vm, String());
    36             return prototype;
    37         }
    38        
    39         void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction);
    40        
    41         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
    42         {
    43             return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
    44         }
     32    static FunctionPrototype* create(VM& vm, Structure* structure)
     33    {
     34        FunctionPrototype* prototype = new (NotNull, allocateCell<FunctionPrototype>(vm.heap)) FunctionPrototype(vm, structure);
     35        prototype->finishCreation(vm, String());
     36        return prototype;
     37    }
    4538
    46         DECLARE_INFO;
     39    void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction);
    4740
    48     protected:
    49         void finishCreation(VM&, const String& name);
     41    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
     42    {
     43        return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
     44    }
    5045
    51     private:
    52         FunctionPrototype(VM&, Structure*);
    53         static CallType getCallData(JSCell*, CallData&);
    54     };
     46    DECLARE_INFO;
     47
     48protected:
     49    void finishCreation(VM&, const String& name);
     50
     51private:
     52    FunctionPrototype(VM&, Structure*);
     53    static CallType getCallData(JSCell*, CallData&);
     54};
    5555
    5656} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/GetterSetter.h

    r172129 r173269  
    3131namespace JSC {
    3232
    33     class JSObject;
     33class JSObject;
    3434
    35     // This is an internal value object which stores getter and setter functions
    36     // for a property. Instances of this class have the property that once a getter
    37     // or setter is set to a non-null value, then they cannot be changed. This means
    38     // that if a property holding a GetterSetter reference is constant-inferred and
    39     // that constant is observed to have a non-null setter (or getter) then we can
    40     // constant fold that setter (or getter).
    41     class GetterSetter : public JSCell {
    42         friend class JIT;
     35// This is an internal value object which stores getter and setter functions
     36// for a property. Instances of this class have the property that once a getter
     37// or setter is set to a non-null value, then they cannot be changed. This means
     38// that if a property holding a GetterSetter reference is constant-inferred and
     39// that constant is observed to have a non-null setter (or getter) then we can
     40// constant fold that setter (or getter).
     41class GetterSetter : public JSCell {
     42    friend class JIT;
    4343
    44     private:       
    45         GetterSetter(VM& vm)
    46             : JSCell(vm, vm.getterSetterStructure.get())
    47         {
    48         }
    49 
    50     public:
    51         typedef JSCell Base;
    52 
    53         static GetterSetter* create(VM& vm)
    54         {
    55             GetterSetter* getterSetter = new (NotNull, allocateCell<GetterSetter>(vm.heap)) GetterSetter(vm);
    56             getterSetter->finishCreation(vm);
    57             return getterSetter;
    58         }
    59 
    60         static void visitChildren(JSCell*, SlotVisitor&);
    61 
    62         JSObject* getter() const { return m_getter.get(); }
    63        
    64         JSObject* getterConcurrently() const
    65         {
    66             JSObject* result = getter();
    67             WTF::loadLoadFence();
    68             return result;
    69         }
    70        
    71         // Set the getter. It's only valid to call this if you've never set the getter on this
    72         // object.
    73         void setGetter(VM& vm, JSObject* getter)
    74         {
    75             RELEASE_ASSERT(!m_getter);
    76             WTF::storeStoreFence();
    77             m_getter.setMayBeNull(vm, this, getter);
    78         }
    79        
    80         JSObject* setter() const { return m_setter.get(); }
    81        
    82         JSObject* setterConcurrently() const
    83         {
    84             JSObject* result = setter();
    85             WTF::loadLoadFence();
    86             return result;
    87         }
    88        
    89         // Set the setter. It's only valid to call this if you've never set the setter on this
    90         // object.
    91         void setSetter(VM& vm, JSObject* setter)
    92         {
    93             RELEASE_ASSERT(!m_setter);
    94             WTF::storeStoreFence();
    95             m_setter.setMayBeNull(vm, this, setter);
    96         }
    97        
    98         GetterSetter* withGetter(VM&, JSObject* getter);
    99         GetterSetter* withSetter(VM&, JSObject* setter);
    100        
    101         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    102         {
    103             return Structure::create(vm, globalObject, prototype, TypeInfo(GetterSetterType), info());
    104         }
    105        
    106         static ptrdiff_t offsetOfGetter()
    107         {
    108             return OBJECT_OFFSETOF(GetterSetter, m_getter);
    109         }
    110        
    111         static ptrdiff_t offsetOfSetter()
    112         {
    113             return OBJECT_OFFSETOF(GetterSetter, m_setter);
    114         }
    115        
    116         DECLARE_INFO;
    117 
    118     private:
    119         WriteBarrier<JSObject> m_getter;
    120         WriteBarrier<JSObject> m_setter; 
    121     };
    122 
    123     GetterSetter* asGetterSetter(JSValue);
    124 
    125     inline GetterSetter* asGetterSetter(JSValue value)
     44private:       
     45    GetterSetter(VM& vm)
     46        : JSCell(vm, vm.getterSetterStructure.get())
    12647    {
    127         ASSERT_WITH_SECURITY_IMPLICATION(value.asCell()->isGetterSetter());
    128         return static_cast<GetterSetter*>(value.asCell());
    12948    }
    13049
    131     JSValue callGetter(ExecState*, JSValue base, JSValue getterSetter);
    132     void callSetter(ExecState*, JSValue base, JSValue getterSetter, JSValue value, ECMAMode);
     50public:
     51    typedef JSCell Base;
     52
     53    static GetterSetter* create(VM& vm)
     54    {
     55        GetterSetter* getterSetter = new (NotNull, allocateCell<GetterSetter>(vm.heap)) GetterSetter(vm);
     56        getterSetter->finishCreation(vm);
     57        return getterSetter;
     58    }
     59
     60    static void visitChildren(JSCell*, SlotVisitor&);
     61
     62    JSObject* getter() const { return m_getter.get(); }
     63
     64    JSObject* getterConcurrently() const
     65    {
     66        JSObject* result = getter();
     67        WTF::loadLoadFence();
     68        return result;
     69    }
     70
     71    // Set the getter. It's only valid to call this if you've never set the getter on this
     72    // object.
     73    void setGetter(VM& vm, JSObject* getter)
     74    {
     75        RELEASE_ASSERT(!m_getter);
     76        WTF::storeStoreFence();
     77        m_getter.setMayBeNull(vm, this, getter);
     78    }
     79
     80    JSObject* setter() const { return m_setter.get(); }
     81
     82    JSObject* setterConcurrently() const
     83    {
     84        JSObject* result = setter();
     85        WTF::loadLoadFence();
     86        return result;
     87    }
     88
     89    // Set the setter. It's only valid to call this if you've never set the setter on this
     90    // object.
     91    void setSetter(VM& vm, JSObject* setter)
     92    {
     93        RELEASE_ASSERT(!m_setter);
     94        WTF::storeStoreFence();
     95        m_setter.setMayBeNull(vm, this, setter);
     96    }
     97
     98    GetterSetter* withGetter(VM&, JSObject* getter);
     99    GetterSetter* withSetter(VM&, JSObject* setter);
     100
     101    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     102    {
     103        return Structure::create(vm, globalObject, prototype, TypeInfo(GetterSetterType), info());
     104    }
     105
     106    static ptrdiff_t offsetOfGetter()
     107    {
     108        return OBJECT_OFFSETOF(GetterSetter, m_getter);
     109    }
     110
     111    static ptrdiff_t offsetOfSetter()
     112    {
     113        return OBJECT_OFFSETOF(GetterSetter, m_setter);
     114    }
     115
     116    DECLARE_INFO;
     117
     118private:
     119    WriteBarrier<JSObject> m_getter;
     120    WriteBarrier<JSObject> m_setter; 
     121};
     122
     123GetterSetter* asGetterSetter(JSValue);
     124
     125inline GetterSetter* asGetterSetter(JSValue value)
     126{
     127    ASSERT_WITH_SECURITY_IMPLICATION(value.asCell()->isGetterSetter());
     128    return static_cast<GetterSetter*>(value.asCell());
     129}
     130
     131JSValue callGetter(ExecState*, JSValue base, JSValue getterSetter);
     132void callSetter(ExecState*, JSValue base, JSValue getterSetter, JSValue, ECMAMode);
    133133
    134134} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/Identifier.h

    r172129 r173269  
    3030namespace JSC {
    3131
    32     class ExecState;
    33 
    34     class Identifier {
    35         friend class Structure;
    36     public:
    37         Identifier() { }
    38         enum EmptyIdentifierFlag { EmptyIdentifier };
    39         Identifier(EmptyIdentifierFlag) : m_string(StringImpl::empty()) { ASSERT(m_string.impl()->isAtomic()); }
    40 
    41         // Only to be used with string literals.
    42         template<unsigned charactersCount>
    43         Identifier(ExecState* exec, const char (&characters)[charactersCount]) : m_string(add(exec, characters)) { ASSERT(m_string.impl()->isAtomic()); }
    44         template<unsigned charactersCount>
    45         Identifier(VM* vm, const char (&characters)[charactersCount]) : m_string(add(vm, characters)) { ASSERT(m_string.impl()->isAtomic()); }
    46 
    47         Identifier(ExecState* exec, StringImpl* rep) : m_string(add(exec, rep)) { ASSERT(m_string.impl()->isAtomic()); }
    48         Identifier(ExecState* exec, const String& s) : m_string(add(exec, s.impl())) { ASSERT(m_string.impl()->isAtomic()); }
    49 
    50         Identifier(VM* vm, const LChar* s, int length) : m_string(add(vm, s, length)) { ASSERT(m_string.impl()->isAtomic()); }
    51         Identifier(VM* vm, const UChar* s, int length) : m_string(add(vm, s, length)) { ASSERT(m_string.impl()->isAtomic()); }
    52         Identifier(VM* vm, StringImpl* rep) : m_string(add(vm, rep)) { ASSERT(m_string.impl()->isAtomic()); }
    53         Identifier(VM* vm, const String& s) : m_string(add(vm, s.impl())) { ASSERT(m_string.impl()->isAtomic()); }
    54 
    55         const String& string() const { return m_string; }
    56         StringImpl* impl() const { return m_string.impl(); }
    57        
    58         int length() const { return m_string.length(); }
    59        
    60         CString ascii() const { return m_string.ascii(); }
    61         CString utf8() const { return m_string.utf8(); }
    62        
    63         static Identifier from(const PrivateName& name)
    64         {
    65             Identifier result;
    66             result.m_string = name.uid();
    67             return result;
    68         }
    69 
    70         static Identifier createLCharFromUChar(VM* vm, const UChar* s, int length) { return Identifier(vm, add8(vm, s, length)); }
    71 
    72         JS_EXPORT_PRIVATE static Identifier from(ExecState* exec, unsigned y);
    73         JS_EXPORT_PRIVATE static Identifier from(ExecState* exec, int y);
    74         static Identifier from(ExecState* exec, double y);
    75         static Identifier from(VM*, unsigned y);
    76         static Identifier from(VM*, int y);
    77         static Identifier from(VM*, double y);
    78 
    79         bool isNull() const { return m_string.isNull(); }
    80         bool isEmpty() const { return m_string.isEmpty(); }
    81        
    82         friend bool operator==(const Identifier&, const Identifier&);
    83         friend bool operator!=(const Identifier&, const Identifier&);
    84 
    85         friend bool operator==(const Identifier&, const LChar*);
    86         friend bool operator==(const Identifier&, const char*);
    87         friend bool operator!=(const Identifier&, const LChar*);
    88         friend bool operator!=(const Identifier&, const char*);
    89    
    90         static bool equal(const StringImpl*, const LChar*);
    91         static inline bool equal(const StringImpl*a, const char*b) { return Identifier::equal(a, reinterpret_cast<const LChar*>(b)); };
    92         static bool equal(const StringImpl*, const LChar*, unsigned length);
    93         static bool equal(const StringImpl*, const UChar*, unsigned length);
    94         static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); }
    95 
    96         // Only to be used with string literals.
    97         JS_EXPORT_PRIVATE static PassRef<StringImpl> add(VM*, const char*);
    98         JS_EXPORT_PRIVATE static PassRef<StringImpl> add(ExecState*, const char*);
    99        
    100         void dump(PrintStream&) const;
    101 
    102     private:
    103         String m_string;
    104 
    105         template <typename CharType>
    106         ALWAYS_INLINE static uint32_t toUInt32FromCharacters(const CharType* characters, unsigned length, bool& ok);
    107 
    108         static bool equal(const Identifier& a, const Identifier& b) { return a.m_string.impl() == b.m_string.impl(); }
    109         static bool equal(const Identifier& a, const LChar* b) { return equal(a.m_string.impl(), b); }
    110 
    111         template <typename T> static PassRef<StringImpl> add(VM*, const T*, int length);
    112         static PassRef<StringImpl> add8(VM*, const UChar*, int length);
    113         template <typename T> ALWAYS_INLINE static bool canUseSingleCharacterString(T);
    114 
    115         static PassRef<StringImpl> add(ExecState*, StringImpl*);
    116         static PassRef<StringImpl> add(VM*, StringImpl*);
     32class ExecState;
     33
     34class Identifier {
     35    friend class Structure;
     36public:
     37    Identifier() { }
     38    enum EmptyIdentifierFlag { EmptyIdentifier };
     39    Identifier(EmptyIdentifierFlag) : m_string(StringImpl::empty()) { ASSERT(m_string.impl()->isAtomic()); }
     40
     41    // Only to be used with string literals.
     42    template<unsigned charactersCount>
     43    Identifier(ExecState* exec, const char (&characters)[charactersCount]) : m_string(add(exec, characters)) { ASSERT(m_string.impl()->isAtomic()); }
     44    template<unsigned charactersCount>
     45    Identifier(VM* vm, const char (&characters)[charactersCount]) : m_string(add(vm, characters)) { ASSERT(m_string.impl()->isAtomic()); }
     46
     47    Identifier(ExecState* exec, StringImpl* rep) : m_string(add(exec, rep)) { ASSERT(m_string.impl()->isAtomic()); }
     48    Identifier(ExecState* exec, const String& s) : m_string(add(exec, s.impl())) { ASSERT(m_string.impl()->isAtomic()); }
     49
     50    Identifier(VM* vm, const LChar* s, int length) : m_string(add(vm, s, length)) { ASSERT(m_string.impl()->isAtomic()); }
     51    Identifier(VM* vm, const UChar* s, int length) : m_string(add(vm, s, length)) { ASSERT(m_string.impl()->isAtomic()); }
     52    Identifier(VM* vm, StringImpl* rep) : m_string(add(vm, rep)) { ASSERT(m_string.impl()->isAtomic()); }
     53    Identifier(VM* vm, const String& s) : m_string(add(vm, s.impl())) { ASSERT(m_string.impl()->isAtomic()); }
     54
     55    const String& string() const { return m_string; }
     56    StringImpl* impl() const { return m_string.impl(); }
     57
     58    int length() const { return m_string.length(); }
     59
     60    CString ascii() const { return m_string.ascii(); }
     61    CString utf8() const { return m_string.utf8(); }
     62
     63    static Identifier from(const PrivateName& name)
     64    {
     65        Identifier result;
     66        result.m_string = name.uid();
     67        return result;
     68    }
     69
     70    static Identifier createLCharFromUChar(VM* vm, const UChar* s, int length) { return Identifier(vm, add8(vm, s, length)); }
     71
     72    JS_EXPORT_PRIVATE static Identifier from(ExecState*, unsigned y);
     73    JS_EXPORT_PRIVATE static Identifier from(ExecState*, int y);
     74    static Identifier from(ExecState*, double y);
     75    static Identifier from(VM*, unsigned y);
     76    static Identifier from(VM*, int y);
     77    static Identifier from(VM*, double y);
     78
     79    bool isNull() const { return m_string.isNull(); }
     80    bool isEmpty() const { return m_string.isEmpty(); }
     81
     82    friend bool operator==(const Identifier&, const Identifier&);
     83    friend bool operator!=(const Identifier&, const Identifier&);
     84
     85    friend bool operator==(const Identifier&, const LChar*);
     86    friend bool operator==(const Identifier&, const char*);
     87    friend bool operator!=(const Identifier&, const LChar*);
     88    friend bool operator!=(const Identifier&, const char*);
     89
     90    static bool equal(const StringImpl*, const LChar*);
     91    static inline bool equal(const StringImpl*a, const char*b) { return Identifier::equal(a, reinterpret_cast<const LChar*>(b)); };
     92    static bool equal(const StringImpl*, const LChar*, unsigned length);
     93    static bool equal(const StringImpl*, const UChar*, unsigned length);
     94    static bool equal(const StringImpl* a, const StringImpl* b) { return ::equal(a, b); }
     95
     96    // Only to be used with string literals.
     97    JS_EXPORT_PRIVATE static PassRef<StringImpl> add(VM*, const char*);
     98    JS_EXPORT_PRIVATE static PassRef<StringImpl> add(ExecState*, const char*);
     99
     100    void dump(PrintStream&) const;
     101
     102private:
     103    String m_string;
     104
     105    template <typename CharType>
     106    ALWAYS_INLINE static uint32_t toUInt32FromCharacters(const CharType* characters, unsigned length, bool& ok);
     107
     108    static bool equal(const Identifier& a, const Identifier& b) { return a.m_string.impl() == b.m_string.impl(); }
     109    static bool equal(const Identifier& a, const LChar* b) { return equal(a.m_string.impl(), b); }
     110
     111    template <typename T> static PassRef<StringImpl> add(VM*, const T*, int length);
     112    static PassRef<StringImpl> add8(VM*, const UChar*, int length);
     113    template <typename T> ALWAYS_INLINE static bool canUseSingleCharacterString(T);
     114
     115    static PassRef<StringImpl> add(ExecState*, StringImpl*);
     116    static PassRef<StringImpl> add(VM*, StringImpl*);
    117117
    118118#ifndef NDEBUG
    119         JS_EXPORT_PRIVATE static void checkCurrentAtomicStringTable(ExecState*);
    120         JS_EXPORT_PRIVATE static void checkCurrentAtomicStringTable(VM*);
     119    JS_EXPORT_PRIVATE static void checkCurrentAtomicStringTable(ExecState*);
     120    JS_EXPORT_PRIVATE static void checkCurrentAtomicStringTable(VM*);
    121121#else
    122         JS_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH static void checkCurrentAtomicStringTable(ExecState*);
    123         JS_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH static void checkCurrentAtomicStringTable(VM*);
     122    JS_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH static void checkCurrentAtomicStringTable(ExecState*);
     123    JS_EXPORT_PRIVATE NO_RETURN_DUE_TO_CRASH static void checkCurrentAtomicStringTable(VM*);
    124124#endif
    125     };
    126 
    127     template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(LChar)
    128     {
    129         ASSERT(maxSingleCharacterString == 0xff);
    130         return true;
     125};
     126
     127template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(LChar)
     128{
     129    ASSERT(maxSingleCharacterString == 0xff);
     130    return true;
     131}
     132
     133template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(UChar c)
     134{
     135    return (c <= maxSingleCharacterString);
     136}
     137
     138template <typename T>
     139PassRef<StringImpl> Identifier::add(VM* vm, const T* s, int length)
     140{
     141    if (length == 1) {
     142        T c = s[0];
     143        if (canUseSingleCharacterString(c))
     144            return *vm->smallStrings.singleCharacterStringRep(c);
    131145    }
    132 
    133     template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(UChar c)
    134     {
    135         return (c <= maxSingleCharacterString);
    136     }
    137 
    138     template <typename T>
    139     PassRef<StringImpl> Identifier::add(VM* vm, const T* s, int length)
    140     {
    141         if (length == 1) {
    142             T c = s[0];
    143             if (canUseSingleCharacterString(c))
    144                 return *vm->smallStrings.singleCharacterStringRep(c);
    145         }
    146         if (!length)
    147             return *StringImpl::empty();
    148        
    149         return *AtomicString::add(s, length);
    150     }
    151 
    152     inline bool operator==(const Identifier& a, const Identifier& b)
    153     {
    154         return Identifier::equal(a, b);
    155     }
    156 
    157     inline bool operator!=(const Identifier& a, const Identifier& b)
    158     {
    159         return !Identifier::equal(a, b);
    160     }
    161 
    162     inline bool operator==(const Identifier& a, const LChar* b)
    163     {
    164         return Identifier::equal(a, b);
    165     }
    166 
    167     inline bool operator==(const Identifier& a, const char* b)
    168     {
    169         return Identifier::equal(a, reinterpret_cast<const LChar*>(b));
    170     }
    171    
    172     inline bool operator!=(const Identifier& a, const LChar* b)
    173     {
    174         return !Identifier::equal(a, b);
    175     }
    176 
    177     inline bool operator!=(const Identifier& a, const char* b)
    178     {
    179         return !Identifier::equal(a, reinterpret_cast<const LChar*>(b));
    180     }
    181    
    182     inline bool Identifier::equal(const StringImpl* r, const LChar* s)
    183     {
    184         return WTF::equal(r, s);
    185     }
    186 
    187     inline bool Identifier::equal(const StringImpl* r, const LChar* s, unsigned length)
    188     {
    189         return WTF::equal(r, s, length);
    190     }
    191 
    192     inline bool Identifier::equal(const StringImpl* r, const UChar* s, unsigned length)
    193     {
    194         return WTF::equal(r, s, length);
    195     }
    196    
    197     struct IdentifierRepHash : PtrHash<RefPtr<StringImpl>> {
    198         static unsigned hash(const RefPtr<StringImpl>& key) { return key->existingHash(); }
    199         static unsigned hash(StringImpl* key) { return key->existingHash(); }
    200     };
    201 
    202     struct IdentifierMapIndexHashTraits : HashTraits<int> {
    203         static int emptyValue() { return std::numeric_limits<int>::max(); }
    204         static const bool emptyValueIsZero = false;
    205     };
    206 
    207     typedef HashMap<RefPtr<StringImpl>, int, IdentifierRepHash, HashTraits<RefPtr<StringImpl>>, IdentifierMapIndexHashTraits> IdentifierMap;
    208     typedef HashMap<StringImpl*, int, IdentifierRepHash, HashTraits<StringImpl*>, IdentifierMapIndexHashTraits> BorrowedIdentifierMap;
     146    if (!length)
     147        return *StringImpl::empty();
     148
     149    return *AtomicString::add(s, length);
     150}
     151
     152inline bool operator==(const Identifier& a, const Identifier& b)
     153{
     154    return Identifier::equal(a, b);
     155}
     156
     157inline bool operator!=(const Identifier& a, const Identifier& b)
     158{
     159    return !Identifier::equal(a, b);
     160}
     161
     162inline bool operator==(const Identifier& a, const LChar* b)
     163{
     164    return Identifier::equal(a, b);
     165}
     166
     167inline bool operator==(const Identifier& a, const char* b)
     168{
     169    return Identifier::equal(a, reinterpret_cast<const LChar*>(b));
     170}
     171
     172inline bool operator!=(const Identifier& a, const LChar* b)
     173{
     174    return !Identifier::equal(a, b);
     175}
     176
     177inline bool operator!=(const Identifier& a, const char* b)
     178{
     179    return !Identifier::equal(a, reinterpret_cast<const LChar*>(b));
     180}
     181
     182inline bool Identifier::equal(const StringImpl* r, const LChar* s)
     183{
     184    return WTF::equal(r, s);
     185}
     186
     187inline bool Identifier::equal(const StringImpl* r, const LChar* s, unsigned length)
     188{
     189    return WTF::equal(r, s, length);
     190}
     191
     192inline bool Identifier::equal(const StringImpl* r, const UChar* s, unsigned length)
     193{
     194    return WTF::equal(r, s, length);
     195}
     196
     197struct IdentifierRepHash : PtrHash<RefPtr<StringImpl>> {
     198    static unsigned hash(const RefPtr<StringImpl>& key) { return key->existingHash(); }
     199    static unsigned hash(StringImpl* key) { return key->existingHash(); }
     200};
     201
     202struct IdentifierMapIndexHashTraits : HashTraits<int> {
     203    static int emptyValue() { return std::numeric_limits<int>::max(); }
     204    static const bool emptyValueIsZero = false;
     205};
     206
     207typedef HashMap<RefPtr<StringImpl>, int, IdentifierRepHash, HashTraits<RefPtr<StringImpl>>, IdentifierMapIndexHashTraits> IdentifierMap;
     208typedef HashMap<StringImpl*, int, IdentifierRepHash, HashTraits<StringImpl*>, IdentifierMapIndexHashTraits> BorrowedIdentifierMap;
    209209
    210210} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/InitializeThreading.h

    r165676 r173269  
    3232namespace JSC {
    3333
    34     // This function must be called from the main thread. It is safe to call it repeatedly.
    35     // Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly.
    36     JS_EXPORT_PRIVATE void initializeThreading();
     34// This function must be called from the main thread. It is safe to call it repeatedly.
     35// Darwin is an exception to this rule: it is OK to call this function from any thread, even reentrantly.
     36JS_EXPORT_PRIVATE void initializeThreading();
    3737
    3838}
  • trunk/Source/JavaScriptCore/runtime/InternalFunction.h

    r156624 r173269  
    3030namespace JSC {
    3131
    32     class FunctionPrototype;
     32class FunctionPrototype;
    3333
    34     class InternalFunction : public JSDestructibleObject {
    35     public:
    36         typedef JSDestructibleObject Base;
     34class InternalFunction : public JSDestructibleObject {
     35public:
     36    typedef JSDestructibleObject Base;
    3737
    38         DECLARE_EXPORT_INFO;
     38    DECLARE_EXPORT_INFO;
    3939
    40         JS_EXPORT_PRIVATE const String& name(ExecState*);
    41         const String displayName(ExecState*);
    42         const String calculatedDisplayName(ExecState*);
     40    JS_EXPORT_PRIVATE const String& name(ExecState*);
     41    const String displayName(ExecState*);
     42    const String calculatedDisplayName(ExecState*);
    4343
    44         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
    45         {
    46             return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
    47         }
     44    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
     45    {
     46        return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
     47    }
    4848
    49     protected:
    50         static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
     49protected:
     50    static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;
    5151
    52         JS_EXPORT_PRIVATE InternalFunction(VM&, Structure*);
     52    JS_EXPORT_PRIVATE InternalFunction(VM&, Structure*);
    5353
    54         JS_EXPORT_PRIVATE void finishCreation(VM&, const String& name);
     54    JS_EXPORT_PRIVATE void finishCreation(VM&, const String& name);
    5555
    56         static CallType getCallData(JSCell*, CallData&);
    57     };
     56    static CallType getCallData(JSCell*, CallData&);
     57};
    5858
    59     InternalFunction* asInternalFunction(JSValue);
     59InternalFunction* asInternalFunction(JSValue);
    6060
    61     inline InternalFunction* asInternalFunction(JSValue value)
    62     {
    63         ASSERT(asObject(value)->inherits(InternalFunction::info()));
    64         return static_cast<InternalFunction*>(asObject(value));
    65     }
     61inline InternalFunction* asInternalFunction(JSValue value)
     62{
     63    ASSERT(asObject(value)->inherits(InternalFunction::info()));
     64    return static_cast<InternalFunction*>(asObject(value));
     65}
    6666
    6767} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h

    r171939 r173269  
    3131namespace JSC {
    3232
    33     class JSAPIValueWrapper : public JSCell {
    34         friend JSValue jsAPIValueWrapper(ExecState*, JSValue);
    35     public:
    36         typedef JSCell Base;
     33class JSAPIValueWrapper : public JSCell {
     34    friend JSValue jsAPIValueWrapper(ExecState*, JSValue);
     35public:
     36    typedef JSCell Base;
    3737
    38         JSValue value() const { return m_value.get(); }
     38    JSValue value() const { return m_value.get(); }
    3939
    40         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    41         {
    42             return Structure::create(vm, globalObject, prototype, TypeInfo(APIValueWrapperType, OverridesGetPropertyNames), info());
    43         }
    44        
    45         DECLARE_EXPORT_INFO;
    46        
    47         static JSAPIValueWrapper* create(ExecState* exec, JSValue value)
    48         {
    49             VM& vm = exec->vm();
    50             JSAPIValueWrapper* wrapper = new (NotNull, allocateCell<JSAPIValueWrapper>(vm.heap)) JSAPIValueWrapper(exec);
    51             wrapper->finishCreation(vm, value);
    52             return wrapper;
    53         }
     40    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     41    {
     42        return Structure::create(vm, globalObject, prototype, TypeInfo(APIValueWrapperType, OverridesGetPropertyNames), info());
     43    }
    5444
    55     protected:
    56         void finishCreation(VM& vm, JSValue value)
    57         {
    58             Base::finishCreation(vm);
    59             m_value.set(vm, this, value);
    60             ASSERT(!value.isCell());
    61         }
     45    DECLARE_EXPORT_INFO;
    6246
    63     private:
    64         JSAPIValueWrapper(ExecState* exec)
    65             : JSCell(exec->vm(), exec->vm().apiWrapperStructure.get())
    66         {
    67         }
     47    static JSAPIValueWrapper* create(ExecState* exec, JSValue value)
     48    {
     49        VM& vm = exec->vm();
     50        JSAPIValueWrapper* wrapper = new (NotNull, allocateCell<JSAPIValueWrapper>(vm.heap)) JSAPIValueWrapper(exec);
     51        wrapper->finishCreation(vm, value);
     52        return wrapper;
     53    }
    6854
    69         WriteBarrier<Unknown> m_value;
    70     };
     55protected:
     56    void finishCreation(VM& vm, JSValue value)
     57    {
     58        Base::finishCreation(vm);
     59        m_value.set(vm, this, value);
     60        ASSERT(!value.isCell());
     61    }
    7162
    72     inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value)
     63private:
     64    JSAPIValueWrapper(ExecState* exec)
     65        : JSCell(exec->vm(), exec->vm().apiWrapperStructure.get())
    7366    {
    74         return JSAPIValueWrapper::create(exec, value);
    7567    }
     68
     69    WriteBarrier<Unknown> m_value;
     70};
     71
     72inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value)
     73{
     74    return JSAPIValueWrapper::create(exec, value);
     75}
    7676
    7777} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSFunction.h

    r171939 r173269  
    3333namespace JSC {
    3434
    35     class ExecutableBase;
    36     class FunctionExecutable;
    37     class FunctionPrototype;
    38     class JSActivation;
    39     class JSGlobalObject;
    40     class LLIntOffsetsExtractor;
    41     class NativeExecutable;
    42     class SourceCode;
    43     namespace DFG {
    44     class SpeculativeJIT;
    45     class JITCompiler;
     35class ExecutableBase;
     36class FunctionExecutable;
     37class FunctionPrototype;
     38class JSActivation;
     39class JSGlobalObject;
     40class LLIntOffsetsExtractor;
     41class NativeExecutable;
     42class SourceCode;
     43namespace DFG {
     44class SpeculativeJIT;
     45class JITCompiler;
     46}
     47
     48JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
     49
     50JS_EXPORT_PRIVATE String getCalculatedDisplayName(CallFrame*, JSObject*);
     51   
     52class JSFunction : public JSDestructibleObject {
     53    friend class JIT;
     54    friend class DFG::SpeculativeJIT;
     55    friend class DFG::JITCompiler;
     56    friend class VM;
     57
     58public:
     59    typedef JSDestructibleObject Base;
     60
     61    JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
     62
     63    static JSFunction* create(VM& vm, FunctionExecutable* executable, JSScope* scope)
     64    {
     65        JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
     66        ASSERT(function->structure()->globalObject());
     67        function->finishCreation(vm);
     68        return function;
    4669    }
    4770
    48     JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);
     71    static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*);
    4972
    50     JS_EXPORT_PRIVATE String getCalculatedDisplayName(CallFrame*, JSObject*);
    51    
    52     class JSFunction : public JSDestructibleObject {
    53         friend class JIT;
    54         friend class DFG::SpeculativeJIT;
    55         friend class DFG::JITCompiler;
    56         friend class VM;
     73    static void destroy(JSCell*);
    5774
    58     public:
    59         typedef JSDestructibleObject Base;
     75    JS_EXPORT_PRIVATE String name(ExecState*);
     76    JS_EXPORT_PRIVATE String displayName(ExecState*);
     77    const String calculatedDisplayName(ExecState*);
    6078
    61         JS_EXPORT_PRIVATE static JSFunction* create(VM&, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor);
     79    JSScope* scope()
     80    {
     81        ASSERT(!isHostFunctionNonInline());
     82        return m_scope.get();
     83    }
     84    // This method may be called for host functins, in which case it
     85    // will return an arbitrary value. This should only be used for
     86    // optimized paths in which the return value does not matter for
     87    // host functions, and checking whether the function is a host
     88    // function is deemed too expensive.
     89    JSScope* scopeUnchecked()
     90    {
     91        return m_scope.get();
     92    }
     93    void setScope(VM& vm, JSScope* scope)
     94    {
     95        ASSERT(!isHostFunctionNonInline());
     96        m_scope.set(vm, this, scope);
     97    }
     98    void addNameScopeIfNeeded(VM&);
    6299
    63         static JSFunction* create(VM& vm, FunctionExecutable* executable, JSScope* scope)
    64         {
    65             JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, executable, scope);
    66             ASSERT(function->structure()->globalObject());
    67             function->finishCreation(vm);
    68             return function;
    69         }
    70        
    71         static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*);
    72        
    73         static void destroy(JSCell*);
    74        
    75         JS_EXPORT_PRIVATE String name(ExecState*);
    76         JS_EXPORT_PRIVATE String displayName(ExecState*);
    77         const String calculatedDisplayName(ExecState*);
     100    ExecutableBase* executable() const { return m_executable.get(); }
    78101
    79         JSScope* scope()
    80         {
    81             ASSERT(!isHostFunctionNonInline());
    82             return m_scope.get();
    83         }
    84         // This method may be called for host functins, in which case it
    85         // will return an arbitrary value. This should only be used for
    86         // optimized paths in which the return value does not matter for
    87         // host functions, and checking whether the function is a host
    88         // function is deemed too expensive.
    89         JSScope* scopeUnchecked()
    90         {
    91             return m_scope.get();
    92         }
    93         void setScope(VM& vm, JSScope* scope)
    94         {
    95             ASSERT(!isHostFunctionNonInline());
    96             m_scope.set(vm, this, scope);
    97         }
    98         void addNameScopeIfNeeded(VM&);
     102    // To call either of these methods include Executable.h
     103    bool isHostFunction() const;
     104    FunctionExecutable* jsExecutable() const;
    99105
    100         ExecutableBase* executable() const { return m_executable.get(); }
     106    JS_EXPORT_PRIVATE const SourceCode* sourceCode() const;
    101107
    102         // To call either of these methods include Executable.h
    103         bool isHostFunction() const;
    104         FunctionExecutable* jsExecutable() const;
     108    DECLARE_EXPORT_INFO;
    105109
    106         JS_EXPORT_PRIVATE const SourceCode* sourceCode() const;
     110    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     111    {
     112        ASSERT(globalObject);
     113        return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
     114    }
    107115
    108         DECLARE_EXPORT_INFO;
     116    NativeFunction nativeFunction();
     117    NativeFunction nativeConstructor();
    109118
    110         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    111         {
    112             ASSERT(globalObject);
    113             return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
    114         }
     119    static ConstructType getConstructData(JSCell*, ConstructData&);
     120    static CallType getCallData(JSCell*, CallData&);
    115121
    116         NativeFunction nativeFunction();
    117         NativeFunction nativeConstructor();
     122    static inline ptrdiff_t offsetOfScopeChain()
     123    {
     124        return OBJECT_OFFSETOF(JSFunction, m_scope);
     125    }
    118126
    119         static ConstructType getConstructData(JSCell*, ConstructData&);
    120         static CallType getCallData(JSCell*, CallData&);
     127    static inline ptrdiff_t offsetOfExecutable()
     128    {
     129        return OBJECT_OFFSETOF(JSFunction, m_executable);
     130    }
    121131
    122         static inline ptrdiff_t offsetOfScopeChain()
    123         {
    124             return OBJECT_OFFSETOF(JSFunction, m_scope);
    125         }
     132    static inline ptrdiff_t offsetOfAllocationProfile()
     133    {
     134        return OBJECT_OFFSETOF(JSFunction, m_allocationProfile);
     135    }
    126136
    127         static inline ptrdiff_t offsetOfExecutable()
    128         {
    129             return OBJECT_OFFSETOF(JSFunction, m_executable);
    130         }
     137    ObjectAllocationProfile* allocationProfile(ExecState* exec, unsigned inlineCapacity)
     138    {
     139        if (UNLIKELY(m_allocationProfile.isNull()))
     140            return createAllocationProfile(exec, inlineCapacity);
     141        return &m_allocationProfile;
     142    }
    131143
    132         static inline ptrdiff_t offsetOfAllocationProfile()
    133         {
    134             return OBJECT_OFFSETOF(JSFunction, m_allocationProfile);
    135         }
     144    Structure* allocationStructure() { return m_allocationProfile.structure(); }
    136145
    137         ObjectAllocationProfile* allocationProfile(ExecState* exec, unsigned inlineCapacity)
    138         {
    139             if (UNLIKELY(m_allocationProfile.isNull()))
    140                 return createAllocationProfile(exec, inlineCapacity);
    141             return &m_allocationProfile;
    142         }
    143        
    144         Structure* allocationStructure() { return m_allocationProfile.structure(); }
     146    InlineWatchpointSet& allocationProfileWatchpointSet()
     147    {
     148        return m_allocationProfileWatchpoint;
     149    }
    145150
    146         InlineWatchpointSet& allocationProfileWatchpointSet()
    147         {
    148             return m_allocationProfileWatchpoint;
    149         }
     151    bool isHostOrBuiltinFunction() const;
     152    bool isBuiltinFunction() const;
     153    JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
    150154
    151         bool isHostOrBuiltinFunction() const;
    152         bool isBuiltinFunction() const;
    153         JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const;
     155protected:
     156    const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesGetPropertyNames | JSObject::StructureFlags;
    154157
    155     protected:
    156         const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesGetPropertyNames | JSObject::StructureFlags;
     158    JS_EXPORT_PRIVATE JSFunction(VM&, JSGlobalObject*, Structure*);
     159    JSFunction(VM&, FunctionExecutable*, JSScope*);
    157160
    158         JS_EXPORT_PRIVATE JSFunction(VM&, JSGlobalObject*, Structure*);
    159         JSFunction(VM&, FunctionExecutable*, JSScope*);
    160        
    161         void finishCreation(VM&, NativeExecutable*, int length, const String& name);
    162         using Base::finishCreation;
     161    void finishCreation(VM&, NativeExecutable*, int length, const String& name);
     162    using Base::finishCreation;
    163163
    164         ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity);
     164    ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity);
    165165
    166         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    167         static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties);
    168         static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
     166    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     167    static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode = ExcludeDontEnumProperties);
     168    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
    169169
    170         static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
     170    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
    171171
    172         static bool deleteProperty(JSCell*, ExecState*, PropertyName);
     172    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
    173173
    174         static void visitChildren(JSCell*, SlotVisitor&);
     174    static void visitChildren(JSCell*, SlotVisitor&);
    175175
    176     private:
    177         friend class LLIntOffsetsExtractor;
    178        
    179         static EncodedJSValue argumentsGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
    180         static EncodedJSValue callerGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
    181         static EncodedJSValue lengthGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
    182         static EncodedJSValue nameGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
     176private:
     177    friend class LLIntOffsetsExtractor;
    183178
    184         WriteBarrier<ExecutableBase> m_executable;
    185         WriteBarrier<JSScope> m_scope;
    186         ObjectAllocationProfile m_allocationProfile;
    187         InlineWatchpointSet m_allocationProfileWatchpoint;
    188     };
     179    static EncodedJSValue argumentsGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
     180    static EncodedJSValue callerGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
     181    static EncodedJSValue lengthGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
     182    static EncodedJSValue nameGetter(ExecState*, JSObject*, EncodedJSValue, PropertyName);
     183
     184    WriteBarrier<ExecutableBase> m_executable;
     185    WriteBarrier<JSScope> m_scope;
     186    ObjectAllocationProfile m_allocationProfile;
     187    InlineWatchpointSet m_allocationProfileWatchpoint;
     188};
    189189
    190190} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSLock.h

    r165999 r173269  
    3232namespace JSC {
    3333
    34     // To make it safe to use JavaScript on multiple threads, it is
    35     // important to lock before doing anything that allocates a
    36     // JavaScript data structure or that interacts with shared state
    37     // such as the protect count hash table. The simplest way to lock
    38     // is to create a local JSLockHolder object in the scope where the lock
    39     // must be held and pass it the context that requires protection.
    40     // The lock is recursive so nesting is ok. The JSLock
    41     // object also acts as a convenience short-hand for running important
    42     // initialization routines.
     34// To make it safe to use JavaScript on multiple threads, it is
     35// important to lock before doing anything that allocates a
     36// JavaScript data structure or that interacts with shared state
     37// such as the protect count hash table. The simplest way to lock
     38// is to create a local JSLockHolder object in the scope where the lock
     39// must be held and pass it the context that requires protection.
     40// The lock is recursive so nesting is ok. The JSLock
     41// object also acts as a convenience short-hand for running important
     42// initialization routines.
    4343
    44     // To avoid deadlock, sometimes it is necessary to temporarily
    45     // release the lock. Since it is recursive you actually have to
    46     // release all locks held by your thread. This is safe to do if
    47     // you are executing code that doesn't require the lock, and you
    48     // reacquire the right number of locks at the end. You can do this
    49     // by constructing a locally scoped JSLock::DropAllLocks object. The
    50     // DropAllLocks object takes care to release the JSLock only if your
    51     // thread acquired it to begin with.
     44// To avoid deadlock, sometimes it is necessary to temporarily
     45// release the lock. Since it is recursive you actually have to
     46// release all locks held by your thread. This is safe to do if
     47// you are executing code that doesn't require the lock, and you
     48// reacquire the right number of locks at the end. You can do this
     49// by constructing a locally scoped JSLock::DropAllLocks object. The
     50// DropAllLocks object takes care to release the JSLock only if your
     51// thread acquired it to begin with.
    5252
    53     class ExecState;
    54     class VM;
     53class ExecState;
     54class VM;
    5555
    56     // This class is used to protect the initialization of the legacy single
    57     // shared VM.
    58     class GlobalJSLock {
    59         WTF_MAKE_NONCOPYABLE(GlobalJSLock);
     56// This class is used to protect the initialization of the legacy single
     57// shared VM.
     58class GlobalJSLock {
     59    WTF_MAKE_NONCOPYABLE(GlobalJSLock);
     60public:
     61    JS_EXPORT_PRIVATE GlobalJSLock();
     62    JS_EXPORT_PRIVATE ~GlobalJSLock();
     63
     64    static void initialize();
     65private:
     66    static std::mutex* s_sharedInstanceMutex;
     67};
     68
     69class JSLockHolder {
     70public:
     71    JS_EXPORT_PRIVATE JSLockHolder(VM*);
     72    JS_EXPORT_PRIVATE JSLockHolder(VM&);
     73    JS_EXPORT_PRIVATE JSLockHolder(ExecState*);
     74
     75    JS_EXPORT_PRIVATE ~JSLockHolder();
     76private:
     77    void init();
     78
     79    RefPtr<VM> m_vm;
     80};
     81
     82class JSLock : public ThreadSafeRefCounted<JSLock> {
     83    WTF_MAKE_NONCOPYABLE(JSLock);
     84public:
     85    JSLock(VM*);
     86    JS_EXPORT_PRIVATE ~JSLock();
     87
     88    JS_EXPORT_PRIVATE void lock();
     89    JS_EXPORT_PRIVATE void unlock();
     90
     91    static void lock(ExecState*);
     92    static void unlock(ExecState*);
     93    static void lock(VM&);
     94    static void unlock(VM&);
     95
     96    VM* vm() { return m_vm; }
     97
     98    bool hasExclusiveThread() const { return m_hasExclusiveThread; }
     99    std::thread::id exclusiveThread() const
     100    {
     101        ASSERT(m_hasExclusiveThread);
     102        return m_ownerThreadID;
     103    }
     104    JS_EXPORT_PRIVATE void setExclusiveThread(std::thread::id);
     105    JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
     106
     107    void willDestroyVM(VM*);
     108
     109    class DropAllLocks {
     110        WTF_MAKE_NONCOPYABLE(DropAllLocks);
    60111    public:
    61         JS_EXPORT_PRIVATE GlobalJSLock();
    62         JS_EXPORT_PRIVATE ~GlobalJSLock();
     112        JS_EXPORT_PRIVATE DropAllLocks(ExecState*);
     113        JS_EXPORT_PRIVATE DropAllLocks(VM*);
     114        JS_EXPORT_PRIVATE DropAllLocks(VM&);
     115        JS_EXPORT_PRIVATE ~DropAllLocks();
    63116
    64         static void initialize();
     117        void setDropDepth(unsigned depth) { m_dropDepth = depth; }
     118        unsigned dropDepth() const { return m_dropDepth; }
     119
    65120    private:
    66         static std::mutex* s_sharedInstanceMutex;
     121        intptr_t m_droppedLockCount;
     122        RefPtr<VM> m_vm;
     123        unsigned m_dropDepth;
    67124    };
    68125
    69     class JSLockHolder {
    70     public:
    71         JS_EXPORT_PRIVATE JSLockHolder(VM*);
    72         JS_EXPORT_PRIVATE JSLockHolder(VM&);
    73         JS_EXPORT_PRIVATE JSLockHolder(ExecState*);
     126private:
     127    void lock(intptr_t lockCount);
     128    void unlock(intptr_t unlockCount);
    74129
    75         JS_EXPORT_PRIVATE ~JSLockHolder();
    76     private:
    77         void init();
     130    void didAcquireLock();
     131    void willReleaseLock();
    78132
    79         RefPtr<VM> m_vm;
    80     };
     133    unsigned dropAllLocks(DropAllLocks*);
     134    void grabAllLocks(DropAllLocks*, unsigned lockCount);
    81135
    82     class JSLock : public ThreadSafeRefCounted<JSLock> {
    83         WTF_MAKE_NONCOPYABLE(JSLock);
    84     public:
    85         JSLock(VM*);
    86         JS_EXPORT_PRIVATE ~JSLock();
    87 
    88         JS_EXPORT_PRIVATE void lock();
    89         JS_EXPORT_PRIVATE void unlock();
    90 
    91         static void lock(ExecState*);
    92         static void unlock(ExecState*);
    93         static void lock(VM&);
    94         static void unlock(VM&);
    95 
    96         VM* vm() { return m_vm; }
    97 
    98         bool hasExclusiveThread() const { return m_hasExclusiveThread; }
    99         std::thread::id exclusiveThread() const
    100         {
    101             ASSERT(m_hasExclusiveThread);
    102             return m_ownerThreadID;
    103         }
    104         JS_EXPORT_PRIVATE void setExclusiveThread(std::thread::id);
    105         JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
    106 
    107         void willDestroyVM(VM*);
    108 
    109         class DropAllLocks {
    110             WTF_MAKE_NONCOPYABLE(DropAllLocks);
    111         public:
    112             JS_EXPORT_PRIVATE DropAllLocks(ExecState*);
    113             JS_EXPORT_PRIVATE DropAllLocks(VM*);
    114             JS_EXPORT_PRIVATE DropAllLocks(VM&);
    115             JS_EXPORT_PRIVATE ~DropAllLocks();
    116            
    117             void setDropDepth(unsigned depth) { m_dropDepth = depth; }
    118             unsigned dropDepth() const { return m_dropDepth; }
    119 
    120         private:
    121             intptr_t m_droppedLockCount;
    122             RefPtr<VM> m_vm;
    123             unsigned m_dropDepth;
    124         };
    125 
    126     private:
    127         void lock(intptr_t lockCount);
    128         void unlock(intptr_t unlockCount);
    129 
    130         void didAcquireLock();
    131         void willReleaseLock();
    132 
    133         unsigned dropAllLocks(DropAllLocks*);
    134         void grabAllLocks(DropAllLocks*, unsigned lockCount);
    135 
    136         std::mutex m_lock;
    137         std::thread::id m_ownerThreadID;
    138         intptr_t m_lockCount;
    139         unsigned m_lockDropDepth;
    140         bool m_hasExclusiveThread;
    141         VM* m_vm;
    142         AtomicStringTable* m_entryAtomicStringTable;
    143     };
     136    std::mutex m_lock;
     137    std::thread::id m_ownerThreadID;
     138    intptr_t m_lockCount;
     139    unsigned m_lockDropDepth;
     140    bool m_hasExclusiveThread;
     141    VM* m_vm;
     142    AtomicStringTable* m_entryAtomicStringTable;
     143};
    144144
    145145} // namespace
  • trunk/Source/JavaScriptCore/runtime/JSNotAnObject.h

    r165676 r173269  
    3434namespace JSC {
    3535
    36     // This unholy class is used to allow us to avoid multiple exception checks
    37     // in certain SquirrelFish bytecodes -- effectively it just silently consumes
    38     // any operations performed on the result of a failed toObject call.
    39     class JSNotAnObject : public JSNonFinalObject {
    40     private:
    41         explicit JSNotAnObject(VM& vm)
    42             : JSNonFinalObject(vm, vm.notAnObjectStructure.get())
    43         {
    44         }
    45        
    46     public:
    47         typedef JSNonFinalObject Base;
     36// This unholy class is used to allow us to avoid multiple exception checks
     37// in certain SquirrelFish bytecodes -- effectively it just silently consumes
     38// any operations performed on the result of a failed toObject call.
     39class JSNotAnObject : public JSNonFinalObject {
     40private:
     41    explicit JSNotAnObject(VM& vm)
     42        : JSNonFinalObject(vm, vm.notAnObjectStructure.get())
     43    {
     44    }
    4845
    49         static JSNotAnObject* create(VM& vm)
    50         {
    51             JSNotAnObject* object = new (NotNull, allocateCell<JSNotAnObject>(vm.heap)) JSNotAnObject(vm);
    52             object->finishCreation(vm);
    53             return object;
    54         }
     46public:
     47    typedef JSNonFinalObject Base;
    5548
    56         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    57         {
    58             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    59         }
     49    static JSNotAnObject* create(VM& vm)
     50    {
     51        JSNotAnObject* object = new (NotNull, allocateCell<JSNotAnObject>(vm.heap)) JSNotAnObject(vm);
     52        object->finishCreation(vm);
     53        return object;
     54    }
    6055
    61         DECLARE_INFO;
     56    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     57    {
     58        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     59    }
    6260
    63      private:
    64        
    65         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSObject::StructureFlags;
     61    DECLARE_INFO;
    6662
    67         // JSValue methods
    68         static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
     63private:
    6964
    70         // JSObject methods
    71         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    72         static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
     65    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSObject::StructureFlags;
    7366
    74         static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
    75         static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
     67    // JSValue methods
     68    static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType);
    7669
    77         static bool deleteProperty(JSCell*, ExecState*, PropertyName);
    78         static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
     70    // JSObject methods
     71    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     72    static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
    7973
    80         static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
    81     };
     74    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
     75    static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
     76
     77    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
     78    static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
     79
     80    static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     81};
    8282
    8383} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSONObject.h

    r159377 r173269  
    3131namespace JSC {
    3232
    33     class Stringifier;
     33class Stringifier;
    3434
    35     class JSONObject : public JSNonFinalObject {
    36     public:
    37         typedef JSNonFinalObject Base;
     35class JSONObject : public JSNonFinalObject {
     36public:
     37    typedef JSNonFinalObject Base;
    3838
    39         static JSONObject* create(VM& vm, Structure* structure)
    40         {
    41             JSONObject* object = new (NotNull, allocateCell<JSONObject>(vm.heap)) JSONObject(vm, structure);
    42             object->finishCreation(vm);
    43             return object;
    44         }
    45        
    46         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    47         {
    48             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    49         }
    50        
    51         DECLARE_INFO;
     39    static JSONObject* create(VM& vm, Structure* structure)
     40    {
     41        JSONObject* object = new (NotNull, allocateCell<JSONObject>(vm.heap)) JSONObject(vm, structure);
     42        object->finishCreation(vm);
     43        return object;
     44    }
    5245
    53     protected:
    54         void finishCreation(VM&);
    55         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
     46    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     47    {
     48        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     49    }
    5650
    57     private:
    58         JSONObject(VM&, Structure*);
    59         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     51    DECLARE_INFO;
    6052
    61     };
     53protected:
     54    void finishCreation(VM&);
     55    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
    6256
    63     JS_EXPORT_PRIVATE JSValue JSONParse(ExecState*, const String&);
    64     JS_EXPORT_PRIVATE String JSONStringify(ExecState*, JSValue, unsigned indent);
     57private:
     58    JSONObject(VM&, Structure*);
     59    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     60};
    6561
    66     void escapeStringToBuilder(StringBuilder&, const String&);
     62JS_EXPORT_PRIVATE JSValue JSONParse(ExecState*, const String&);
     63JS_EXPORT_PRIVATE String JSONStringify(ExecState*, JSValue, unsigned indent);
     64
     65void escapeStringToBuilder(StringBuilder&, const String&);
    6766   
    6867} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSString.h

    r172727 r173269  
    3434namespace JSC {
    3535
    36     class JSString;
    37     class JSRopeString;
    38     class LLIntOffsetsExtractor;
    39 
    40     JSString* jsEmptyString(VM*);
    41     JSString* jsEmptyString(ExecState*);
    42     JSString* jsString(VM*, const String&); // returns empty string if passed null string
    43     JSString* jsString(ExecState*, const String&); // returns empty string if passed null string
    44 
    45     JSString* jsSingleCharacterString(VM*, UChar);
    46     JSString* jsSingleCharacterString(ExecState*, UChar);
    47     JSString* jsSingleCharacterSubstring(ExecState*, const String&, unsigned offset);
    48     JSString* jsSubstring(VM*, const String&, unsigned offset, unsigned length);
    49     JSString* jsSubstring(ExecState*, const String&, unsigned offset, unsigned length);
    50 
    51     // Non-trivial strings are two or more characters long.
    52     // These functions are faster than just calling jsString.
    53     JSString* jsNontrivialString(VM*, const String&);
    54     JSString* jsNontrivialString(ExecState*, const String&);
    55 
    56     // Should be used for strings that are owned by an object that will
    57     // likely outlive the JSValue this makes, such as the parse tree or a
    58     // DOM object that contains a String
    59     JSString* jsOwnedString(VM*, const String&);
    60     JSString* jsOwnedString(ExecState*, const String&);
    61 
    62     JSRopeString* jsStringBuilder(VM*);
    63 
    64     class JSString : public JSCell {
     36class JSString;
     37class JSRopeString;
     38class LLIntOffsetsExtractor;
     39
     40JSString* jsEmptyString(VM*);
     41JSString* jsEmptyString(ExecState*);
     42JSString* jsString(VM*, const String&); // returns empty string if passed null string
     43JSString* jsString(ExecState*, const String&); // returns empty string if passed null string
     44
     45JSString* jsSingleCharacterString(VM*, UChar);
     46JSString* jsSingleCharacterString(ExecState*, UChar);
     47JSString* jsSingleCharacterSubstring(ExecState*, const String&, unsigned offset);
     48JSString* jsSubstring(VM*, const String&, unsigned offset, unsigned length);
     49JSString* jsSubstring(ExecState*, const String&, unsigned offset, unsigned length);
     50
     51// Non-trivial strings are two or more characters long.
     52// These functions are faster than just calling jsString.
     53JSString* jsNontrivialString(VM*, const String&);
     54JSString* jsNontrivialString(ExecState*, const String&);
     55
     56// Should be used for strings that are owned by an object that will
     57// likely outlive the JSValue this makes, such as the parse tree or a
     58// DOM object that contains a String
     59JSString* jsOwnedString(VM*, const String&);
     60JSString* jsOwnedString(ExecState*, const String&);
     61
     62JSRopeString* jsStringBuilder(VM*);
     63
     64class JSString : public JSCell {
     65public:
     66    friend class JIT;
     67    friend class VM;
     68    friend class SpecializedThunkJIT;
     69    friend class JSRopeString;
     70    friend class MarkStack;
     71    friend class SlotVisitor;
     72    friend struct ThunkHelpers;
     73
     74    typedef JSCell Base;
     75
     76    static const bool needsDestruction = true;
     77    static const bool hasImmortalStructure = true;
     78    static void destroy(JSCell*);
     79
     80private:
     81    JSString(VM& vm, PassRefPtr<StringImpl> value)
     82        : JSCell(vm, vm.stringStructure.get())
     83        , m_flags(0)
     84        , m_value(value)
     85    {
     86    }
     87
     88    JSString(VM& vm)
     89        : JSCell(vm, vm.stringStructure.get())
     90        , m_flags(0)
     91    {
     92    }
     93
     94    void finishCreation(VM& vm, size_t length)
     95    {
     96        ASSERT(!m_value.isNull());
     97        Base::finishCreation(vm);
     98        m_length = length;
     99        setIs8Bit(m_value.impl()->is8Bit());
     100        vm.m_newStringsSinceLastHashCons++;
     101    }
     102
     103    void finishCreation(VM& vm, size_t length, size_t cost)
     104    {
     105        ASSERT(!m_value.isNull());
     106        Base::finishCreation(vm);
     107        m_length = length;
     108        setIs8Bit(m_value.impl()->is8Bit());
     109        Heap::heap(this)->reportExtraMemoryCost(cost);
     110        vm.m_newStringsSinceLastHashCons++;
     111    }
     112
     113protected:
     114    void finishCreation(VM& vm)
     115    {
     116        Base::finishCreation(vm);
     117        m_length = 0;
     118        setIs8Bit(true);
     119        vm.m_newStringsSinceLastHashCons++;
     120    }
     121
     122public:
     123    static JSString* create(VM& vm, PassRefPtr<StringImpl> value)
     124    {
     125        ASSERT(value);
     126        int32_t length = value->length();
     127        RELEASE_ASSERT(length >= 0);
     128        size_t cost = value->cost();
     129        JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
     130        newString->finishCreation(vm, length, cost);
     131        return newString;
     132    }
     133    static JSString* createHasOtherOwner(VM& vm, PassRefPtr<StringImpl> value)
     134    {
     135        ASSERT(value);
     136        size_t length = value->length();
     137        JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
     138        newString->finishCreation(vm, length);
     139        return newString;
     140    }
     141
     142    Identifier toIdentifier(ExecState*) const;
     143    AtomicString toAtomicString(ExecState*) const;
     144    AtomicStringImpl* toExistingAtomicString(ExecState*) const;
     145    const String& value(ExecState*) const;
     146    const String& tryGetValue() const;
     147    const StringImpl* tryGetValueImpl() const;
     148    unsigned length() const { return m_length; }
     149
     150    JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
     151    JS_EXPORT_PRIVATE bool toBoolean() const;
     152    bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
     153    JSObject* toObject(ExecState*, JSGlobalObject*) const;
     154    double toNumber(ExecState*) const;
     155
     156    bool getStringPropertySlot(ExecState*, PropertyName, PropertySlot&);
     157    bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
     158    bool getStringPropertyDescriptor(ExecState*, PropertyName, PropertyDescriptor&);
     159
     160    bool canGetIndex(unsigned i) { return i < m_length; }
     161    JSString* getIndex(ExecState*, unsigned);
     162
     163    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
     164    {
     165        return Structure::create(vm, globalObject, proto, TypeInfo(StringType, StructureFlags), info());
     166    }
     167
     168    static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
     169    static size_t offsetOfFlags() { return OBJECT_OFFSETOF(JSString, m_flags); }
     170    static size_t offsetOfValue() { return OBJECT_OFFSETOF(JSString, m_value); }
     171
     172    DECLARE_EXPORT_INFO;
     173
     174    static void dumpToStream(const JSCell*, PrintStream&);
     175    static void visitChildren(JSCell*, SlotVisitor&);
     176
     177    enum {
     178        HashConsLock = 1u << 2,
     179        IsHashConsSingleton = 1u << 1,
     180        Is8Bit = 1u
     181    };
     182
     183protected:
     184    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
     185
     186    friend class JSValue;
     187
     188    bool isRope() const { return m_value.isNull(); }
     189    bool is8Bit() const { return m_flags & Is8Bit; }
     190    void setIs8Bit(bool flag) const
     191    {
     192        if (flag)
     193            m_flags |= Is8Bit;
     194        else
     195            m_flags &= ~Is8Bit;
     196    }
     197    bool shouldTryHashCons();
     198    bool isHashConsSingleton() const { return m_flags & IsHashConsSingleton; }
     199    void clearHashConsSingleton() { m_flags &= ~IsHashConsSingleton; }
     200    void setHashConsSingleton() { m_flags |= IsHashConsSingleton; }
     201    bool tryHashConsLock();
     202    void releaseHashConsLock();
     203
     204    mutable unsigned m_flags;
     205
     206    // A string is represented either by a String or a rope of fibers.
     207    unsigned m_length;
     208    mutable String m_value;
     209
     210private:
     211    friend class LLIntOffsetsExtractor;
     212
     213    static JSValue toThis(JSCell*, ExecState*, ECMAMode);
     214
     215    String& string() { ASSERT(!isRope()); return m_value; }
     216
     217    friend JSValue jsString(ExecState*, JSString*, JSString*);
     218    friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length);
     219};
     220
     221class JSRopeString : public JSString {
     222    friend class JSString;
     223
     224    friend JSRopeString* jsStringBuilder(VM*);
     225
     226    class RopeBuilder {
    65227    public:
    66         friend class JIT;
    67         friend class VM;
    68         friend class SpecializedThunkJIT;
    69         friend class JSRopeString;
    70         friend class MarkStack;
    71         friend class SlotVisitor;
    72         friend struct ThunkHelpers;
    73 
    74         typedef JSCell Base;
    75 
    76         static const bool needsDestruction = true;
    77         static const bool hasImmortalStructure = true;
    78         static void destroy(JSCell*);
    79 
    80     private:
    81         JSString(VM& vm, PassRefPtr<StringImpl> value)
    82             : JSCell(vm, vm.stringStructure.get())
    83             , m_flags(0)
    84             , m_value(value)
     228        RopeBuilder(VM& vm)
     229            : m_vm(vm)
     230            , m_jsString(jsStringBuilder(&vm))
     231            , m_index(0)
    85232        {
    86233        }
    87234
    88         JSString(VM& vm)
    89             : JSCell(vm, vm.stringStructure.get())
    90             , m_flags(0)
     235        bool append(JSString* jsString)
    91236        {
     237            if (m_index == JSRopeString::s_maxInternalRopeLength)
     238                expand();
     239            if (static_cast<int32_t>(m_jsString->length() + jsString->length()) < 0) {
     240                m_jsString = nullptr;
     241                return false;
     242            }
     243            m_jsString->append(m_vm, m_index++, jsString);
     244            return true;
    92245        }
    93246
    94         void finishCreation(VM& vm, size_t length)
     247        JSRopeString* release()
    95248        {
    96             ASSERT(!m_value.isNull());
    97             Base::finishCreation(vm);
    98             m_length = length;
    99             setIs8Bit(m_value.impl()->is8Bit());
    100             vm.m_newStringsSinceLastHashCons++;
     249            RELEASE_ASSERT(m_jsString);
     250            JSRopeString* tmp = m_jsString;
     251            m_jsString = 0;
     252            return tmp;
    101253        }
    102254
    103         void finishCreation(VM& vm, size_t length, size_t cost)
    104         {
    105             ASSERT(!m_value.isNull());
    106             Base::finishCreation(vm);
    107             m_length = length;
    108             setIs8Bit(m_value.impl()->is8Bit());
    109             Heap::heap(this)->reportExtraMemoryCost(cost);
    110             vm.m_newStringsSinceLastHashCons++;
    111         }
    112 
    113     protected:
    114         void finishCreation(VM& vm)
    115         {
    116             Base::finishCreation(vm);
    117             m_length = 0;
    118             setIs8Bit(true);
    119             vm.m_newStringsSinceLastHashCons++;
    120         }
    121            
    122     public:
    123         static JSString* create(VM& vm, PassRefPtr<StringImpl> value)
    124         {
    125             ASSERT(value);
    126             int32_t length = value->length();
    127             RELEASE_ASSERT(length >= 0);
    128             size_t cost = value->cost();
    129             JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
    130             newString->finishCreation(vm, length, cost);
    131             return newString;
    132         }
    133         static JSString* createHasOtherOwner(VM& vm, PassRefPtr<StringImpl> value)
    134         {
    135             ASSERT(value);
    136             size_t length = value->length();
    137             JSString* newString = new (NotNull, allocateCell<JSString>(vm.heap)) JSString(vm, value);
    138             newString->finishCreation(vm, length);
    139             return newString;
    140         }
    141 
    142         Identifier toIdentifier(ExecState*) const;
    143         AtomicString toAtomicString(ExecState*) const;
    144         AtomicStringImpl* toExistingAtomicString(ExecState*) const;
    145         const String& value(ExecState*) const;
    146         const String& tryGetValue() const;
    147         const StringImpl* tryGetValueImpl() const;
    148         unsigned length() const { return m_length; }
    149 
    150         JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
    151         JS_EXPORT_PRIVATE bool toBoolean() const;
    152         bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const;
    153         JSObject* toObject(ExecState*, JSGlobalObject*) const;
    154         double toNumber(ExecState*) const;
    155            
    156         bool getStringPropertySlot(ExecState*, PropertyName, PropertySlot&);
    157         bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
    158         bool getStringPropertyDescriptor(ExecState*, PropertyName, PropertyDescriptor&);
    159 
    160         bool canGetIndex(unsigned i) { return i < m_length; }
    161         JSString* getIndex(ExecState*, unsigned);
    162 
    163         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
    164         {
    165             return Structure::create(vm, globalObject, proto, TypeInfo(StringType, StructureFlags), info());
    166         }
    167 
    168         static size_t offsetOfLength() { return OBJECT_OFFSETOF(JSString, m_length); }
    169         static size_t offsetOfFlags() { return OBJECT_OFFSETOF(JSString, m_flags); }
    170         static size_t offsetOfValue() { return OBJECT_OFFSETOF(JSString, m_value); }
    171 
    172         DECLARE_EXPORT_INFO;
    173 
    174         static void dumpToStream(const JSCell*, PrintStream&);
    175         static void visitChildren(JSCell*, SlotVisitor&);
    176 
    177         enum {
    178             HashConsLock = 1u << 2,
    179             IsHashConsSingleton = 1u << 1,
    180             Is8Bit = 1u
    181         };
    182 
    183     protected:
    184         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | StructureIsImmortal;
    185 
    186         friend class JSValue;
    187            
    188         bool isRope() const { return m_value.isNull(); }
    189         bool is8Bit() const { return m_flags & Is8Bit; }
    190         void setIs8Bit(bool flag) const
    191         {
    192             if (flag)
    193                 m_flags |= Is8Bit;
    194             else
    195                 m_flags &= ~Is8Bit;
    196         }
    197         bool shouldTryHashCons();
    198         bool isHashConsSingleton() const { return m_flags & IsHashConsSingleton; }
    199         void clearHashConsSingleton() { m_flags &= ~IsHashConsSingleton; }
    200         void setHashConsSingleton() { m_flags |= IsHashConsSingleton; }
    201         bool tryHashConsLock();
    202         void releaseHashConsLock();
    203 
    204         mutable unsigned m_flags;
    205            
    206         // A string is represented either by a String or a rope of fibers.
    207         unsigned m_length;
    208         mutable String m_value;
     255        unsigned length() const { return m_jsString->m_length; }
    209256
    210257    private:
    211         friend class LLIntOffsetsExtractor;
    212            
    213         static JSValue toThis(JSCell*, ExecState*, ECMAMode);
    214 
    215         String& string() { ASSERT(!isRope()); return m_value; }
    216 
    217         friend JSValue jsString(ExecState*, JSString*, JSString*);
    218         friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length);
     258        void expand();
     259
     260        VM& m_vm;
     261        JSRopeString* m_jsString;
     262        size_t m_index;
    219263    };
    220264
    221     class JSRopeString : public JSString {
    222         friend class JSString;
    223 
    224         friend JSRopeString* jsStringBuilder(VM*);
    225 
    226         class RopeBuilder {
    227         public:
    228             RopeBuilder(VM& vm)
    229                 : m_vm(vm)
    230                 , m_jsString(jsStringBuilder(&vm))
    231                 , m_index(0)
    232             {
    233             }
    234 
    235             bool append(JSString* jsString)
    236             {
    237                 if (m_index == JSRopeString::s_maxInternalRopeLength)
    238                     expand();
    239                 if (static_cast<int32_t>(m_jsString->length() + jsString->length()) < 0) {
    240                     m_jsString = nullptr;
    241                     return false;
    242                 }
    243                 m_jsString->append(m_vm, m_index++, jsString);
    244                 return true;
    245             }
    246 
    247             JSRopeString* release()
    248             {
    249                 RELEASE_ASSERT(m_jsString);
    250                 JSRopeString* tmp = m_jsString;
    251                 m_jsString = 0;
    252                 return tmp;
    253             }
    254 
    255             unsigned length() const { return m_jsString->m_length; }
    256 
    257         private:
    258             void expand();
    259                
    260             VM& m_vm;
    261             JSRopeString* m_jsString;
    262             size_t m_index;
    263         };
    264            
    265     private:
    266         JSRopeString(VM& vm)
    267             : JSString(vm)
    268         {
    269         }
    270 
    271         void finishCreation(VM& vm, JSString* s1, JSString* s2)
    272         {
    273             Base::finishCreation(vm);
    274             m_length = s1->length() + s2->length();
    275             setIs8Bit(s1->is8Bit() && s2->is8Bit());
    276             setIsSubstring(false);
    277             fiber(0).set(vm, this, s1);
    278             fiber(1).set(vm, this, s2);
    279             fiber(2).clear();
    280         }
    281            
    282         void finishCreation(VM& vm, JSString* s1, JSString* s2, JSString* s3)
    283         {
    284             Base::finishCreation(vm);
    285             m_length = s1->length() + s2->length() + s3->length();
    286             setIs8Bit(s1->is8Bit() && s2->is8Bit() &&  s3->is8Bit());
    287             setIsSubstring(false);
    288             fiber(0).set(vm, this, s1);
    289             fiber(1).set(vm, this, s2);
    290             fiber(2).set(vm, this, s3);
    291         }
    292        
    293         void finishCreation(VM& vm, JSString* base, unsigned offset, unsigned length)
    294         {
    295             Base::finishCreation(vm);
    296             ASSERT(!base->isRope());
    297             ASSERT(!sumOverflows<int32_t>(offset, length));
    298             ASSERT(offset + length <= base->length());
    299             m_length = length;
    300             setIs8Bit(base->is8Bit());
    301             setIsSubstring(true);
    302             substringBase().set(vm, this, base);
    303             substringOffset() = offset;
    304         }
    305 
    306         void finishCreation(VM& vm)
    307         {
    308             JSString::finishCreation(vm);
    309             setIsSubstring(false);
    310             fiber(0).clear();
    311             fiber(1).clear();
    312             fiber(2).clear();
    313         }
    314 
    315         void append(VM& vm, size_t index, JSString* jsString)
    316         {
    317             fiber(index).set(vm, this, jsString);
    318             m_length += jsString->m_length;
    319             RELEASE_ASSERT(static_cast<int32_t>(m_length) >= 0);
    320             setIs8Bit(is8Bit() && jsString->is8Bit());
    321         }
    322 
    323         static JSRopeString* createNull(VM& vm)
    324         {
    325             JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
    326             newString->finishCreation(vm);
    327             return newString;
    328         }
    329 
    330     public:
    331         static JSString* create(VM& vm, JSString* s1, JSString* s2)
    332         {
    333             JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
    334             newString->finishCreation(vm, s1, s2);
    335             return newString;
    336         }
    337         static JSString* create(VM& vm, JSString* s1, JSString* s2, JSString* s3)
    338         {
    339             JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
    340             newString->finishCreation(vm, s1, s2, s3);
    341             return newString;
    342         }
    343        
    344         static JSString* create(VM& vm, JSString* base, unsigned offset, unsigned length)
    345         {
    346             JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
    347             newString->finishCreation(vm, base, offset, length);
    348             return newString;
    349         }
    350 
    351         void visitFibers(SlotVisitor&);
    352            
    353         static ptrdiff_t offsetOfFibers() { return OBJECT_OFFSETOF(JSRopeString, u); }
    354 
    355         static const unsigned s_maxInternalRopeLength = 3;
    356            
    357     private:
    358         friend JSValue jsStringFromRegisterArray(ExecState*, Register*, unsigned);
    359         friend JSValue jsStringFromArguments(ExecState*, JSValue);
    360 
    361         JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
    362         JS_EXPORT_PRIVATE void resolveRopeToAtomicString(ExecState*) const;
    363         JS_EXPORT_PRIVATE AtomicStringImpl* resolveRopeToExistingAtomicString(ExecState*) const;
    364         void resolveRopeSlowCase8(LChar*) const;
    365         void resolveRopeSlowCase(UChar*) const;
    366         void outOfMemory(ExecState*) const;
    367         void resolveRopeInternal8(LChar*) const;
    368         void resolveRopeInternal8NoSubstring(LChar*) const;
    369         void resolveRopeInternal16(UChar*) const;
    370         void resolveRopeInternal16NoSubstring(UChar*) const;
    371         void clearFibers() const;
    372            
    373         JS_EXPORT_PRIVATE JSString* getIndexSlowCase(ExecState*, unsigned);
    374        
    375         WriteBarrierBase<JSString>& fiber(unsigned i) const
    376         {
    377             ASSERT(!isSubstring());
    378             ASSERT(i < s_maxInternalRopeLength);
    379             return u[i].string;
    380         }
    381        
    382         WriteBarrierBase<JSString>& substringBase() const
    383         {
    384             return u[1].string;
    385         }
    386        
    387         uintptr_t& substringOffset() const
    388         {
    389             return u[2].number;
    390         }
    391        
    392         static uintptr_t notSubstringSentinel()
    393         {
    394             return 0;
    395         }
    396        
    397         static uintptr_t substringSentinel()
    398         {
    399             return 1;
    400         }
    401        
    402         bool isSubstring() const
    403         {
    404             return u[0].number == substringSentinel();
    405         }
    406        
    407         void setIsSubstring(bool isSubstring)
    408         {
    409             u[0].number = isSubstring ? substringSentinel() : notSubstringSentinel();
    410         }
    411 
    412         mutable union {
    413             uintptr_t number;
    414             WriteBarrierBase<JSString> string;
    415         } u[s_maxInternalRopeLength];
    416     };
    417 
    418 
    419     inline const StringImpl* JSString::tryGetValueImpl() const
    420     {
    421         return m_value.impl();
    422     }
    423 
    424     JSString* asString(JSValue);
    425 
    426     inline JSString* asString(JSValue value)
    427     {
    428         ASSERT(value.asCell()->isString());
    429         return jsCast<JSString*>(value.asCell());
    430     }
    431 
    432     inline JSString* jsEmptyString(VM* vm)
    433     {
     265private:
     266    JSRopeString(VM& vm)
     267        : JSString(vm)
     268    {
     269    }
     270
     271    void finishCreation(VM& vm, JSString* s1, JSString* s2)
     272    {
     273        Base::finishCreation(vm);
     274        m_length = s1->length() + s2->length();
     275        setIs8Bit(s1->is8Bit() && s2->is8Bit());
     276        setIsSubstring(false);
     277        fiber(0).set(vm, this, s1);
     278        fiber(1).set(vm, this, s2);
     279        fiber(2).clear();
     280    }
     281
     282    void finishCreation(VM& vm, JSString* s1, JSString* s2, JSString* s3)
     283    {
     284        Base::finishCreation(vm);
     285        m_length = s1->length() + s2->length() + s3->length();
     286        setIs8Bit(s1->is8Bit() && s2->is8Bit() &&  s3->is8Bit());
     287        setIsSubstring(false);
     288        fiber(0).set(vm, this, s1);
     289        fiber(1).set(vm, this, s2);
     290        fiber(2).set(vm, this, s3);
     291    }
     292
     293    void finishCreation(VM& vm, JSString* base, unsigned offset, unsigned length)
     294    {
     295        Base::finishCreation(vm);
     296        ASSERT(!base->isRope());
     297        ASSERT(!sumOverflows<int32_t>(offset, length));
     298        ASSERT(offset + length <= base->length());
     299        m_length = length;
     300        setIs8Bit(base->is8Bit());
     301        setIsSubstring(true);
     302        substringBase().set(vm, this, base);
     303        substringOffset() = offset;
     304    }
     305
     306    void finishCreation(VM& vm)
     307    {
     308        JSString::finishCreation(vm);
     309        setIsSubstring(false);
     310        fiber(0).clear();
     311        fiber(1).clear();
     312        fiber(2).clear();
     313    }
     314
     315    void append(VM& vm, size_t index, JSString* jsString)
     316    {
     317        fiber(index).set(vm, this, jsString);
     318        m_length += jsString->m_length;
     319        RELEASE_ASSERT(static_cast<int32_t>(m_length) >= 0);
     320        setIs8Bit(is8Bit() && jsString->is8Bit());
     321    }
     322
     323    static JSRopeString* createNull(VM& vm)
     324    {
     325        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
     326        newString->finishCreation(vm);
     327        return newString;
     328    }
     329
     330public:
     331    static JSString* create(VM& vm, JSString* s1, JSString* s2)
     332    {
     333        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
     334        newString->finishCreation(vm, s1, s2);
     335        return newString;
     336    }
     337    static JSString* create(VM& vm, JSString* s1, JSString* s2, JSString* s3)
     338    {
     339        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
     340        newString->finishCreation(vm, s1, s2, s3);
     341        return newString;
     342    }
     343
     344    static JSString* create(VM& vm, JSString* base, unsigned offset, unsigned length)
     345    {
     346        JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);
     347        newString->finishCreation(vm, base, offset, length);
     348        return newString;
     349    }
     350
     351    void visitFibers(SlotVisitor&);
     352
     353    static ptrdiff_t offsetOfFibers() { return OBJECT_OFFSETOF(JSRopeString, u); }
     354
     355    static const unsigned s_maxInternalRopeLength = 3;
     356
     357private:
     358    friend JSValue jsStringFromRegisterArray(ExecState*, Register*, unsigned);
     359    friend JSValue jsStringFromArguments(ExecState*, JSValue);
     360
     361    JS_EXPORT_PRIVATE void resolveRope(ExecState*) const;
     362    JS_EXPORT_PRIVATE void resolveRopeToAtomicString(ExecState*) const;
     363    JS_EXPORT_PRIVATE AtomicStringImpl* resolveRopeToExistingAtomicString(ExecState*) const;
     364    void resolveRopeSlowCase8(LChar*) const;
     365    void resolveRopeSlowCase(UChar*) const;
     366    void outOfMemory(ExecState*) const;
     367    void resolveRopeInternal8(LChar*) const;
     368    void resolveRopeInternal8NoSubstring(LChar*) const;
     369    void resolveRopeInternal16(UChar*) const;
     370    void resolveRopeInternal16NoSubstring(UChar*) const;
     371    void clearFibers() const;
     372
     373    JS_EXPORT_PRIVATE JSString* getIndexSlowCase(ExecState*, unsigned);
     374
     375    WriteBarrierBase<JSString>& fiber(unsigned i) const
     376    {
     377        ASSERT(!isSubstring());
     378        ASSERT(i < s_maxInternalRopeLength);
     379        return u[i].string;
     380    }
     381
     382    WriteBarrierBase<JSString>& substringBase() const
     383    {
     384        return u[1].string;
     385    }
     386
     387    uintptr_t& substringOffset() const
     388    {
     389        return u[2].number;
     390    }
     391
     392    static uintptr_t notSubstringSentinel()
     393    {
     394        return 0;
     395    }
     396
     397    static uintptr_t substringSentinel()
     398    {
     399        return 1;
     400    }
     401
     402    bool isSubstring() const
     403    {
     404        return u[0].number == substringSentinel();
     405    }
     406
     407    void setIsSubstring(bool isSubstring)
     408    {
     409        u[0].number = isSubstring ? substringSentinel() : notSubstringSentinel();
     410    }
     411
     412    mutable union {
     413        uintptr_t number;
     414        WriteBarrierBase<JSString> string;
     415    } u[s_maxInternalRopeLength];
     416};
     417
     418
     419inline const StringImpl* JSString::tryGetValueImpl() const
     420{
     421    return m_value.impl();
     422}
     423
     424JSString* asString(JSValue);
     425
     426inline JSString* asString(JSValue value)
     427{
     428    ASSERT(value.asCell()->isString());
     429    return jsCast<JSString*>(value.asCell());
     430}
     431
     432inline JSString* jsEmptyString(VM* vm)
     433{
     434    return vm->smallStrings.emptyString();
     435}
     436
     437ALWAYS_INLINE JSString* jsSingleCharacterString(VM* vm, UChar c)
     438{
     439    if (c <= maxSingleCharacterString)
     440        return vm->smallStrings.singleCharacterString(c);
     441    return JSString::create(*vm, String(&c, 1).impl());
     442}
     443
     444ALWAYS_INLINE JSString* jsSingleCharacterSubstring(ExecState* exec, const String& s, unsigned offset)
     445{
     446    VM* vm = &exec->vm();
     447    ASSERT(offset < static_cast<unsigned>(s.length()));
     448    UChar c = s.characterAt(offset);
     449    if (c <= maxSingleCharacterString)
     450        return vm->smallStrings.singleCharacterString(c);
     451    return JSString::create(*vm, StringImpl::createSubstringSharingImpl(s.impl(), offset, 1));
     452}
     453
     454inline JSString* jsNontrivialString(VM* vm, const String& s)
     455{
     456    ASSERT(s.length() > 1);
     457    return JSString::create(*vm, s.impl());
     458}
     459
     460ALWAYS_INLINE Identifier JSString::toIdentifier(ExecState* exec) const
     461{
     462    return Identifier(exec, toAtomicString(exec));
     463}
     464
     465ALWAYS_INLINE AtomicString JSString::toAtomicString(ExecState* exec) const
     466{
     467    if (isRope())
     468        static_cast<const JSRopeString*>(this)->resolveRopeToAtomicString(exec);
     469    return AtomicString(m_value);
     470}
     471
     472ALWAYS_INLINE AtomicStringImpl* JSString::toExistingAtomicString(ExecState* exec) const
     473{
     474    if (isRope())
     475        return static_cast<const JSRopeString*>(this)->resolveRopeToExistingAtomicString(exec);
     476    if (m_value.impl()->isAtomic())
     477        return static_cast<AtomicStringImpl*>(m_value.impl());
     478    if (AtomicStringImpl* existingAtomicString = AtomicString::find(m_value.impl())) {
     479        m_value = *existingAtomicString;
     480        setIs8Bit(m_value.impl()->is8Bit());
     481        return existingAtomicString;
     482    }
     483    return nullptr;
     484}
     485
     486inline const String& JSString::value(ExecState* exec) const
     487{
     488    if (isRope())
     489        static_cast<const JSRopeString*>(this)->resolveRope(exec);
     490    return m_value;
     491}
     492
     493inline const String& JSString::tryGetValue() const
     494{
     495    if (isRope())
     496        static_cast<const JSRopeString*>(this)->resolveRope(0);
     497    return m_value;
     498}
     499
     500inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
     501{
     502    ASSERT(canGetIndex(i));
     503    if (isRope())
     504        return static_cast<JSRopeString*>(this)->getIndexSlowCase(exec, i);
     505    ASSERT(i < m_value.length());
     506    return jsSingleCharacterSubstring(exec, m_value, i);
     507}
     508
     509inline JSString* jsString(VM* vm, const String& s)
     510{
     511    int size = s.length();
     512    if (!size)
    434513        return vm->smallStrings.emptyString();
    435     }
    436 
    437     ALWAYS_INLINE JSString* jsSingleCharacterString(VM* vm, UChar c)
    438     {
     514    if (size == 1) {
     515        UChar c = s.characterAt(0);
    439516        if (c <= maxSingleCharacterString)
    440517            return vm->smallStrings.singleCharacterString(c);
    441         return JSString::create(*vm, String(&c, 1).impl());
    442     }
    443 
    444     ALWAYS_INLINE JSString* jsSingleCharacterSubstring(ExecState* exec, const String& s, unsigned offset)
    445     {
    446         VM* vm = &exec->vm();
    447         ASSERT(offset < static_cast<unsigned>(s.length()));
     518    }
     519    return JSString::create(*vm, s.impl());
     520}
     521
     522inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
     523{
     524    ASSERT(offset <= static_cast<unsigned>(s->length()));
     525    ASSERT(length <= static_cast<unsigned>(s->length()));
     526    ASSERT(offset + length <= static_cast<unsigned>(s->length()));
     527    VM& vm = exec->vm();
     528    if (!length)
     529        return vm.smallStrings.emptyString();
     530    s->value(exec); // For effect. We need to ensure that any string that is used as a substring base is not a rope.
     531    return JSRopeString::create(vm, s, offset, length);
     532}
     533
     534inline JSString* jsSubstring8(VM* vm, const String& s, unsigned offset, unsigned length)
     535{
     536    ASSERT(offset <= static_cast<unsigned>(s.length()));
     537    ASSERT(length <= static_cast<unsigned>(s.length()));
     538    ASSERT(offset + length <= static_cast<unsigned>(s.length()));
     539    if (!length)
     540        return vm->smallStrings.emptyString();
     541    if (length == 1) {
    448542        UChar c = s.characterAt(offset);
    449543        if (c <= maxSingleCharacterString)
    450544            return vm->smallStrings.singleCharacterString(c);
    451         return JSString::create(*vm, StringImpl::createSubstringSharingImpl(s.impl(), offset, 1));
    452     }
    453 
    454     inline JSString* jsNontrivialString(VM* vm, const String& s)
    455     {
    456         ASSERT(s.length() > 1);
    457         return JSString::create(*vm, s.impl());
    458     }
    459 
    460     ALWAYS_INLINE Identifier JSString::toIdentifier(ExecState* exec) const
    461     {
    462         return Identifier(exec, toAtomicString(exec));
    463     }
    464 
    465     ALWAYS_INLINE AtomicString JSString::toAtomicString(ExecState* exec) const
    466     {
    467         if (isRope())
    468             static_cast<const JSRopeString*>(this)->resolveRopeToAtomicString(exec);
    469         return AtomicString(m_value);
    470     }
    471 
    472     ALWAYS_INLINE AtomicStringImpl* JSString::toExistingAtomicString(ExecState* exec) const
    473     {
    474         if (isRope())
    475             return static_cast<const JSRopeString*>(this)->resolveRopeToExistingAtomicString(exec);
    476         if (m_value.impl()->isAtomic())
    477             return static_cast<AtomicStringImpl*>(m_value.impl());
    478         if (AtomicStringImpl* existingAtomicString = AtomicString::find(m_value.impl())) {
    479             m_value = *existingAtomicString;
    480             setIs8Bit(m_value.impl()->is8Bit());
    481             return existingAtomicString;
    482         }
    483         return nullptr;
    484     }
    485 
    486     inline const String& JSString::value(ExecState* exec) const
    487     {
    488         if (isRope())
    489             static_cast<const JSRopeString*>(this)->resolveRope(exec);
    490         return m_value;
    491     }
    492 
    493     inline const String& JSString::tryGetValue() const
    494     {
    495         if (isRope())
    496             static_cast<const JSRopeString*>(this)->resolveRope(0);
    497         return m_value;
    498     }
    499 
    500     inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
    501     {
    502         ASSERT(canGetIndex(i));
    503         if (isRope())
    504             return static_cast<JSRopeString*>(this)->getIndexSlowCase(exec, i);
    505         ASSERT(i < m_value.length());
    506         return jsSingleCharacterSubstring(exec, m_value, i);
    507     }
    508 
    509     inline JSString* jsString(VM* vm, const String& s)
    510     {
    511         int size = s.length();
    512         if (!size)
    513             return vm->smallStrings.emptyString();
    514         if (size == 1) {
    515             UChar c = s.characterAt(0);
    516             if (c <= maxSingleCharacterString)
    517                 return vm->smallStrings.singleCharacterString(c);
    518         }
    519         return JSString::create(*vm, s.impl());
    520     }
    521 
    522     inline JSString* jsSubstring(ExecState* exec, JSString* s, unsigned offset, unsigned length)
    523     {
    524         ASSERT(offset <= static_cast<unsigned>(s->length()));
    525         ASSERT(length <= static_cast<unsigned>(s->length()));
    526         ASSERT(offset + length <= static_cast<unsigned>(s->length()));
    527         VM& vm = exec->vm();
    528         if (!length)
    529             return vm.smallStrings.emptyString();
    530         s->value(exec); // For effect. We need to ensure that any string that is used as a substring base is not a rope.
    531         return JSRopeString::create(vm, s, offset, length);
    532     }
    533 
    534     inline JSString* jsSubstring8(VM* vm, const String& s, unsigned offset, unsigned length)
    535     {
    536         ASSERT(offset <= static_cast<unsigned>(s.length()));
    537         ASSERT(length <= static_cast<unsigned>(s.length()));
    538         ASSERT(offset + length <= static_cast<unsigned>(s.length()));
    539         if (!length)
    540             return vm->smallStrings.emptyString();
    541         if (length == 1) {
    542             UChar c = s.characterAt(offset);
    543             if (c <= maxSingleCharacterString)
    544                 return vm->smallStrings.singleCharacterString(c);
    545         }
    546         return JSString::createHasOtherOwner(*vm, StringImpl::createSubstringSharingImpl8(s.impl(), offset, length));
    547     }
    548 
    549     inline JSString* jsSubstring(VM* vm, const String& s, unsigned offset, unsigned length)
    550     {
    551         ASSERT(offset <= static_cast<unsigned>(s.length()));
    552         ASSERT(length <= static_cast<unsigned>(s.length()));
    553         ASSERT(offset + length <= static_cast<unsigned>(s.length()));
    554         if (!length)
    555             return vm->smallStrings.emptyString();
    556         if (length == 1) {
    557             UChar c = s.characterAt(offset);
    558             if (c <= maxSingleCharacterString)
    559                 return vm->smallStrings.singleCharacterString(c);
    560         }
    561         return JSString::createHasOtherOwner(*vm, StringImpl::createSubstringSharingImpl(s.impl(), offset, length));
    562     }
    563 
    564     inline JSString* jsOwnedString(VM* vm, const String& s)
    565     {
    566         int size = s.length();
    567         if (!size)
    568             return vm->smallStrings.emptyString();
    569         if (size == 1) {
    570             UChar c = s.characterAt(0);
    571             if (c <= maxSingleCharacterString)
    572                 return vm->smallStrings.singleCharacterString(c);
    573         }
    574         return JSString::createHasOtherOwner(*vm, s.impl());
    575     }
    576 
    577     inline JSRopeString* jsStringBuilder(VM* vm)
    578     {
    579         return JSRopeString::createNull(*vm);
    580     }
    581 
    582     inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->vm()); }
    583     inline JSString* jsString(ExecState* exec, const String& s) { return jsString(&exec->vm(), s); }
    584     inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->vm(), c); }
    585     inline JSString* jsSubstring8(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->vm(), s, offset, length); }
    586     inline JSString* jsSubstring(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring(&exec->vm(), s, offset, length); }
    587     inline JSString* jsNontrivialString(ExecState* exec, const String& s) { return jsNontrivialString(&exec->vm(), s); }
    588     inline JSString* jsOwnedString(ExecState* exec, const String& s) { return jsOwnedString(&exec->vm(), s); }
    589 
    590     JS_EXPORT_PRIVATE JSString* jsStringWithCacheSlowCase(VM&, StringImpl&);
    591 
    592     ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const String& s)
    593     {
    594         VM& vm = exec->vm();
    595         StringImpl* stringImpl = s.impl();
    596         if (!stringImpl || !stringImpl->length())
    597             return jsEmptyString(&vm);
    598 
    599         if (stringImpl->length() == 1) {
    600             UChar singleCharacter = (*stringImpl)[0u];
    601             if (singleCharacter <= maxSingleCharacterString)
    602                 return vm.smallStrings.singleCharacterString(static_cast<unsigned char>(singleCharacter));
    603         }
    604 
    605         if (JSString* lastCachedString = vm.lastCachedString.get()) {
    606             if (lastCachedString->tryGetValueImpl() == stringImpl)
    607                 return lastCachedString;
    608         }
    609 
    610         return jsStringWithCacheSlowCase(vm, *stringImpl);
    611     }
    612 
    613     ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const AtomicString& s)
    614     {
    615         return jsStringWithCache(exec, s.string());
    616     }
    617 
    618     ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
    619     {
    620         if (propertyName == exec->propertyNames().length) {
    621             slot.setValue(this, DontEnum | DontDelete | ReadOnly, jsNumber(m_length));
    622             return true;
    623         }
    624 
    625         unsigned i = propertyName.asIndex();
    626         if (i < m_length) {
    627             ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
    628             slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, i));
    629             return true;
    630         }
    631 
    632         return false;
    633     }
    634            
    635     ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
    636     {
    637         if (propertyName < m_length) {
    638             slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, propertyName));
    639             return true;
    640         }
    641 
    642         return false;
    643     }
    644 
    645     inline bool isJSString(JSValue v) { return v.isCell() && v.asCell()->type() == StringType; }
    646 
    647     // --- JSValue inlines ----------------------------
    648        
    649     inline bool JSValue::toBoolean(ExecState* exec) const
    650     {
    651         if (isInt32())
    652             return asInt32();
    653         if (isDouble())
    654             return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
    655         if (isCell())
    656             return asCell()->toBoolean(exec);
    657         return isTrue(); // false, null, and undefined all convert to false.
    658     }
    659 
    660     inline JSString* JSValue::toString(ExecState* exec) const
    661     {
    662         if (isString())
    663             return jsCast<JSString*>(asCell());
    664         return toStringSlowCase(exec);
    665     }
    666 
    667     inline String JSValue::toWTFString(ExecState* exec) const
    668     {
    669         if (isString())
    670             return static_cast<JSString*>(asCell())->value(exec);
    671         return toWTFStringSlowCase(exec);
    672     }
    673 
    674     ALWAYS_INLINE String inlineJSValueNotStringtoString(const JSValue& value, ExecState* exec)
    675     {
    676         VM& vm = exec->vm();
    677         if (value.isInt32())
    678             return vm.numericStrings.add(value.asInt32());
    679         if (value.isDouble())
    680             return vm.numericStrings.add(value.asDouble());
    681         if (value.isTrue())
    682             return vm.propertyNames->trueKeyword.string();
    683         if (value.isFalse())
    684             return vm.propertyNames->falseKeyword.string();
    685         if (value.isNull())
    686             return vm.propertyNames->nullKeyword.string();
    687         if (value.isUndefined())
    688             return vm.propertyNames->undefinedKeyword.string();
    689         return value.toString(exec)->value(exec);
    690     }
    691 
    692     ALWAYS_INLINE String JSValue::toWTFStringInline(ExecState* exec) const
    693     {
    694         if (isString())
    695             return static_cast<JSString*>(asCell())->value(exec);
    696 
    697         return inlineJSValueNotStringtoString(*this, exec);
    698     }
     545    }
     546    return JSString::createHasOtherOwner(*vm, StringImpl::createSubstringSharingImpl8(s.impl(), offset, length));
     547}
     548
     549inline JSString* jsSubstring(VM* vm, const String& s, unsigned offset, unsigned length)
     550{
     551    ASSERT(offset <= static_cast<unsigned>(s.length()));
     552    ASSERT(length <= static_cast<unsigned>(s.length()));
     553    ASSERT(offset + length <= static_cast<unsigned>(s.length()));
     554    if (!length)
     555        return vm->smallStrings.emptyString();
     556    if (length == 1) {
     557        UChar c = s.characterAt(offset);
     558        if (c <= maxSingleCharacterString)
     559            return vm->smallStrings.singleCharacterString(c);
     560    }
     561    return JSString::createHasOtherOwner(*vm, StringImpl::createSubstringSharingImpl(s.impl(), offset, length));
     562}
     563
     564inline JSString* jsOwnedString(VM* vm, const String& s)
     565{
     566    int size = s.length();
     567    if (!size)
     568        return vm->smallStrings.emptyString();
     569    if (size == 1) {
     570        UChar c = s.characterAt(0);
     571        if (c <= maxSingleCharacterString)
     572            return vm->smallStrings.singleCharacterString(c);
     573    }
     574    return JSString::createHasOtherOwner(*vm, s.impl());
     575}
     576
     577inline JSRopeString* jsStringBuilder(VM* vm)
     578{
     579    return JSRopeString::createNull(*vm);
     580}
     581
     582inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->vm()); }
     583inline JSString* jsString(ExecState* exec, const String& s) { return jsString(&exec->vm(), s); }
     584inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->vm(), c); }
     585inline JSString* jsSubstring8(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->vm(), s, offset, length); }
     586inline JSString* jsSubstring(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring(&exec->vm(), s, offset, length); }
     587inline JSString* jsNontrivialString(ExecState* exec, const String& s) { return jsNontrivialString(&exec->vm(), s); }
     588inline JSString* jsOwnedString(ExecState* exec, const String& s) { return jsOwnedString(&exec->vm(), s); }
     589
     590JS_EXPORT_PRIVATE JSString* jsStringWithCacheSlowCase(VM&, StringImpl&);
     591
     592ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const String& s)
     593{
     594    VM& vm = exec->vm();
     595    StringImpl* stringImpl = s.impl();
     596    if (!stringImpl || !stringImpl->length())
     597        return jsEmptyString(&vm);
     598
     599    if (stringImpl->length() == 1) {
     600        UChar singleCharacter = (*stringImpl)[0u];
     601        if (singleCharacter <= maxSingleCharacterString)
     602            return vm.smallStrings.singleCharacterString(static_cast<unsigned char>(singleCharacter));
     603    }
     604
     605    if (JSString* lastCachedString = vm.lastCachedString.get()) {
     606        if (lastCachedString->tryGetValueImpl() == stringImpl)
     607            return lastCachedString;
     608    }
     609
     610    return jsStringWithCacheSlowCase(vm, *stringImpl);
     611}
     612
     613ALWAYS_INLINE JSString* jsStringWithCache(ExecState* exec, const AtomicString& s)
     614{
     615    return jsStringWithCache(exec, s.string());
     616}
     617
     618ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot)
     619{
     620    if (propertyName == exec->propertyNames().length) {
     621        slot.setValue(this, DontEnum | DontDelete | ReadOnly, jsNumber(m_length));
     622        return true;
     623    }
     624
     625    unsigned i = propertyName.asIndex();
     626    if (i < m_length) {
     627        ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
     628        slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, i));
     629        return true;
     630    }
     631
     632    return false;
     633}
     634
     635ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
     636{
     637    if (propertyName < m_length) {
     638        slot.setValue(this, DontDelete | ReadOnly, getIndex(exec, propertyName));
     639        return true;
     640    }
     641
     642    return false;
     643}
     644
     645inline bool isJSString(JSValue v) { return v.isCell() && v.asCell()->type() == StringType; }
     646
     647// --- JSValue inlines ----------------------------
     648
     649inline bool JSValue::toBoolean(ExecState* exec) const
     650{
     651    if (isInt32())
     652        return asInt32();
     653    if (isDouble())
     654        return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
     655    if (isCell())
     656        return asCell()->toBoolean(exec);
     657    return isTrue(); // false, null, and undefined all convert to false.
     658}
     659
     660inline JSString* JSValue::toString(ExecState* exec) const
     661{
     662    if (isString())
     663        return jsCast<JSString*>(asCell());
     664    return toStringSlowCase(exec);
     665}
     666
     667inline String JSValue::toWTFString(ExecState* exec) const
     668{
     669    if (isString())
     670        return static_cast<JSString*>(asCell())->value(exec);
     671    return toWTFStringSlowCase(exec);
     672}
     673
     674ALWAYS_INLINE String inlineJSValueNotStringtoString(const JSValue& value, ExecState* exec)
     675{
     676    VM& vm = exec->vm();
     677    if (value.isInt32())
     678        return vm.numericStrings.add(value.asInt32());
     679    if (value.isDouble())
     680        return vm.numericStrings.add(value.asDouble());
     681    if (value.isTrue())
     682        return vm.propertyNames->trueKeyword.string();
     683    if (value.isFalse())
     684        return vm.propertyNames->falseKeyword.string();
     685    if (value.isNull())
     686        return vm.propertyNames->nullKeyword.string();
     687    if (value.isUndefined())
     688        return vm.propertyNames->undefinedKeyword.string();
     689    return value.toString(exec)->value(exec);
     690}
     691
     692ALWAYS_INLINE String JSValue::toWTFStringInline(ExecState* exec) const
     693{
     694    if (isString())
     695        return static_cast<JSString*>(asCell())->value(exec);
     696
     697    return inlineJSValueNotStringtoString(*this, exec);
     698}
    699699
    700700} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSTypeInfo.h

    r171939 r173269  
    3535namespace JSC {
    3636
    37     class LLIntOffsetsExtractor;
     37class LLIntOffsetsExtractor;
    3838
    39     static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
    40     static const unsigned ImplementsHasInstance = 1 << 1;
    41     static const unsigned OverridesHasInstance = 1 << 2;
    42     static const unsigned ImplementsDefaultHasInstance = 1 << 3;
    43     static const unsigned IsEnvironmentRecord = 1 << 4;
    44     static const unsigned OverridesGetOwnPropertySlot = 1 << 5;
    45     static const unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 6;
     39static const unsigned MasqueradesAsUndefined = 1; // WebCore uses MasqueradesAsUndefined to make document.all undetectable.
     40static const unsigned ImplementsHasInstance = 1 << 1;
     41static const unsigned OverridesHasInstance = 1 << 2;
     42static const unsigned ImplementsDefaultHasInstance = 1 << 3;
     43static const unsigned IsEnvironmentRecord = 1 << 4;
     44static const unsigned OverridesGetOwnPropertySlot = 1 << 5;
     45static const unsigned InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero = 1 << 6;
    4646
    47     static const unsigned OverridesGetPropertyNames = 1 << 8;
    48     static const unsigned ProhibitsPropertyCaching = 1 << 9;
    49     static const unsigned HasImpureGetOwnPropertySlot = 1 << 10;
    50     static const unsigned NewImpurePropertyFiresWatchpoints = 1 << 11;
    51     static const unsigned StructureIsImmortal = 1 << 12;
     47static const unsigned OverridesGetPropertyNames = 1 << 8;
     48static const unsigned ProhibitsPropertyCaching = 1 << 9;
     49static const unsigned HasImpureGetOwnPropertySlot = 1 << 10;
     50static const unsigned NewImpurePropertyFiresWatchpoints = 1 << 11;
     51static const unsigned StructureIsImmortal = 1 << 12;
    5252
    53     class TypeInfo {
    54     public:
    55         typedef uint8_t InlineTypeFlags;
    56         typedef uint8_t OutOfLineTypeFlags;
     53class TypeInfo {
     54public:
     55    typedef uint8_t InlineTypeFlags;
     56    typedef uint8_t OutOfLineTypeFlags;
    5757
    58         TypeInfo(JSType type, unsigned flags = 0)
    59             : TypeInfo(type, flags & 0xff, flags >> 8)
    60         {
    61         }
    62        
    63         TypeInfo(JSType type, InlineTypeFlags inlineTypeFlags, OutOfLineTypeFlags outOfLineTypeFlags)
    64             : m_type(type)
    65             , m_flags(inlineTypeFlags)
    66             , m_flags2(outOfLineTypeFlags)
    67         {
    68             // No object that doesn't ImplementsHasInstance should override it!
    69             ASSERT((m_flags & (ImplementsHasInstance | OverridesHasInstance)) != OverridesHasInstance);
    70             // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
    71             if ((m_flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
    72                 m_flags |= ImplementsDefaultHasInstance;
    73         }
     58    TypeInfo(JSType type, unsigned flags = 0)
     59        : TypeInfo(type, flags & 0xff, flags >> 8)
     60    {
     61    }
    7462
    75         JSType type() const { return static_cast<JSType>(m_type); }
    76         bool isObject() const { return isObject(type()); }
    77         static bool isObject(JSType type) { return type >= ObjectType; }
    78         bool isFinalObject() const { return type() == FinalObjectType; }
    79         bool isNumberObject() const { return type() == NumberObjectType; }
    80         bool isName() const { return type() == NameInstanceType; }
     63    TypeInfo(JSType type, InlineTypeFlags inlineTypeFlags, OutOfLineTypeFlags outOfLineTypeFlags)
     64        : m_type(type)
     65        , m_flags(inlineTypeFlags)
     66        , m_flags2(outOfLineTypeFlags)
     67    {
     68        // No object that doesn't ImplementsHasInstance should override it!
     69        ASSERT((m_flags & (ImplementsHasInstance | OverridesHasInstance)) != OverridesHasInstance);
     70        // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
     71        if ((m_flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
     72            m_flags |= ImplementsDefaultHasInstance;
     73    }
    8174
    82         unsigned flags() const { return (static_cast<unsigned>(m_flags2) << 8) | static_cast<unsigned>(m_flags); }
    83         bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); }
    84         bool implementsHasInstance() const { return isSetOnFlags1(ImplementsHasInstance); }
    85         bool isEnvironmentRecord() const { return isSetOnFlags1(IsEnvironmentRecord); }
    86         bool overridesHasInstance() const { return isSetOnFlags1(OverridesHasInstance); }
    87         bool implementsDefaultHasInstance() const { return isSetOnFlags1(ImplementsDefaultHasInstance); }
    88         bool overridesGetOwnPropertySlot() const { return overridesGetOwnPropertySlot(inlineTypeFlags()); }
    89         static bool overridesGetOwnPropertySlot(InlineTypeFlags flags) { return flags & OverridesGetOwnPropertySlot; }
    90         bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags1(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }
    91         bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
    92         bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
    93         bool hasImpureGetOwnPropertySlot() const { return isSetOnFlags2(HasImpureGetOwnPropertySlot); }
    94         bool newImpurePropertyFiresWatchpoints() const { return isSetOnFlags2(NewImpurePropertyFiresWatchpoints); }
    95         bool structureIsImmortal() const { return isSetOnFlags2(StructureIsImmortal); }
     75    JSType type() const { return static_cast<JSType>(m_type); }
     76    bool isObject() const { return isObject(type()); }
     77    static bool isObject(JSType type) { return type >= ObjectType; }
     78    bool isFinalObject() const { return type() == FinalObjectType; }
     79    bool isNumberObject() const { return type() == NumberObjectType; }
     80    bool isName() const { return type() == NameInstanceType; }
    9681
    97         static ptrdiff_t flagsOffset()
    98         {
    99             return OBJECT_OFFSETOF(TypeInfo, m_flags);
    100         }
     82    unsigned flags() const { return (static_cast<unsigned>(m_flags2) << 8) | static_cast<unsigned>(m_flags); }
     83    bool masqueradesAsUndefined() const { return isSetOnFlags1(MasqueradesAsUndefined); }
     84    bool implementsHasInstance() const { return isSetOnFlags1(ImplementsHasInstance); }
     85    bool isEnvironmentRecord() const { return isSetOnFlags1(IsEnvironmentRecord); }
     86    bool overridesHasInstance() const { return isSetOnFlags1(OverridesHasInstance); }
     87    bool implementsDefaultHasInstance() const { return isSetOnFlags1(ImplementsDefaultHasInstance); }
     88    bool overridesGetOwnPropertySlot() const { return overridesGetOwnPropertySlot(inlineTypeFlags()); }
     89    static bool overridesGetOwnPropertySlot(InlineTypeFlags flags) { return flags & OverridesGetOwnPropertySlot; }
     90    bool interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero() const { return isSetOnFlags1(InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero); }
     91    bool overridesGetPropertyNames() const { return isSetOnFlags2(OverridesGetPropertyNames); }
     92    bool prohibitsPropertyCaching() const { return isSetOnFlags2(ProhibitsPropertyCaching); }
     93    bool hasImpureGetOwnPropertySlot() const { return isSetOnFlags2(HasImpureGetOwnPropertySlot); }
     94    bool newImpurePropertyFiresWatchpoints() const { return isSetOnFlags2(NewImpurePropertyFiresWatchpoints); }
     95    bool structureIsImmortal() const { return isSetOnFlags2(StructureIsImmortal); }
    10196
    102         static ptrdiff_t typeOffset()
    103         {
    104             return OBJECT_OFFSETOF(TypeInfo, m_type);
    105         }
     97    static ptrdiff_t flagsOffset()
     98    {
     99        return OBJECT_OFFSETOF(TypeInfo, m_flags);
     100    }
    106101
    107         InlineTypeFlags inlineTypeFlags() const { return m_flags; }
    108         OutOfLineTypeFlags outOfLineTypeFlags() const { return m_flags2; }
     102    static ptrdiff_t typeOffset()
     103    {
     104        return OBJECT_OFFSETOF(TypeInfo, m_type);
     105    }
    109106
    110     private:
    111         friend class LLIntOffsetsExtractor;
    112        
    113         bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
    114         bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
     107    InlineTypeFlags inlineTypeFlags() const { return m_flags; }
     108    OutOfLineTypeFlags outOfLineTypeFlags() const { return m_flags2; }
    115109
    116         unsigned char m_type;
    117         unsigned char m_flags;
    118         unsigned char m_flags2;
    119     };
     110private:
     111    friend class LLIntOffsetsExtractor;
     112
     113    bool isSetOnFlags1(unsigned flag) const { ASSERT(flag <= (1 << 7)); return m_flags & flag; }
     114    bool isSetOnFlags2(unsigned flag) const { ASSERT(flag >= (1 << 8)); return m_flags2 & (flag >> 8); }
     115
     116    unsigned char m_type;
     117    unsigned char m_flags;
     118    unsigned char m_flags2;
     119};
    120120
    121121}
  • trunk/Source/JavaScriptCore/runtime/JSWrapperObject.h

    r171939 r173269  
    2727namespace JSC {
    2828
    29     // This class is used as a base for classes such as String,
    30     // Number, Boolean and Date which are wrappers for primitive types.
    31     class JSWrapperObject : public JSDestructibleObject {
    32     public:
    33         typedef JSDestructibleObject Base;
     29// This class is used as a base for classes such as String,
     30// Number, Boolean and Date which are wrappers for primitive types.
     31class JSWrapperObject : public JSDestructibleObject {
     32public:
     33    typedef JSDestructibleObject Base;
    3434
    35         static size_t allocationSize(size_t inlineCapacity)
    36         {
    37             ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
    38             return sizeof(JSWrapperObject);
    39         }
    40 
    41         JSValue internalValue() const;
    42         void setInternalValue(VM&, JSValue);
    43 
    44         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    45         {
    46             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    47         }
    48        
    49         static ptrdiff_t internalValueOffset() { return OBJECT_OFFSETOF(JSWrapperObject, m_internalValue); }
    50         static ptrdiff_t internalValueCellOffset()
    51         {
    52 #if USE(JSVALUE64)
    53             return internalValueOffset();
    54 #else
    55             return internalValueOffset() + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload);
    56 #endif
    57         }
    58 
    59     protected:
    60         explicit JSWrapperObject(VM&, Structure*);
    61 
    62         JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
    63 
    64     private:
    65         WriteBarrier<Unknown> m_internalValue;
    66     };
    67 
    68     inline JSWrapperObject::JSWrapperObject(VM& vm, Structure* structure)
    69         : JSDestructibleObject(vm, structure)
     35    static size_t allocationSize(size_t inlineCapacity)
    7036    {
     37        ASSERT_UNUSED(inlineCapacity, !inlineCapacity);
     38        return sizeof(JSWrapperObject);
    7139    }
    7240
    73     inline JSValue JSWrapperObject::internalValue() const
    74     {
    75         return m_internalValue.get();
     41    JSValue internalValue() const;
     42    void setInternalValue(VM&, JSValue);
     43
     44    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     45    {
     46        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    7647    }
    7748
    78     inline void JSWrapperObject::setInternalValue(VM& vm, JSValue value)
     49    static ptrdiff_t internalValueOffset() { return OBJECT_OFFSETOF(JSWrapperObject, m_internalValue); }
     50    static ptrdiff_t internalValueCellOffset()
    7951    {
    80         ASSERT(value);
    81         ASSERT(!value.isObject());
    82         m_internalValue.set(vm, this, value);
     52#if USE(JSVALUE64)
     53        return internalValueOffset();
     54#else
     55        return internalValueOffset() + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload);
     56#endif
    8357    }
     58
     59protected:
     60    explicit JSWrapperObject(VM&, Structure*);
     61
     62    JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
     63
     64private:
     65    WriteBarrier<Unknown> m_internalValue;
     66};
     67
     68inline JSWrapperObject::JSWrapperObject(VM& vm, Structure* structure)
     69    : JSDestructibleObject(vm, structure)
     70{
     71}
     72
     73inline JSValue JSWrapperObject::internalValue() const
     74{
     75    return m_internalValue.get();
     76}
     77
     78inline void JSWrapperObject::setInternalValue(VM& vm, JSValue value)
     79{
     80    ASSERT(value);
     81    ASSERT(!value.isObject());
     82    m_internalValue.set(vm, this, value);
     83}
    8484
    8585} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/Lookup.h

    r171824 r173269  
    3434
    3535namespace JSC {
    36     struct CompactHashIndex {
    37         const int16_t value;
    38         const int16_t next;
     36
     37struct CompactHashIndex {
     38    const int16_t value;
     39    const int16_t next;
     40};
     41
     42// FIXME: There is no reason this get function can't be simpler.
     43// ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject)
     44typedef PropertySlot::GetValueFunc GetFunction;
     45typedef PutPropertySlot::PutValueFunc PutFunction;
     46typedef FunctionExecutable* (*BuiltinGenerator)(VM&);
     47
     48// Hash table generated by the create_hash_table script.
     49struct HashTableValue {
     50    const char* m_key; // property name
     51    unsigned m_attributes; // JSObject attributes
     52    Intrinsic m_intrinsic;
     53    intptr_t m_value1;
     54    intptr_t m_value2;
     55
     56    unsigned attributes() const { return m_attributes; }
     57
     58    Intrinsic intrinsic() const { ASSERT(m_attributes & Function); return m_intrinsic; }
     59    BuiltinGenerator builtinGenerator() const { ASSERT(m_attributes & Builtin); return reinterpret_cast<BuiltinGenerator>(m_value1); }
     60    NativeFunction function() const { ASSERT(m_attributes & Function); return reinterpret_cast<NativeFunction>(m_value1); }
     61    unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_value2); }
     62
     63    GetFunction propertyGetter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrConstant)); return reinterpret_cast<GetFunction>(m_value1); }
     64    PutFunction propertyPutter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrConstant)); return reinterpret_cast<PutFunction>(m_value2); }
     65
     66    intptr_t constantInteger() const { ASSERT(m_attributes & ConstantInteger); return m_value1; }
     67
     68    intptr_t lexerValue() const { ASSERT(!m_attributes); return m_value1; }
     69};
     70
     71struct HashTable {
     72    mutable int numberOfValues;
     73    int indexMask;
     74    bool hasSetterOrReadonlyProperties;
     75
     76    const HashTableValue* values; // Fixed values generated by script.
     77    mutable const char** keys; // Table allocated at runtime.
     78    const CompactHashIndex* index;
     79
     80    ALWAYS_INLINE HashTable copy() const
     81    {
     82        // Don't copy dynamic table since it's thread specific.
     83        HashTable result = { numberOfValues, indexMask, hasSetterOrReadonlyProperties, values, 0, index };
     84        return result;
     85    }
     86
     87    ALWAYS_INLINE void initializeIfNeeded() const
     88    {
     89        if (!keys)
     90            createTable();
     91    }
     92
     93    JS_EXPORT_PRIVATE void deleteTable() const;
     94
     95    // Find an entry in the table, and return the entry.
     96    ALWAYS_INLINE const HashTableValue* entry(PropertyName propertyName) const
     97    {
     98        initializeIfNeeded();
     99
     100        StringImpl* impl = propertyName.uid();
     101        if (!impl)
     102            return 0;
     103
     104        ASSERT(keys);
     105
     106        int indexEntry = impl->existingHash() & indexMask;
     107        int valueIndex = index[indexEntry].value;
     108        if (valueIndex == -1)
     109            return 0;
     110
     111        while (true) {
     112            if (WTF::equal(impl, keys[valueIndex]))
     113                return &values[valueIndex];
     114
     115            indexEntry = index[indexEntry].next;
     116            if (indexEntry == -1)
     117                return nullptr;
     118            valueIndex = index[indexEntry].value;
     119            ASSERT(valueIndex != -1);
     120        };
     121    }
     122
     123    class ConstIterator {
     124    public:
     125        ConstIterator(const HashTable* table, int position)
     126            : m_table(table)
     127            , m_position(position)
     128        {
     129            skipInvalidKeys();
     130        }
     131
     132        const HashTableValue* value()
     133        {
     134            return &m_table->values[m_position];
     135        }
     136
     137        const char* key()
     138        {
     139            return m_table->keys[m_position];
     140        }
     141
     142        const HashTableValue* operator->()
     143        {
     144            return value();
     145        }
     146
     147        bool operator!=(const ConstIterator& other)
     148        {
     149            ASSERT(m_table == other.m_table);
     150            return m_position != other.m_position;
     151        }
     152
     153        ConstIterator& operator++()
     154        {
     155            ASSERT(m_position < m_table->numberOfValues);
     156            ++m_position;
     157            skipInvalidKeys();
     158            return *this;
     159        }
     160
     161    private:
     162        void skipInvalidKeys()
     163        {
     164            ASSERT(m_position <= m_table->numberOfValues);
     165            while (m_position < m_table->numberOfValues && !m_table->keys[m_position])
     166                ++m_position;
     167            ASSERT(m_position <= m_table->numberOfValues);
     168        }
     169
     170        const HashTable* m_table;
     171        int m_position;
    39172    };
    40173
    41     // FIXME: There is no reason this get function can't be simpler.
    42     // ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject)
    43     typedef PropertySlot::GetValueFunc GetFunction;
    44     typedef PutPropertySlot::PutValueFunc PutFunction;
    45     typedef FunctionExecutable* (*BuiltinGenerator)(VM&);
    46 
    47     // Hash table generated by the create_hash_table script.
    48     struct HashTableValue {
    49         const char* m_key; // property name
    50         unsigned m_attributes; // JSObject attributes
    51         Intrinsic m_intrinsic;
    52         intptr_t m_value1;
    53         intptr_t m_value2;
    54 
    55         unsigned attributes() const { return m_attributes; }
    56 
    57         Intrinsic intrinsic() const { ASSERT(m_attributes & Function); return m_intrinsic; }
    58         BuiltinGenerator builtinGenerator() const { ASSERT(m_attributes & Builtin); return reinterpret_cast<BuiltinGenerator>(m_value1); }
    59         NativeFunction function() const { ASSERT(m_attributes & Function); return reinterpret_cast<NativeFunction>(m_value1); }
    60         unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_value2); }
    61 
    62         GetFunction propertyGetter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrConstant)); return reinterpret_cast<GetFunction>(m_value1); }
    63         PutFunction propertyPutter() const { ASSERT(!(m_attributes & BuiltinOrFunctionOrConstant)); return reinterpret_cast<PutFunction>(m_value2); }
    64 
    65         intptr_t constantInteger() const { ASSERT(m_attributes & ConstantInteger); return m_value1; }
    66 
    67         intptr_t lexerValue() const { ASSERT(!m_attributes); return m_value1; }
    68     };
    69 
    70     struct HashTable {
    71         mutable int numberOfValues;
    72         int indexMask;
    73         bool hasSetterOrReadonlyProperties;
    74 
    75         const HashTableValue* values; // Fixed values generated by script.
    76         mutable const char** keys; // Table allocated at runtime.
    77         const CompactHashIndex* index;
    78 
    79         ALWAYS_INLINE HashTable copy() const
    80         {
    81             // Don't copy dynamic table since it's thread specific.
    82             HashTable result = { numberOfValues, indexMask, hasSetterOrReadonlyProperties, values, 0, index };
    83             return result;
    84         }
    85 
    86         ALWAYS_INLINE void initializeIfNeeded() const
    87         {
    88             if (!keys)
    89                 createTable();
    90         }
    91 
    92         JS_EXPORT_PRIVATE void deleteTable() const;
    93 
    94         // Find an entry in the table, and return the entry.
    95         ALWAYS_INLINE const HashTableValue* entry(PropertyName propertyName) const
    96         {
    97             initializeIfNeeded();
    98 
    99             StringImpl* impl = propertyName.uid();
    100             if (!impl)
    101                 return 0;
    102        
    103             ASSERT(keys);
    104 
    105             int indexEntry = impl->existingHash() & indexMask;
    106             int valueIndex = index[indexEntry].value;
    107             if (valueIndex == -1)
    108                 return 0;
    109 
    110             while (true) {
    111                 if (WTF::equal(impl, keys[valueIndex]))
    112                     return &values[valueIndex];
    113 
    114                 indexEntry = index[indexEntry].next;
    115                 if (indexEntry == -1)
    116                     return nullptr;
    117                 valueIndex = index[indexEntry].value;
    118                 ASSERT(valueIndex != -1);
    119             };
    120         }
    121 
    122         class ConstIterator {
    123         public:
    124             ConstIterator(const HashTable* table, int position)
    125                 : m_table(table)
    126                 , m_position(position)
    127             {
    128                 skipInvalidKeys();
    129             }
    130 
    131             const HashTableValue* value()
    132             {
    133                 return &m_table->values[m_position];
    134             }
    135 
    136             const char* key()
    137             {
    138                 return m_table->keys[m_position];
    139             }
    140 
    141             const HashTableValue* operator->()
    142             {
    143                 return value();
    144             }
    145 
    146             bool operator!=(const ConstIterator& other)
    147             {
    148                 ASSERT(m_table == other.m_table);
    149                 return m_position != other.m_position;
    150             }
    151            
    152             ConstIterator& operator++()
    153             {
    154                 ASSERT(m_position < m_table->numberOfValues);
    155                 ++m_position;
    156                 skipInvalidKeys();
    157                 return *this;
    158             }
    159 
    160         private:
    161             void skipInvalidKeys()
    162             {
    163                 ASSERT(m_position <= m_table->numberOfValues);
    164                 while (m_position < m_table->numberOfValues && !m_table->keys[m_position])
    165                     ++m_position;
    166                 ASSERT(m_position <= m_table->numberOfValues);
    167             }
    168            
    169             const HashTable* m_table;
    170             int m_position;
    171         };
    172 
    173         ConstIterator begin() const
    174         {
    175             initializeIfNeeded();
    176             return ConstIterator(this, 0);
    177         }
    178         ConstIterator end() const
    179         {
    180             initializeIfNeeded();
    181             return ConstIterator(this, numberOfValues);
    182         }
    183 
    184     private:
    185         // Convert the hash table keys to identifiers.
    186         JS_EXPORT_PRIVATE void createTable() const;
    187     };
    188 
    189     JS_EXPORT_PRIVATE bool setUpStaticFunctionSlot(ExecState*, const HashTableValue*, JSObject* thisObject, PropertyName, PropertySlot&);
    190 
    191     /**
    192      * This method does it all (looking in the hashtable, checking for function
    193      * overrides, creating the function or retrieving from cache, calling
    194      * getValueProperty in case of a non-function property, forwarding to parent if
    195      * unknown property).
    196      */
    197     template <class ThisImp, class ParentImp>
    198     inline bool getStaticPropertySlot(ExecState* exec, const HashTable& table, ThisImp* thisObj, PropertyName propertyName, PropertySlot& slot)
    199     {
    200         const HashTableValue* entry = table.entry(propertyName);
    201 
    202         if (!entry) // not found, forward to parent
    203             return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
    204 
    205         if (entry->attributes() & BuiltinOrFunction)
    206             return setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
    207 
    208         if (entry->attributes() & ConstantInteger) {
    209             slot.setValue(thisObj, entry->attributes(), jsNumber(entry->constantInteger()));
    210             return true;
    211         }
    212    
    213         slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
     174    ConstIterator begin() const
     175    {
     176        initializeIfNeeded();
     177        return ConstIterator(this, 0);
     178    }
     179    ConstIterator end() const
     180    {
     181        initializeIfNeeded();
     182        return ConstIterator(this, numberOfValues);
     183    }
     184
     185private:
     186    // Convert the hash table keys to identifiers.
     187    JS_EXPORT_PRIVATE void createTable() const;
     188};
     189
     190JS_EXPORT_PRIVATE bool setUpStaticFunctionSlot(ExecState*, const HashTableValue*, JSObject* thisObject, PropertyName, PropertySlot&);
     191
     192/**
     193 * This method does it all (looking in the hashtable, checking for function
     194 * overrides, creating the function or retrieving from cache, calling
     195 * getValueProperty in case of a non-function property, forwarding to parent if
     196 * unknown property).
     197 */
     198template <class ThisImp, class ParentImp>
     199inline bool getStaticPropertySlot(ExecState* exec, const HashTable& table, ThisImp* thisObj, PropertyName propertyName, PropertySlot& slot)
     200{
     201    const HashTableValue* entry = table.entry(propertyName);
     202
     203    if (!entry) // not found, forward to parent
     204        return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
     205
     206    if (entry->attributes() & BuiltinOrFunction)
     207        return setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
     208
     209    if (entry->attributes() & ConstantInteger) {
     210        slot.setValue(thisObj, entry->attributes(), jsNumber(entry->constantInteger()));
    214211        return true;
    215212    }
    216213
    217     /**
    218      * Simplified version of getStaticPropertySlot in case there are only functions.
    219      * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing
    220      * a dummy getValueProperty.
    221      */
    222     template <class ParentImp>
    223     inline bool getStaticFunctionSlot(ExecState* exec, const HashTable& table, JSObject* thisObj, PropertyName propertyName, PropertySlot& slot)
    224     {
    225         if (ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot))
    226             return true;
    227 
    228         const HashTableValue* entry = table.entry(propertyName);
    229         if (!entry)
    230             return false;
    231 
    232         return setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
    233     }
    234 
    235     /**
    236      * Simplified version of getStaticPropertySlot in case there are no functions, only "values".
    237      * Using this instead of getStaticPropertySlot removes the need for a FuncImp class.
    238      */
    239     template <class ThisImp, class ParentImp>
    240     inline bool getStaticValueSlot(ExecState* exec, const HashTable& table, ThisImp* thisObj, PropertyName propertyName, PropertySlot& slot)
    241     {
    242         const HashTableValue* entry = table.entry(propertyName);
    243 
    244         if (!entry) // not found, forward to parent
    245             return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
    246 
    247         ASSERT(!(entry->attributes() & BuiltinOrFunction));
    248 
    249         if (entry->attributes() & ConstantInteger) {
    250             slot.setValue(thisObj, entry->attributes(), jsNumber(entry->constantInteger()));
    251             return true;
    252         }
    253 
    254         slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
     214    slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
     215    return true;
     216}
     217
     218/**
     219 * Simplified version of getStaticPropertySlot in case there are only functions.
     220 * Using this instead of getStaticPropertySlot allows 'this' to avoid implementing
     221 * a dummy getValueProperty.
     222 */
     223template <class ParentImp>
     224inline bool getStaticFunctionSlot(ExecState* exec, const HashTable& table, JSObject* thisObj, PropertyName propertyName, PropertySlot& slot)
     225{
     226    if (ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot))
    255227        return true;
    256     }
    257 
    258     inline void putEntry(ExecState* exec, const HashTableValue* entry, JSObject* base, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
    259     {
    260         // If this is a function put it as an override property.
    261         if (entry->attributes() & BuiltinOrFunction) {
    262             if (JSObject* thisObject = jsDynamicCast<JSObject*>(slot.thisValue()))
    263                 thisObject->putDirect(exec->vm(), propertyName, value);
    264         } else if (!(entry->attributes() & ReadOnly)) {
    265             entry->propertyPutter()(exec, base, JSValue::encode(slot.thisValue()), JSValue::encode(value));
    266             slot.setCustomProperty(base, entry->propertyPutter());
    267         } else if (slot.isStrictMode())
    268             throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    269     }
    270 
    271     /**
    272      * This one is for "put".
    273      * It looks up a hash entry for the property to be set.  If an entry
    274      * is found it sets the value and returns true, else it returns false.
    275      */
    276     inline bool lookupPut(ExecState* exec, PropertyName propertyName, JSObject* base, JSValue value, const HashTable& table, PutPropertySlot& slot)
    277     {
    278         const HashTableValue* entry = table.entry(propertyName);
    279 
    280         if (!entry)
    281             return false;
    282 
    283         putEntry(exec, entry, base, propertyName, value, slot);
     228
     229    const HashTableValue* entry = table.entry(propertyName);
     230    if (!entry)
     231        return false;
     232
     233    return setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
     234}
     235
     236/**
     237 * Simplified version of getStaticPropertySlot in case there are no functions, only "values".
     238 * Using this instead of getStaticPropertySlot removes the need for a FuncImp class.
     239 */
     240template <class ThisImp, class ParentImp>
     241inline bool getStaticValueSlot(ExecState* exec, const HashTable& table, ThisImp* thisObj, PropertyName propertyName, PropertySlot& slot)
     242{
     243    const HashTableValue* entry = table.entry(propertyName);
     244
     245    if (!entry) // not found, forward to parent
     246        return ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot);
     247
     248    ASSERT(!(entry->attributes() & BuiltinOrFunction));
     249
     250    if (entry->attributes() & ConstantInteger) {
     251        slot.setValue(thisObj, entry->attributes(), jsNumber(entry->constantInteger()));
    284252        return true;
    285253    }
    286254
    287     template<unsigned numberOfValues>
    288     inline void reifyStaticProperties(VM& vm, const HashTableValue (&values)[numberOfValues], JSObject& thisObj)
    289     {
    290         BatchedTransitionOptimizer transitionOptimizer(vm, &thisObj);
    291         for (auto& value : values) {
    292             if (!value.m_key)
    293                 continue;               
    294        
    295             Identifier propertyName(&vm, reinterpret_cast<const LChar*>(value.m_key), strlen(value.m_key));
    296             if (value.attributes() & Builtin) {
    297                 thisObj.putDirectBuiltinFunction(vm, thisObj.globalObject(), propertyName, value.builtinGenerator()(vm), value.attributes());
    298                 continue;
    299             }
    300 
    301             if (value.attributes() & Function) {
    302                 thisObj.putDirectNativeFunction(vm, thisObj.globalObject(), propertyName, value.functionLength(),
    303                     value.function(), value.intrinsic(), value.attributes());
    304                 continue;
    305             }
    306 
    307             if (value.attributes() & ConstantInteger) {
    308                 thisObj.putDirect(vm, propertyName, jsNumber(value.constantInteger()), value.attributes());
    309                 continue;
    310             }
    311 
    312             if (value.attributes() & Accessor) {
    313                 RELEASE_ASSERT_NOT_REACHED();
    314                 continue;
    315             }
    316 
    317             CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, value.propertyGetter(), value.propertyPutter());
    318             thisObj.putDirectCustomAccessor(vm, propertyName, customGetterSetter, value.attributes());
    319         }
    320     }
     255    slot.setCacheableCustom(thisObj, entry->attributes(), entry->propertyGetter());
     256    return true;
     257}
     258
     259inline void putEntry(ExecState* exec, const HashTableValue* entry, JSObject* base, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
     260{
     261    // If this is a function put it as an override property.
     262    if (entry->attributes() & BuiltinOrFunction) {
     263        if (JSObject* thisObject = jsDynamicCast<JSObject*>(slot.thisValue()))
     264            thisObject->putDirect(exec->vm(), propertyName, value);
     265    } else if (!(entry->attributes() & ReadOnly)) {
     266        entry->propertyPutter()(exec, base, JSValue::encode(slot.thisValue()), JSValue::encode(value));
     267        slot.setCustomProperty(base, entry->propertyPutter());
     268    } else if (slot.isStrictMode())
     269        throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
     270}
     271
     272/**
     273 * This one is for "put".
     274 * It looks up a hash entry for the property to be set.  If an entry
     275 * is found it sets the value and returns true, else it returns false.
     276 */
     277inline bool lookupPut(ExecState* exec, PropertyName propertyName, JSObject* base, JSValue value, const HashTable& table, PutPropertySlot& slot)
     278{
     279    const HashTableValue* entry = table.entry(propertyName);
     280
     281    if (!entry)
     282        return false;
     283
     284    putEntry(exec, entry, base, propertyName, value, slot);
     285    return true;
     286}
     287
     288template<unsigned numberOfValues>
     289inline void reifyStaticProperties(VM& vm, const HashTableValue (&values)[numberOfValues], JSObject& thisObj)
     290{
     291    BatchedTransitionOptimizer transitionOptimizer(vm, &thisObj);
     292    for (auto& value : values) {
     293        if (!value.m_key)
     294            continue;               
     295
     296        Identifier propertyName(&vm, reinterpret_cast<const LChar*>(value.m_key), strlen(value.m_key));
     297        if (value.attributes() & Builtin) {
     298            thisObj.putDirectBuiltinFunction(vm, thisObj.globalObject(), propertyName, value.builtinGenerator()(vm), value.attributes());
     299            continue;
     300        }
     301
     302        if (value.attributes() & Function) {
     303            thisObj.putDirectNativeFunction(vm, thisObj.globalObject(), propertyName, value.functionLength(),
     304                value.function(), value.intrinsic(), value.attributes());
     305            continue;
     306        }
     307
     308        if (value.attributes() & ConstantInteger) {
     309            thisObj.putDirect(vm, propertyName, jsNumber(value.constantInteger()), value.attributes());
     310            continue;
     311        }
     312
     313        if (value.attributes() & Accessor) {
     314            RELEASE_ASSERT_NOT_REACHED();
     315            continue;
     316        }
     317
     318        CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, value.propertyGetter(), value.propertyPutter());
     319        thisObj.putDirectCustomAccessor(vm, propertyName, customGetterSetter, value.attributes());
     320    }
     321}
    321322
    322323} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/MathObject.h

    r156679 r173269  
    2626namespace JSC {
    2727
    28     class MathObject : public JSNonFinalObject {
    29     private:
    30         MathObject(VM&, Structure*);
     28class MathObject : public JSNonFinalObject {
     29private:
     30    MathObject(VM&, Structure*);
    3131
    32     public:
    33         typedef JSNonFinalObject Base;
     32public:
     33    typedef JSNonFinalObject Base;
    3434
    35         static MathObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
    36         {
    37             MathObject* object = new (NotNull, allocateCell<MathObject>(vm.heap)) MathObject(vm, structure);
    38             object->finishCreation(vm, globalObject);
    39             return object;
    40         }
     35    static MathObject* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     36    {
     37        MathObject* object = new (NotNull, allocateCell<MathObject>(vm.heap)) MathObject(vm, structure);
     38        object->finishCreation(vm, globalObject);
     39        return object;
     40    }
    4141
    42         DECLARE_INFO;
     42    DECLARE_INFO;
    4343
    44         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    45         {
    46             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    47         }
     44    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     45    {
     46        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     47    }
    4848
    49     protected:
    50         void finishCreation(VM&, JSGlobalObject*);
    51         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
    52     };
     49protected:
     50    void finishCreation(VM&, JSGlobalObject*);
     51    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;
     52};
    5353
    5454} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/NativeErrorConstructor.h

    r171939 r173269  
    2727namespace JSC {
    2828
    29     class ErrorInstance;
    30     class FunctionPrototype;
    31     class NativeErrorPrototype;
     29class ErrorInstance;
     30class FunctionPrototype;
     31class NativeErrorPrototype;
    3232
    33     class NativeErrorConstructor : public InternalFunction {
    34     public:
    35         typedef InternalFunction Base;
     33class NativeErrorConstructor : public InternalFunction {
     34public:
     35    typedef InternalFunction Base;
    3636
    37         static NativeErrorConstructor* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, Structure* prototypeStructure, const String& name)
    38         {
    39             NativeErrorConstructor* constructor = new (NotNull, allocateCell<NativeErrorConstructor>(vm.heap)) NativeErrorConstructor(vm, structure);
    40             constructor->finishCreation(vm, globalObject, prototypeStructure, name);
    41             return constructor;
    42         }
    43        
    44         DECLARE_INFO;
     37    static NativeErrorConstructor* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, Structure* prototypeStructure, const String& name)
     38    {
     39        NativeErrorConstructor* constructor = new (NotNull, allocateCell<NativeErrorConstructor>(vm.heap)) NativeErrorConstructor(vm, structure);
     40        constructor->finishCreation(vm, globalObject, prototypeStructure, name);
     41        return constructor;
     42    }
    4543
    46         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    47         {
    48             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    49         }
     44    DECLARE_INFO;
    5045
    51         Structure* errorStructure() { return m_errorStructure.get(); }
     46    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     47    {
     48        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     49    }
    5250
    53     protected:
    54         void finishCreation(VM&, JSGlobalObject*, Structure* prototypeStructure, const String& name);
     51    Structure* errorStructure() { return m_errorStructure.get(); }
    5552
    56     private:
    57         NativeErrorConstructor(VM&, Structure*);
    58         static ConstructType getConstructData(JSCell*, ConstructData&);
    59         static CallType getCallData(JSCell*, CallData&);
    60         static void visitChildren(JSCell*, SlotVisitor&);
     53protected:
     54    void finishCreation(VM&, JSGlobalObject*, Structure* prototypeStructure, const String& name);
    6155
    62         WriteBarrier<Structure> m_errorStructure;
    63     };
     56private:
     57    NativeErrorConstructor(VM&, Structure*);
     58    static ConstructType getConstructData(JSCell*, ConstructData&);
     59    static CallType getCallData(JSCell*, CallData&);
     60    static void visitChildren(JSCell*, SlotVisitor&);
     61
     62    WriteBarrier<Structure> m_errorStructure;
     63};
    6464
    6565} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/NativeErrorPrototype.h

    r156620 r173269  
    2525
    2626namespace JSC {
    27     class NativeErrorConstructor;
    2827
    29     class NativeErrorPrototype : public ErrorPrototype {
    30     private:
    31         NativeErrorPrototype(VM&, Structure*);
    32    
    33     public:
    34         typedef ErrorPrototype Base;
     28class NativeErrorConstructor;
    3529
    36         static NativeErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, const String& name, NativeErrorConstructor* constructor)
    37         {
    38             NativeErrorPrototype* prototype = new (NotNull, allocateCell<NativeErrorPrototype>(vm.heap)) NativeErrorPrototype(vm, structure);
    39             prototype->finishCreation(vm, globalObject, name, constructor);
    40             return prototype;
    41         }
     30class NativeErrorPrototype : public ErrorPrototype {
     31private:
     32    NativeErrorPrototype(VM&, Structure*);
    4233
    43     protected:
    44         void finishCreation(VM&, JSGlobalObject*, const String& nameAndMessage, NativeErrorConstructor*);
    45     };
     34public:
     35    typedef ErrorPrototype Base;
     36
     37    static NativeErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure, const String& name, NativeErrorConstructor* constructor)
     38    {
     39        NativeErrorPrototype* prototype = new (NotNull, allocateCell<NativeErrorPrototype>(vm.heap)) NativeErrorPrototype(vm, structure);
     40        prototype->finishCreation(vm, globalObject, name, constructor);
     41        return prototype;
     42    }
     43
     44protected:
     45    void finishCreation(VM&, JSGlobalObject*, const String& nameAndMessage, NativeErrorConstructor*);
     46};
    4647
    4748} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/NumberConstructor.h

    r162740 r173269  
    2626namespace JSC {
    2727
    28     class NumberPrototype;
     28class NumberPrototype;
    2929
    30     class NumberConstructor : public InternalFunction {
    31     public:
    32         typedef InternalFunction Base;
     30class NumberConstructor : public InternalFunction {
     31public:
     32    typedef InternalFunction Base;
    3333
    34         static NumberConstructor* create(VM& vm, Structure* structure, NumberPrototype* numberPrototype)
    35         {
    36             NumberConstructor* constructor = new (NotNull, allocateCell<NumberConstructor>(vm.heap)) NumberConstructor(vm, structure);
    37             constructor->finishCreation(vm, numberPrototype);
    38             return constructor;
    39         }
     34    static NumberConstructor* create(VM& vm, Structure* structure, NumberPrototype* numberPrototype)
     35    {
     36        NumberConstructor* constructor = new (NotNull, allocateCell<NumberConstructor>(vm.heap)) NumberConstructor(vm, structure);
     37        constructor->finishCreation(vm, numberPrototype);
     38        return constructor;
     39    }
    4040
    41         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    42         JSValue getValueProperty(ExecState*, int token) const;
     41    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     42    JSValue getValueProperty(ExecState*, int token) const;
    4343
    44         DECLARE_INFO;
     44    DECLARE_INFO;
    4545
    46         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
    47         {
    48             return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
    49         }
     46    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
     47    {
     48        return Structure::create(vm, globalObject, proto, TypeInfo(ObjectType, StructureFlags), info());
     49    }
    5050
    51         enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
     51    enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
    5252
    53     protected:
    54         void finishCreation(VM&, NumberPrototype*);
    55         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;
     53protected:
     54    void finishCreation(VM&, NumberPrototype*);
     55    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;
    5656
    57     private:
    58         NumberConstructor(VM&, Structure*);
    59         static ConstructType getConstructData(JSCell*, ConstructData&);
    60         static CallType getCallData(JSCell*, CallData&);
    61     };
     57private:
     58    NumberConstructor(VM&, Structure*);
     59    static ConstructType getConstructData(JSCell*, ConstructData&);
     60    static CallType getCallData(JSCell*, CallData&);
     61};
    6262
    6363} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/NumberObject.h

    r154038 r173269  
    2626namespace JSC {
    2727
    28     class NumberObject : public JSWrapperObject {
    29     protected:
    30         NumberObject(VM&, Structure*);
    31         void finishCreation(VM&);
     28class NumberObject : public JSWrapperObject {
     29protected:
     30    NumberObject(VM&, Structure*);
     31    void finishCreation(VM&);
    3232
    33     public:
    34         typedef JSWrapperObject Base;
     33public:
     34    typedef JSWrapperObject Base;
    3535
    36         static NumberObject* create(VM& vm, Structure* structure)
    37         {
    38             NumberObject* number = new (NotNull, allocateCell<NumberObject>(vm.heap)) NumberObject(vm, structure);
    39             number->finishCreation(vm);
    40             return number;
    41         }
     36    static NumberObject* create(VM& vm, Structure* structure)
     37    {
     38        NumberObject* number = new (NotNull, allocateCell<NumberObject>(vm.heap)) NumberObject(vm, structure);
     39        number->finishCreation(vm);
     40        return number;
     41    }
    4242
    43         DECLARE_EXPORT_INFO;
     43    DECLARE_EXPORT_INFO;
    4444
    45         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    46         {
    47             return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info());
    48         }
    49     };
     45    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     46    {
     47        return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info());
     48    }
     49};
    5050
    51     JS_EXPORT_PRIVATE NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue);
     51JS_EXPORT_PRIVATE NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue);
    5252
    5353} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/NumberPrototype.h

    r156620 r173269  
    2626namespace JSC {
    2727
    28     class NumberPrototype : public NumberObject {
    29     public:
    30         typedef NumberObject Base;
     28class NumberPrototype : public NumberObject {
     29public:
     30    typedef NumberObject Base;
    3131
    32         static NumberPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
    33         {
    34             NumberPrototype* prototype = new (NotNull, allocateCell<NumberPrototype>(vm.heap)) NumberPrototype(vm, structure);
    35             prototype->finishCreation(vm, globalObject);
    36             return prototype;
    37         }
    38        
    39         DECLARE_INFO;
     32    static NumberPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     33    {
     34        NumberPrototype* prototype = new (NotNull, allocateCell<NumberPrototype>(vm.heap)) NumberPrototype(vm, structure);
     35        prototype->finishCreation(vm, globalObject);
     36        return prototype;
     37    }
    4038
    41         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    42         {
    43             return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info());
    44         }
     39    DECLARE_INFO;
    4540
    46     protected:
    47         void finishCreation(VM&, JSGlobalObject*);
    48         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NumberObject::StructureFlags;
     41    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     42    {
     43        return Structure::create(vm, globalObject, prototype, TypeInfo(NumberObjectType, StructureFlags), info());
     44    }
    4945
    50     private:
    51         NumberPrototype(VM&, Structure*);
    52         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    53     };
     46protected:
     47    void finishCreation(VM&, JSGlobalObject*);
     48    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NumberObject::StructureFlags;
     49
     50private:
     51    NumberPrototype(VM&, Structure*);
     52    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     53};
    5454
    5555} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/NumericStrings.h

    r160344 r173269  
    3333namespace JSC {
    3434
    35     class NumericStrings {
    36     public:
    37         ALWAYS_INLINE String add(double d)
    38         {
    39             CacheEntry<double>& entry = lookup(d);
    40             if (d == entry.key && !entry.value.isNull())
    41                 return entry.value;
    42             entry.key = d;
    43             entry.value = String::numberToStringECMAScript(d);
     35class NumericStrings {
     36public:
     37    ALWAYS_INLINE String add(double d)
     38    {
     39        CacheEntry<double>& entry = lookup(d);
     40        if (d == entry.key && !entry.value.isNull())
    4441            return entry.value;
    45         }
     42        entry.key = d;
     43        entry.value = String::numberToStringECMAScript(d);
     44        return entry.value;
     45    }
    4646
    47         ALWAYS_INLINE String add(int i)
    48         {
    49             if (static_cast<unsigned>(i) < cacheSize)
    50                 return lookupSmallString(static_cast<unsigned>(i));
    51             CacheEntry<int>& entry = lookup(i);
    52             if (i == entry.key && !entry.value.isNull())
    53                 return entry.value;
    54             entry.key = i;
    55             entry.value = String::number(i);
     47    ALWAYS_INLINE String add(int i)
     48    {
     49        if (static_cast<unsigned>(i) < cacheSize)
     50            return lookupSmallString(static_cast<unsigned>(i));
     51        CacheEntry<int>& entry = lookup(i);
     52        if (i == entry.key && !entry.value.isNull())
    5653            return entry.value;
    57         }
     54        entry.key = i;
     55        entry.value = String::number(i);
     56        return entry.value;
     57    }
    5858
    59         ALWAYS_INLINE String add(unsigned i)
    60         {
    61             if (i < cacheSize)
    62                 return lookupSmallString(static_cast<unsigned>(i));
    63             CacheEntry<unsigned>& entry = lookup(i);
    64             if (i == entry.key && !entry.value.isNull())
    65                 return entry.value;
    66             entry.key = i;
    67             entry.value = String::number(i);
     59    ALWAYS_INLINE String add(unsigned i)
     60    {
     61        if (i < cacheSize)
     62            return lookupSmallString(static_cast<unsigned>(i));
     63        CacheEntry<unsigned>& entry = lookup(i);
     64        if (i == entry.key && !entry.value.isNull())
    6865            return entry.value;
    69         }
    70     private:
    71         static const size_t cacheSize = 64;
     66        entry.key = i;
     67        entry.value = String::number(i);
     68        return entry.value;
     69    }
     70private:
     71    static const size_t cacheSize = 64;
    7272
    73         template<typename T>
    74         struct CacheEntry {
    75             T key;
    76             String value;
    77         };
     73    template<typename T>
     74    struct CacheEntry {
     75        T key;
     76        String value;
     77    };
    7878
    79         CacheEntry<double>& lookup(double d) { return doubleCache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
    80         CacheEntry<int>& lookup(int i) { return intCache[WTF::IntHash<int>::hash(i) & (cacheSize - 1)]; }
    81         CacheEntry<unsigned>& lookup(unsigned i) { return unsignedCache[WTF::IntHash<unsigned>::hash(i) & (cacheSize - 1)]; }
    82         ALWAYS_INLINE const String& lookupSmallString(unsigned i)
    83         {
    84             ASSERT(i < cacheSize);
    85             if (smallIntCache[i].isNull())
    86                 smallIntCache[i] = String::number(i);
    87             return smallIntCache[i];
    88         }
     79    CacheEntry<double>& lookup(double d) { return doubleCache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
     80    CacheEntry<int>& lookup(int i) { return intCache[WTF::IntHash<int>::hash(i) & (cacheSize - 1)]; }
     81    CacheEntry<unsigned>& lookup(unsigned i) { return unsignedCache[WTF::IntHash<unsigned>::hash(i) & (cacheSize - 1)]; }
     82    ALWAYS_INLINE const String& lookupSmallString(unsigned i)
     83    {
     84        ASSERT(i < cacheSize);
     85        if (smallIntCache[i].isNull())
     86            smallIntCache[i] = String::number(i);
     87        return smallIntCache[i];
     88    }
    8989
    90         std::array<CacheEntry<double>, cacheSize> doubleCache;
    91         std::array<CacheEntry<int>, cacheSize> intCache;
    92         std::array<CacheEntry<unsigned>, cacheSize> unsignedCache;
    93         std::array<String, cacheSize> smallIntCache;
    94     };
     90    std::array<CacheEntry<double>, cacheSize> doubleCache;
     91    std::array<CacheEntry<int>, cacheSize> intCache;
     92    std::array<CacheEntry<unsigned>, cacheSize> unsignedCache;
     93    std::array<String, cacheSize> smallIntCache;
     94};
    9595
    9696} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h

    r156624 r173269  
    2828namespace JSC {
    2929
    30     class ObjectPrototype;
     30class ObjectPrototype;
    3131
    32     class ObjectConstructor : public InternalFunction {
    33     public:
    34         typedef InternalFunction Base;
     32class ObjectConstructor : public InternalFunction {
     33public:
     34    typedef InternalFunction Base;
    3535
    36         static ObjectConstructor* create(VM& vm, Structure* structure, ObjectPrototype* objectPrototype)
    37         {
    38             ObjectConstructor* constructor = new (NotNull, allocateCell<ObjectConstructor>(vm.heap)) ObjectConstructor(vm, structure);
    39             constructor->finishCreation(vm, objectPrototype);
    40             return constructor;
    41         }
    42 
    43         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    44 
    45         DECLARE_INFO;
    46 
    47         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    48         {
    49             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    50         }
    51 
    52     protected:
    53         void finishCreation(VM& vm, ObjectPrototype*);
    54         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
    55 
    56     private:
    57         ObjectConstructor(VM&, Structure*);
    58         static ConstructType getConstructData(JSCell*, ConstructData&);
    59         static CallType getCallData(JSCell*, CallData&);
    60     };
    61 
    62     inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
     36    static ObjectConstructor* create(VM& vm, Structure* structure, ObjectPrototype* objectPrototype)
    6337    {
    64         return JSFinalObject::create(exec, structure);
     38        ObjectConstructor* constructor = new (NotNull, allocateCell<ObjectConstructor>(vm.heap)) ObjectConstructor(vm, structure);
     39        constructor->finishCreation(vm, objectPrototype);
     40        return constructor;
    6541    }
    6642
    67     inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype, unsigned inlineCapacity)
     43    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     44
     45    DECLARE_INFO;
     46
     47    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    6848    {
    69         JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    70         PrototypeMap& prototypeMap = globalObject->vm().prototypeMap;
    71         Structure* structure = prototypeMap.emptyObjectStructureForPrototype(
    72             prototype, inlineCapacity);
    73         return constructEmptyObject(exec, structure);
     49        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    7450    }
    7551
    76     inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype)
    77     {
    78         return constructEmptyObject(exec, prototype, JSFinalObject::defaultInlineCapacity());
    79     }
     52protected:
     53    void finishCreation(VM&, ObjectPrototype*);
     54    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
    8055
    81     inline JSObject* constructEmptyObject(ExecState* exec)
    82     {
    83         return constructEmptyObject(exec, exec->lexicalGlobalObject()->objectPrototype());
    84     }
     56private:
     57    ObjectConstructor(VM&, Structure*);
     58    static ConstructType getConstructData(JSCell*, ConstructData&);
     59    static CallType getCallData(JSCell*, CallData&);
     60};
     61
     62inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
     63{
     64    return JSFinalObject::create(exec, structure);
     65}
     66
     67inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype, unsigned inlineCapacity)
     68{
     69    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     70    PrototypeMap& prototypeMap = globalObject->vm().prototypeMap;
     71    Structure* structure = prototypeMap.emptyObjectStructureForPrototype(
     72        prototype, inlineCapacity);
     73    return constructEmptyObject(exec, structure);
     74}
     75
     76inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype)
     77{
     78    return constructEmptyObject(exec, prototype, JSFinalObject::defaultInlineCapacity());
     79}
     80
     81inline JSObject* constructEmptyObject(ExecState* exec)
     82{
     83    return constructEmptyObject(exec, exec->lexicalGlobalObject()->objectPrototype());
     84}
    8585
    8686} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/ObjectPrototype.h

    r156680 r173269  
    2626namespace JSC {
    2727
    28     class ObjectPrototype : public JSNonFinalObject {
    29     public:
    30         typedef JSNonFinalObject Base;
     28class ObjectPrototype : public JSNonFinalObject {
     29public:
     30    typedef JSNonFinalObject Base;
    3131
    32         static ObjectPrototype* create(VM&, JSGlobalObject*, Structure*);
     32    static ObjectPrototype* create(VM&, JSGlobalObject*, Structure*);
    3333
    34         DECLARE_INFO;
     34    DECLARE_INFO;
    3535
    36         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    37         {
    38             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    39         }
     36    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     37    {
     38        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     39    }
    4040
    41     protected:
    42         void finishCreation(VM&, JSGlobalObject*);
     41protected:
     42    void finishCreation(VM&, JSGlobalObject*);
    4343
    44     private:
    45         ObjectPrototype(VM&, Structure*);
    46     };
     44private:
     45    ObjectPrototype(VM&, Structure*);
     46};
    4747
    48     JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*);
     48JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*);
    4949
    5050} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/PropertyDescriptor.h

    r169703 r173269  
    3030
    3131namespace JSC {
    32     class GetterSetter;
    3332
    34     // See ES5.1 9.12
    35     bool sameValue(ExecState*, JSValue, JSValue);
     33class GetterSetter;
    3634
    37     class PropertyDescriptor {
    38     public:
    39         PropertyDescriptor()
    40             : m_attributes(defaultAttributes)
    41             , m_seenAttributes(0)
    42         {
    43         }
    44         PropertyDescriptor(JSValue value, unsigned attributes)
    45             : m_value(value)
    46             , m_attributes(attributes)
    47             , m_seenAttributes(EnumerablePresent | ConfigurablePresent | WritablePresent)
    48         {
    49             ASSERT(m_value);
    50             ASSERT(!m_value.isGetterSetter());
    51             ASSERT(!m_value.isCustomGetterSetter());
    52         }
    53         JS_EXPORT_PRIVATE bool writable() const;
    54         JS_EXPORT_PRIVATE bool enumerable() const;
    55         JS_EXPORT_PRIVATE bool configurable() const;
    56         JS_EXPORT_PRIVATE bool isDataDescriptor() const;
    57         bool isGenericDescriptor() const;
    58         JS_EXPORT_PRIVATE bool isAccessorDescriptor() const;
    59         unsigned attributes() const { return m_attributes; }
    60         JSValue value() const { return m_value; }
    61         JS_EXPORT_PRIVATE JSValue getter() const;
    62         JS_EXPORT_PRIVATE JSValue setter() const;
    63         JSObject* getterObject() const;
    64         JSObject* setterObject() const;
    65         JS_EXPORT_PRIVATE void setUndefined();
    66         JS_EXPORT_PRIVATE void setDescriptor(JSValue value, unsigned attributes);
    67         JS_EXPORT_PRIVATE void setCustomDescriptor(unsigned attributes);
    68         JS_EXPORT_PRIVATE void setAccessorDescriptor(GetterSetter* accessor, unsigned attributes);
    69         JS_EXPORT_PRIVATE void setWritable(bool);
    70         JS_EXPORT_PRIVATE void setEnumerable(bool);
    71         JS_EXPORT_PRIVATE void setConfigurable(bool);
    72         void setValue(JSValue value) { m_value = value; }
    73         JS_EXPORT_PRIVATE void setSetter(JSValue);
    74         JS_EXPORT_PRIVATE void setGetter(JSValue);
    75         bool isEmpty() const { return !(m_value || m_getter || m_setter || m_seenAttributes); }
    76         bool writablePresent() const { return m_seenAttributes & WritablePresent; }
    77         bool enumerablePresent() const { return m_seenAttributes & EnumerablePresent; }
    78         bool configurablePresent() const { return m_seenAttributes & ConfigurablePresent; }
    79         bool setterPresent() const { return m_setter; }
    80         bool getterPresent() const { return m_getter; }
    81         bool equalTo(ExecState* exec, const PropertyDescriptor& other) const;
    82         bool attributesEqual(const PropertyDescriptor& other) const;
    83         unsigned attributesOverridingCurrent(const PropertyDescriptor& current) const;
     35// See ES5.1 9.12
     36bool sameValue(ExecState*, JSValue, JSValue);
    8437
    85     private:
    86         JS_EXPORTDATA static unsigned defaultAttributes;
    87         bool operator==(const PropertyDescriptor&){ return false; }
    88         enum { WritablePresent = 1, EnumerablePresent = 2, ConfigurablePresent = 4};
    89         // May be a getter/setter
    90         JSValue m_value;
    91         JSValue m_getter;
    92         JSValue m_setter;
    93         unsigned m_attributes;
    94         unsigned m_seenAttributes;
    95     };
     38class PropertyDescriptor {
     39public:
     40    PropertyDescriptor()
     41        : m_attributes(defaultAttributes)
     42        , m_seenAttributes(0)
     43    {
     44    }
     45    PropertyDescriptor(JSValue value, unsigned attributes)
     46        : m_value(value)
     47        , m_attributes(attributes)
     48        , m_seenAttributes(EnumerablePresent | ConfigurablePresent | WritablePresent)
     49    {
     50        ASSERT(m_value);
     51        ASSERT(!m_value.isGetterSetter());
     52        ASSERT(!m_value.isCustomGetterSetter());
     53    }
     54    JS_EXPORT_PRIVATE bool writable() const;
     55    JS_EXPORT_PRIVATE bool enumerable() const;
     56    JS_EXPORT_PRIVATE bool configurable() const;
     57    JS_EXPORT_PRIVATE bool isDataDescriptor() const;
     58    bool isGenericDescriptor() const;
     59    JS_EXPORT_PRIVATE bool isAccessorDescriptor() const;
     60    unsigned attributes() const { return m_attributes; }
     61    JSValue value() const { return m_value; }
     62    JS_EXPORT_PRIVATE JSValue getter() const;
     63    JS_EXPORT_PRIVATE JSValue setter() const;
     64    JSObject* getterObject() const;
     65    JSObject* setterObject() const;
     66    JS_EXPORT_PRIVATE void setUndefined();
     67    JS_EXPORT_PRIVATE void setDescriptor(JSValue, unsigned attributes);
     68    JS_EXPORT_PRIVATE void setCustomDescriptor(unsigned attributes);
     69    JS_EXPORT_PRIVATE void setAccessorDescriptor(GetterSetter* accessor, unsigned attributes);
     70    JS_EXPORT_PRIVATE void setWritable(bool);
     71    JS_EXPORT_PRIVATE void setEnumerable(bool);
     72    JS_EXPORT_PRIVATE void setConfigurable(bool);
     73    void setValue(JSValue value) { m_value = value; }
     74    JS_EXPORT_PRIVATE void setSetter(JSValue);
     75    JS_EXPORT_PRIVATE void setGetter(JSValue);
     76    bool isEmpty() const { return !(m_value || m_getter || m_setter || m_seenAttributes); }
     77    bool writablePresent() const { return m_seenAttributes & WritablePresent; }
     78    bool enumerablePresent() const { return m_seenAttributes & EnumerablePresent; }
     79    bool configurablePresent() const { return m_seenAttributes & ConfigurablePresent; }
     80    bool setterPresent() const { return m_setter; }
     81    bool getterPresent() const { return m_getter; }
     82    bool equalTo(ExecState*, const PropertyDescriptor& other) const;
     83    bool attributesEqual(const PropertyDescriptor& other) const;
     84    unsigned attributesOverridingCurrent(const PropertyDescriptor& current) const;
     85
     86private:
     87    JS_EXPORTDATA static unsigned defaultAttributes;
     88    bool operator==(const PropertyDescriptor&) { return false; }
     89    enum { WritablePresent = 1, EnumerablePresent = 2, ConfigurablePresent = 4};
     90    // May be a getter/setter
     91    JSValue m_value;
     92    JSValue m_getter;
     93    JSValue m_setter;
     94    unsigned m_attributes;
     95    unsigned m_seenAttributes;
     96};
     97
    9698}
    9799
  • trunk/Source/JavaScriptCore/runtime/Protect.h

    r140718 r173269  
    2828namespace JSC {
    2929
    30     inline void gcProtect(JSCell* val)
    31     {
    32         Heap::heap(val)->protect(val);
    33     }
     30inline void gcProtect(JSCell* val)
     31{
     32    Heap::heap(val)->protect(val);
     33}
    3434
    35     inline void gcUnprotect(JSCell* val)
    36     {
    37         Heap::heap(val)->unprotect(val);
    38     }
     35inline void gcUnprotect(JSCell* val)
     36{
     37    Heap::heap(val)->unprotect(val);
     38}
    3939
    40     inline void gcProtectNullTolerant(JSCell* val)
    41     {
    42         if (val)
    43             gcProtect(val);
    44     }
     40inline void gcProtectNullTolerant(JSCell* val)
     41{
     42    if (val)
     43        gcProtect(val);
     44}
    4545
    46     inline void gcUnprotectNullTolerant(JSCell* val)
    47     {
    48         if (val)
    49             gcUnprotect(val);
    50     }
    51    
    52     inline void gcProtect(JSValue value)
    53     {
    54         if (value && value.isCell())
    55             gcProtect(value.asCell());
    56     }
     46inline void gcUnprotectNullTolerant(JSCell* val)
     47{
     48    if (val)
     49        gcUnprotect(val);
     50}
    5751
    58     inline void gcUnprotect(JSValue value)
    59     {
    60         if (value && value.isCell())
    61             gcUnprotect(value.asCell());
    62     }
     52inline void gcProtect(JSValue value)
     53{
     54    if (value && value.isCell())
     55        gcProtect(value.asCell());
     56}
     57
     58inline void gcUnprotect(JSValue value)
     59{
     60    if (value && value.isCell())
     61        gcUnprotect(value.asCell());
     62}
    6363
    6464} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h

    r173100 r173269  
    3434namespace JSC {
    3535   
    36     class JSObject;
    37     class JSFunction;
     36class JSObject;
     37class JSFunction;
    3838   
    39     class PutPropertySlot {
    40     public:
    41         enum Type { Uncachable, ExistingProperty, NewProperty, SetterProperty, CustomProperty };
    42         enum Context { UnknownContext, PutById, PutByIdEval };
    43         typedef void (*PutValueFunc)(ExecState*, JSObject* base, EncodedJSValue thisObject, EncodedJSValue value);
     39class PutPropertySlot {
     40public:
     41    enum Type { Uncachable, ExistingProperty, NewProperty, SetterProperty, CustomProperty };
     42    enum Context { UnknownContext, PutById, PutByIdEval };
     43    typedef void (*PutValueFunc)(ExecState*, JSObject* base, EncodedJSValue thisObject, EncodedJSValue value);
    4444
    45         PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext)
    46             : m_type(Uncachable)
    47             , m_base(0)
    48             , m_thisValue(thisValue)
    49             , m_isStrictMode(isStrictMode)
    50             , m_context(context)
    51             , m_putFunction(nullptr)
    52         {
    53         }
     45    PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext)
     46        : m_type(Uncachable)
     47        , m_base(0)
     48        , m_thisValue(thisValue)
     49        , m_isStrictMode(isStrictMode)
     50        , m_context(context)
     51        , m_putFunction(nullptr)
     52    {
     53    }
    5454
    55         void setExistingProperty(JSObject* base, PropertyOffset offset)
    56         {
    57             m_type = ExistingProperty;
    58             m_base = base;
    59             m_offset = offset;
    60         }
     55    void setExistingProperty(JSObject* base, PropertyOffset offset)
     56    {
     57        m_type = ExistingProperty;
     58        m_base = base;
     59        m_offset = offset;
     60    }
    6161
    62         void setNewProperty(JSObject* base, PropertyOffset offset)
    63         {
    64             m_type = NewProperty;
    65             m_base = base;
    66             m_offset = offset;
    67         }
     62    void setNewProperty(JSObject* base, PropertyOffset offset)
     63    {
     64        m_type = NewProperty;
     65        m_base = base;
     66        m_offset = offset;
     67    }
    6868
    69         void setCustomProperty(JSObject* base, PutValueFunc function)
    70         {
    71             m_type = CustomProperty;
    72             m_base = base;
    73             m_putFunction = function;
    74         }
    75        
    76         void setCacheableSetter(JSObject* base, PropertyOffset offset)
    77         {
    78             m_type = SetterProperty;
    79             m_base = base;
    80             m_offset = offset;
    81         }
     69    void setCustomProperty(JSObject* base, PutValueFunc function)
     70    {
     71        m_type = CustomProperty;
     72        m_base = base;
     73        m_putFunction = function;
     74    }
    8275
    83         void setThisValue(JSValue thisValue)
    84         {
    85             m_thisValue = thisValue;
    86         }
     76    void setCacheableSetter(JSObject* base, PropertyOffset offset)
     77    {
     78        m_type = SetterProperty;
     79        m_base = base;
     80        m_offset = offset;
     81    }
    8782
    88         PutValueFunc customSetter() const { return m_putFunction; }
     83    void setThisValue(JSValue thisValue)
     84    {
     85        m_thisValue = thisValue;
     86    }
    8987
    90         Context context() const { return static_cast<Context>(m_context); }
     88    PutValueFunc customSetter() const { return m_putFunction; }
    9189
    92         Type type() const { return m_type; }
    93         JSObject* base() const { return m_base; }
    94         JSValue thisValue() const { return m_thisValue; }
     90    Context context() const { return static_cast<Context>(m_context); }
    9591
    96         bool isStrictMode() const { return m_isStrictMode; }
    97         bool isCacheablePut() const { return m_type == NewProperty || m_type == ExistingProperty; }
    98         bool isCacheableSetter() const { return m_type == SetterProperty; }
    99         bool isCacheableCustom() const { return m_type == CustomProperty; }
     92    Type type() const { return m_type; }
     93    JSObject* base() const { return m_base; }
     94    JSValue thisValue() const { return m_thisValue; }
    10095
    101         PropertyOffset cachedOffset() const
    102         {
    103             return m_offset;
    104         }
     96    bool isStrictMode() const { return m_isStrictMode; }
     97    bool isCacheablePut() const { return m_type == NewProperty || m_type == ExistingProperty; }
     98    bool isCacheableSetter() const { return m_type == SetterProperty; }
     99    bool isCacheableCustom() const { return m_type == CustomProperty; }
    105100
    106     private:
    107         Type m_type;
    108         JSObject* m_base;
    109         JSValue m_thisValue;
    110         PropertyOffset m_offset;
    111         bool m_isStrictMode;
    112         uint8_t m_context;
    113         PutValueFunc m_putFunction;
     101    PropertyOffset cachedOffset() const
     102    {
     103        return m_offset;
     104    }
    114105
    115     };
     106private:
     107    Type m_type;
     108    JSObject* m_base;
     109    JSValue m_thisValue;
     110    PropertyOffset m_offset;
     111    bool m_isStrictMode;
     112    uint8_t m_context;
     113    PutValueFunc m_putFunction;
     114};
    116115
    117116} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/RegExp.h

    r171660 r173269  
    3838namespace JSC {
    3939
    40     struct RegExpRepresentation;
    41     class VM;
     40struct RegExpRepresentation;
     41class VM;
    4242
    43     JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);
     43JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);
    4444
    45     class RegExp : public JSCell {
    46     public:
    47         typedef JSCell Base;
     45class RegExp : public JSCell {
     46public:
     47    typedef JSCell Base;
    4848
    49         JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags);
    50         static const bool needsDestruction = true;
    51         static const bool hasImmortalStructure = true;
    52         static void destroy(JSCell*);
     49    JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags);
     50    static const bool needsDestruction = true;
     51    static const bool hasImmortalStructure = true;
     52    static void destroy(JSCell*);
    5353
    54         bool global() const { return m_flags & FlagGlobal; }
    55         bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
    56         bool multiline() const { return m_flags & FlagMultiline; }
     54    bool global() const { return m_flags & FlagGlobal; }
     55    bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
     56    bool multiline() const { return m_flags & FlagMultiline; }
    5757
    58         const String& pattern() const { return m_patternString; }
     58    const String& pattern() const { return m_patternString; }
    5959
    60         bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
    61         const char* errorMessage() const { return m_constructionError; }
     60    bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; }
     61    const char* errorMessage() const { return m_constructionError; }
    6262
    63         JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int, 32>& ovector);
    64         JS_EXPORT_PRIVATE MatchResult match(VM&, const String&, unsigned startOffset);
    65         unsigned numSubpatterns() const { return m_numSubpatterns; }
     63    JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int, 32>& ovector);
     64    JS_EXPORT_PRIVATE MatchResult match(VM&, const String&, unsigned startOffset);
     65    unsigned numSubpatterns() const { return m_numSubpatterns; }
    6666
    67         bool hasCode()
    68         {
    69             return m_state != NotCompiled;
    70         }
     67    bool hasCode()
     68    {
     69        return m_state != NotCompiled;
     70    }
    7171
    72         void invalidateCode();
    73        
     72    void invalidateCode();
     73
    7474#if ENABLE(REGEXP_TRACING)
    75         void printTraceData();
     75    void printTraceData();
    7676#endif
    7777
    78         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    79         {
    80             return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
    81         }
    82        
    83         DECLARE_INFO;
     78    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     79    {
     80        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     81    }
    8482
    85         RegExpKey key() { return RegExpKey(m_flags, m_patternString); }
     83    DECLARE_INFO;
    8684
    87     protected:
    88         static const unsigned StructureFlags = StructureIsImmortal;
     85    RegExpKey key() { return RegExpKey(m_flags, m_patternString); }
    8986
    90         void finishCreation(VM&);
     87protected:
     88    static const unsigned StructureFlags = StructureIsImmortal;
    9189
    92     private:
    93         friend class RegExpCache;
    94         RegExp(VM&, const String&, RegExpFlags);
     90    void finishCreation(VM&);
    9591
    96         static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags);
     92private:
     93    friend class RegExpCache;
     94    RegExp(VM&, const String&, RegExpFlags);
    9795
    98         enum RegExpState {
    99             ParseError,
    100             JITCode,
    101             ByteCode,
    102             NotCompiled
    103         } m_state;
     96    static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags);
    10497
    105         void compile(VM*, Yarr::YarrCharSize);
    106         void compileIfNecessary(VM&, Yarr::YarrCharSize);
     98    enum RegExpState {
     99        ParseError,
     100        JITCode,
     101        ByteCode,
     102        NotCompiled
     103    };
    107104
    108         void compileMatchOnly(VM*, Yarr::YarrCharSize);
    109         void compileIfNecessaryMatchOnly(VM&, Yarr::YarrCharSize);
     105    RegExpState m_state;
     106
     107    void compile(VM*, Yarr::YarrCharSize);
     108    void compileIfNecessary(VM&, Yarr::YarrCharSize);
     109
     110    void compileMatchOnly(VM*, Yarr::YarrCharSize);
     111    void compileIfNecessaryMatchOnly(VM&, Yarr::YarrCharSize);
    110112
    111113#if ENABLE(YARR_JIT_DEBUG)
    112         void matchCompareWithInterpreter(const String&, int startOffset, int* offsetVector, int jitResult);
     114    void matchCompareWithInterpreter(const String&, int startOffset, int* offsetVector, int jitResult);
    113115#endif
    114116
    115         String m_patternString;
    116         RegExpFlags m_flags;
    117         const char* m_constructionError;
    118         unsigned m_numSubpatterns;
     117    String m_patternString;
     118    RegExpFlags m_flags;
     119    const char* m_constructionError;
     120    unsigned m_numSubpatterns;
    119121#if ENABLE(REGEXP_TRACING)
    120         double m_rtMatchOnlyTotalSubjectStringLen;
    121         double m_rtMatchTotalSubjectStringLen;
    122         unsigned m_rtMatchOnlyCallCount;
    123         unsigned m_rtMatchOnlyFoundCount;
    124         unsigned m_rtMatchCallCount;
    125         unsigned m_rtMatchFoundCount;
     122    double m_rtMatchOnlyTotalSubjectStringLen;
     123    double m_rtMatchTotalSubjectStringLen;
     124    unsigned m_rtMatchOnlyCallCount;
     125    unsigned m_rtMatchOnlyFoundCount;
     126    unsigned m_rtMatchCallCount;
     127    unsigned m_rtMatchFoundCount;
    126128#endif
    127129
    128130#if ENABLE(YARR_JIT)
    129         Yarr::YarrCodeBlock m_regExpJITCode;
     131    Yarr::YarrCodeBlock m_regExpJITCode;
    130132#endif
    131         OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
    132     };
     133    OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
     134};
    133135
    134136} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/RegExpCachedResult.h

    r148696 r173269  
    3131namespace JSC {
    3232
    33     class JSString;
    34     class RegExpMatchesArray;
     33class JSString;
     34class RegExpMatchesArray;
    3535
    36     // RegExpCachedResult is used to track the cached results of the last
    37     // match, stores on the RegExp constructor (e.g. $&, $_, $1, $2 ...).
    38     // These values will be lazily generated on demand, so the cached result
    39     // may be in a lazy or reified state. A lazy state is indicated by a
    40     // value of m_result indicating a successful match, and a reified state
    41     // is indicated by setting m_result to MatchResult::failed().
    42     // Following a successful match, m_result, m_lastInput and m_lastRegExp
    43     // can be used to reify the results from the match, following reification
    44     // m_reifiedResult and m_reifiedInput hold the cached results.
    45     class RegExpCachedResult {
    46     public:
    47         RegExpCachedResult(VM& vm, JSObject* owner, RegExp* emptyRegExp)
    48             : m_result(0, 0)
    49         {
    50             m_lastInput.set(vm, owner, jsEmptyString(&vm));
    51             m_lastRegExp.set(vm, owner, emptyRegExp);
    52         }
     36// RegExpCachedResult is used to track the cached results of the last
     37// match, stores on the RegExp constructor (e.g. $&, $_, $1, $2 ...).
     38// These values will be lazily generated on demand, so the cached result
     39// may be in a lazy or reified state. A lazy state is indicated by a
     40// value of m_result indicating a successful match, and a reified state
     41// is indicated by setting m_result to MatchResult::failed().
     42// Following a successful match, m_result, m_lastInput and m_lastRegExp
     43// can be used to reify the results from the match, following reification
     44// m_reifiedResult and m_reifiedInput hold the cached results.
     45class RegExpCachedResult {
     46public:
     47    RegExpCachedResult(VM& vm, JSObject* owner, RegExp* emptyRegExp)
     48        : m_result(0, 0)
     49    {
     50        m_lastInput.set(vm, owner, jsEmptyString(&vm));
     51        m_lastRegExp.set(vm, owner, emptyRegExp);
     52    }
    5353
    54         ALWAYS_INLINE void record(VM& vm, JSObject* owner, RegExp* regExp, JSString* input, MatchResult result)
    55         {
    56             m_lastRegExp.set(vm, owner, regExp);
    57             m_lastInput.set(vm, owner, input);
    58             m_result = result;
    59         }
     54    ALWAYS_INLINE void record(VM& vm, JSObject* owner, RegExp* regExp, JSString* input, MatchResult result)
     55    {
     56        m_lastRegExp.set(vm, owner, regExp);
     57        m_lastInput.set(vm, owner, input);
     58        m_result = result;
     59    }
    6060
    61         RegExpMatchesArray* lastResult(ExecState*, JSObject* owner);
    62         void setInput(ExecState*, JSObject* owner, JSString*);
     61    RegExpMatchesArray* lastResult(ExecState*, JSObject* owner);
     62    void setInput(ExecState*, JSObject* owner, JSString*);
    6363
    64         JSString* input()
    65         {
    66             // If m_result showas a match then we're in a lazy state, so m_lastInput
    67             // is the most recent value of the input property. If not then we have
    68             // reified, in which case m_reifiedInput will contain the correct value.
    69             return m_result ? m_lastInput.get() : m_reifiedInput.get();
    70         }
     64    JSString* input()
     65    {
     66        // If m_result showas a match then we're in a lazy state, so m_lastInput
     67        // is the most recent value of the input property. If not then we have
     68        // reified, in which case m_reifiedInput will contain the correct value.
     69        return m_result ? m_lastInput.get() : m_reifiedInput.get();
     70    }
    7171
    72         void visitChildren(SlotVisitor&);
     72    void visitChildren(SlotVisitor&);
    7373
    74     private:
    75         MatchResult m_result;
    76         WriteBarrier<JSString> m_lastInput;
    77         WriteBarrier<RegExp> m_lastRegExp;
    78         WriteBarrier<RegExpMatchesArray> m_reifiedResult;
    79         WriteBarrier<JSString> m_reifiedInput;
    80     };
     74private:
     75    MatchResult m_result;
     76    WriteBarrier<JSString> m_lastInput;
     77    WriteBarrier<RegExp> m_lastRegExp;
     78    WriteBarrier<RegExpMatchesArray> m_reifiedResult;
     79    WriteBarrier<JSString> m_reifiedInput;
     80};
    8181
    8282} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/RegExpConstructor.h

    r171939 r173269  
    3131namespace JSC {
    3232
    33     class RegExpPrototype;
     33class RegExpPrototype;
    3434
    35     class RegExpConstructor : public InternalFunction {
    36     public:
    37         typedef InternalFunction Base;
     35class RegExpConstructor : public InternalFunction {
     36public:
     37    typedef InternalFunction Base;
    3838
    39         static RegExpConstructor* create(VM& vm, Structure* structure, RegExpPrototype* regExpPrototype)
    40         {
    41             RegExpConstructor* constructor = new (NotNull, allocateCell<RegExpConstructor>(vm.heap)) RegExpConstructor(vm, structure, regExpPrototype);
    42             constructor->finishCreation(vm, regExpPrototype);
    43             return constructor;
    44         }
    45 
    46         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    47         {
    48             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    49         }
    50 
    51         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    52 
    53         DECLARE_INFO;
    54 
    55         MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset, int** ovector);
    56         MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset);
    57 
    58         void setMultiline(bool multiline) { m_multiline = multiline; }
    59         bool multiline() const { return m_multiline; }
    60 
    61         JSValue getBackref(ExecState*, unsigned);
    62         JSValue getLastParen(ExecState*);
    63         JSValue getLeftContext(ExecState*);
    64         JSValue getRightContext(ExecState*);
    65 
    66         void setInput(ExecState* exec, JSString* string) { m_cachedResult.setInput(exec, this, string); }
    67         JSString* input() { return m_cachedResult.input(); }
    68 
    69         static void visitChildren(JSCell*, SlotVisitor&);
    70 
    71     protected:
    72         void finishCreation(VM&, RegExpPrototype*);
    73         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
    74 
    75     private:
    76         RegExpConstructor(VM&, Structure*, RegExpPrototype*);
    77         static void destroy(JSCell*);
    78         static ConstructType getConstructData(JSCell*, ConstructData&);
    79         static CallType getCallData(JSCell*, CallData&);
    80 
    81         RegExpCachedResult m_cachedResult;
    82         bool m_multiline;
    83         Vector<int, 32> m_ovector;
    84     };
    85 
    86     RegExpConstructor* asRegExpConstructor(JSValue);
    87 
    88     JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&, bool callAsConstructor = false);
    89 
    90     inline RegExpConstructor* asRegExpConstructor(JSValue value)
     39    static RegExpConstructor* create(VM& vm, Structure* structure, RegExpPrototype* regExpPrototype)
    9140    {
    92         ASSERT(asObject(value)->inherits(RegExpConstructor::info()));
    93         return static_cast<RegExpConstructor*>(asObject(value));
     41        RegExpConstructor* constructor = new (NotNull, allocateCell<RegExpConstructor>(vm.heap)) RegExpConstructor(vm, structure, regExpPrototype);
     42        constructor->finishCreation(vm, regExpPrototype);
     43        return constructor;
    9444    }
    9545
    96     /*
    97       To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
    98       expression matching through the performMatch function. We use cached results to calculate,
    99       e.g., RegExp.lastMatch and RegExp.leftParen.
    100     */
    101     ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
     46    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    10247    {
    103         int position = regExp->match(vm, input, startOffset, m_ovector);
     48        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     49    }
    10450
    105         if (ovector)
    106             *ovector = m_ovector.data();
     51    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    10752
    108         if (position == -1)
    109             return MatchResult::failed();
     53    DECLARE_INFO;
    11054
    111         ASSERT(!m_ovector.isEmpty());
    112         ASSERT(m_ovector[0] == position);
    113         ASSERT(m_ovector[1] >= position);
    114         size_t end = m_ovector[1];
     55    MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset, int** ovector);
     56    MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset);
    11557
    116         m_cachedResult.record(vm, this, regExp, string, MatchResult(position, end));
     58    void setMultiline(bool multiline) { m_multiline = multiline; }
     59    bool multiline() const { return m_multiline; }
    11760
    118         return MatchResult(position, end);
    119     }
    120     ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset)
    121     {
    122         MatchResult result = regExp->match(vm, input, startOffset);
    123         if (result)
    124             m_cachedResult.record(vm, this, regExp, string, result);
    125         return result;
    126     }
     61    JSValue getBackref(ExecState*, unsigned);
     62    JSValue getLastParen(ExecState*);
     63    JSValue getLeftContext(ExecState*);
     64    JSValue getRightContext(ExecState*);
     65
     66    void setInput(ExecState* exec, JSString* string) { m_cachedResult.setInput(exec, this, string); }
     67    JSString* input() { return m_cachedResult.input(); }
     68
     69    static void visitChildren(JSCell*, SlotVisitor&);
     70
     71protected:
     72    void finishCreation(VM&, RegExpPrototype*);
     73    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
     74
     75private:
     76    RegExpConstructor(VM&, Structure*, RegExpPrototype*);
     77    static void destroy(JSCell*);
     78    static ConstructType getConstructData(JSCell*, ConstructData&);
     79    static CallType getCallData(JSCell*, CallData&);
     80
     81    RegExpCachedResult m_cachedResult;
     82    bool m_multiline;
     83    Vector<int, 32> m_ovector;
     84};
     85
     86RegExpConstructor* asRegExpConstructor(JSValue);
     87
     88JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&, bool callAsConstructor = false);
     89
     90inline RegExpConstructor* asRegExpConstructor(JSValue value)
     91{
     92    ASSERT(asObject(value)->inherits(RegExpConstructor::info()));
     93    return static_cast<RegExpConstructor*>(asObject(value));
     94}
     95
     96/*
     97   To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
     98   expression matching through the performMatch function. We use cached results to calculate,
     99   e.g., RegExp.lastMatch and RegExp.leftParen.
     100*/
     101ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
     102{
     103    int position = regExp->match(vm, input, startOffset, m_ovector);
     104
     105    if (ovector)
     106        *ovector = m_ovector.data();
     107
     108    if (position == -1)
     109        return MatchResult::failed();
     110
     111    ASSERT(!m_ovector.isEmpty());
     112    ASSERT(m_ovector[0] == position);
     113    ASSERT(m_ovector[1] >= position);
     114    size_t end = m_ovector[1];
     115
     116    m_cachedResult.record(vm, this, regExp, string, MatchResult(position, end));
     117
     118    return MatchResult(position, end);
     119}
     120ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset)
     121{
     122    MatchResult result = regExp->match(vm, input, startOffset);
     123    if (result)
     124        m_cachedResult.record(vm, this, regExp, string, result);
     125    return result;
     126}
    127127
    128128} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.h

    r171939 r173269  
    2727namespace JSC {
    2828
    29     class RegExpMatchesArray : public JSArray {
    30     private:
    31         RegExpMatchesArray(VM&, Butterfly*, JSGlobalObject*, JSString*, RegExp*, MatchResult);
     29class RegExpMatchesArray : public JSArray {
     30private:
     31    RegExpMatchesArray(VM&, Butterfly*, JSGlobalObject*, JSString*, RegExp*, MatchResult);
    3232
    33         enum ReifiedState { ReifiedNone, ReifiedMatch, ReifiedAll };
     33    enum ReifiedState { ReifiedNone, ReifiedMatch, ReifiedAll };
    3434
    35     public:
    36         typedef JSArray Base;
     35public:
     36    typedef JSArray Base;
    3737
    38         static RegExpMatchesArray* create(ExecState*, JSString*, RegExp*, MatchResult);
     38    static RegExpMatchesArray* create(ExecState*, JSString*, RegExp*, MatchResult);
    3939
    40         JSString* leftContext(ExecState*);
    41         JSString* rightContext(ExecState*);
     40    JSString* leftContext(ExecState*);
     41    JSString* rightContext(ExecState*);
    4242
    43         DECLARE_INFO;
     43    DECLARE_INFO;
    4444
    45         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    46         {
    47             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayWithSlowPutArrayStorage);
    48         }
     45    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     46    {
     47        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(), ArrayWithSlowPutArrayStorage);
     48    }
    4949
    50         static void visitChildren(JSCell*, SlotVisitor&);
     50    static void visitChildren(JSCell*, SlotVisitor&);
    5151
    52     protected:
    53         void finishCreation(VM&);
     52protected:
     53    void finishCreation(VM&);
    5454
    55         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
     55    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
    5656
    57     private:
    58         ALWAYS_INLINE void reifyAllPropertiesIfNecessary(ExecState* exec)
    59         {
    60             if (m_state != ReifiedAll)
    61                 reifyAllProperties(exec);
    62         }
     57private:
     58    ALWAYS_INLINE void reifyAllPropertiesIfNecessary(ExecState* exec)
     59    {
     60        if (m_state != ReifiedAll)
     61            reifyAllProperties(exec);
     62    }
    6363
    64         ALWAYS_INLINE void reifyMatchPropertyIfNecessary(ExecState* exec)
    65         {
    66             if (m_state == ReifiedNone)
    67                 reifyMatchProperty(exec);
    68         }
     64    ALWAYS_INLINE void reifyMatchPropertyIfNecessary(ExecState* exec)
     65    {
     66        if (m_state == ReifiedNone)
     67            reifyMatchProperty(exec);
     68    }
    6969
    70         static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
    71         {
    72             RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
     70    static bool getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
     71    {
     72        RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
     73        thisObject->reifyAllPropertiesIfNecessary(exec);
     74        return JSArray::getOwnPropertySlot(thisObject, exec, propertyName, slot);
     75    }
     76
     77    static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
     78    {
     79        RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
     80        if (propertyName)
    7381            thisObject->reifyAllPropertiesIfNecessary(exec);
    74             return JSArray::getOwnPropertySlot(thisObject, exec, propertyName, slot);
    75         }
     82        else
     83            thisObject->reifyMatchPropertyIfNecessary(exec);
     84        return JSArray::getOwnPropertySlotByIndex(thisObject, exec, propertyName, slot);
     85    }
    7686
    77         static bool getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
    78         {
    79             RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
    80             if (propertyName)
    81                 thisObject->reifyAllPropertiesIfNecessary(exec);
    82             else
    83                 thisObject->reifyMatchPropertyIfNecessary(exec);
    84             return JSArray::getOwnPropertySlotByIndex(thisObject, exec, propertyName, slot);
    85         }
     87    static void put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue v, PutPropertySlot& slot)
     88    {
     89        RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
     90        thisObject->reifyAllPropertiesIfNecessary(exec);
     91        JSArray::put(thisObject, exec, propertyName, v, slot);
     92    }
    8693
    87         static void put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue v, PutPropertySlot& slot)
    88         {
    89             RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    90             thisObject->reifyAllPropertiesIfNecessary(exec);
    91             JSArray::put(thisObject, exec, propertyName, v, slot);
    92         }
    93        
    94         static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v, bool shouldThrow)
    95         {
    96             RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    97             thisObject->reifyAllPropertiesIfNecessary(exec);
    98             JSArray::putByIndex(thisObject, exec, propertyName, v, shouldThrow);
    99         }
     94    static void putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue v, bool shouldThrow)
     95    {
     96        RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
     97        thisObject->reifyAllPropertiesIfNecessary(exec);
     98        JSArray::putByIndex(thisObject, exec, propertyName, v, shouldThrow);
     99    }
    100100
    101         static bool deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
    102         {
    103             RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    104             thisObject->reifyAllPropertiesIfNecessary(exec);
    105             return JSArray::deleteProperty(thisObject, exec, propertyName);
    106         }
     101    static bool deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
     102    {
     103        RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
     104        thisObject->reifyAllPropertiesIfNecessary(exec);
     105        return JSArray::deleteProperty(thisObject, exec, propertyName);
     106    }
    107107
    108         static bool deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
    109         {
    110             RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
    111             thisObject->reifyAllPropertiesIfNecessary(exec);
    112             return JSArray::deletePropertyByIndex(thisObject, exec, propertyName);
    113         }
     108    static bool deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
     109    {
     110        RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(cell);
     111        thisObject->reifyAllPropertiesIfNecessary(exec);
     112        return JSArray::deletePropertyByIndex(thisObject, exec, propertyName);
     113    }
    114114
    115         static void getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
    116         {
    117             RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
    118             thisObject->reifyAllPropertiesIfNecessary(exec);
    119             JSArray::getOwnPropertyNames(thisObject, exec, arr, mode);
    120         }
     115    static void getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
     116    {
     117        RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
     118        thisObject->reifyAllPropertiesIfNecessary(exec);
     119        JSArray::getOwnPropertyNames(thisObject, exec, arr, mode);
     120    }
    121121
    122         static bool defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
    123         {
    124             RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
    125             thisObject->reifyAllPropertiesIfNecessary(exec);
    126             return JSArray::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
    127         }
     122    static bool defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
     123    {
     124        RegExpMatchesArray* thisObject = jsCast<RegExpMatchesArray*>(object);
     125        thisObject->reifyAllPropertiesIfNecessary(exec);
     126        return JSArray::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
     127    }
    128128
    129         void reifyAllProperties(ExecState*);
    130         void reifyMatchProperty(ExecState*);
     129    void reifyAllProperties(ExecState*);
     130    void reifyMatchProperty(ExecState*);
    131131
    132         WriteBarrier<JSString> m_input;
    133         WriteBarrier<RegExp> m_regExp;
    134         MatchResult m_result;
    135         ReifiedState m_state;
     132    WriteBarrier<JSString> m_input;
     133    WriteBarrier<RegExp> m_regExp;
     134    MatchResult m_result;
     135    ReifiedState m_state;
    136136};
    137137
  • trunk/Source/JavaScriptCore/runtime/RegExpObject.h

    r172176 r173269  
    2727namespace JSC {
    2828   
    29     class RegExpObject : public JSNonFinalObject {
    30     public:
    31         typedef JSNonFinalObject Base;
     29class RegExpObject : public JSNonFinalObject {
     30public:
     31    typedef JSNonFinalObject Base;
    3232
    33         static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp)
    34         {
    35             RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp);
    36             object->finishCreation(vm);
    37             return object;
    38         }
     33    static RegExpObject* create(VM& vm, Structure* structure, RegExp* regExp)
     34    {
     35        RegExpObject* object = new (NotNull, allocateCell<RegExpObject>(vm.heap)) RegExpObject(vm, structure, regExp);
     36        object->finishCreation(vm);
     37        return object;
     38    }
    3939
    40         void setRegExp(VM& vm, RegExp* r) { m_regExp.set(vm, this, r); }
    41         RegExp* regExp() const { return m_regExp.get(); }
     40    void setRegExp(VM& vm, RegExp* r) { m_regExp.set(vm, this, r); }
     41    RegExp* regExp() const { return m_regExp.get(); }
    4242
    43         void setLastIndex(ExecState* exec, size_t lastIndex)
    44         {
     43    void setLastIndex(ExecState* exec, size_t lastIndex)
     44    {
     45        m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
     46        if (LIKELY(m_lastIndexIsWritable))
    4547            m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
    46             if (LIKELY(m_lastIndexIsWritable))
    47                 m_lastIndex.setWithoutWriteBarrier(jsNumber(lastIndex));
    48             else
    49                 throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    50         }
    51         void setLastIndex(ExecState* exec, JSValue lastIndex, bool shouldThrow)
    52         {
    53             if (LIKELY(m_lastIndexIsWritable))
    54                 m_lastIndex.set(exec->vm(), this, lastIndex);
    55             else if (shouldThrow)
    56                 throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    57         }
    58         JSValue getLastIndex() const
    59         {
    60             return m_lastIndex.get();
    61         }
     48        else
     49            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
     50    }
     51    void setLastIndex(ExecState* exec, JSValue lastIndex, bool shouldThrow)
     52    {
     53        if (LIKELY(m_lastIndexIsWritable))
     54            m_lastIndex.set(exec->vm(), this, lastIndex);
     55        else if (shouldThrow)
     56            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
     57    }
     58    JSValue getLastIndex() const
     59    {
     60        return m_lastIndex.get();
     61    }
    6262
    63         bool test(ExecState* exec, JSString* string) { return match(exec, string); }
    64         JSValue exec(ExecState*, JSString*);
     63    bool test(ExecState* exec, JSString* string) { return match(exec, string); }
     64    JSValue exec(ExecState*, JSString*);
    6565
    66         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    67         static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
     66    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     67    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
    6868
    69         DECLARE_EXPORT_INFO;
     69    DECLARE_EXPORT_INFO;
    7070
    71         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    72         {
    73             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    74         }
     71    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     72    {
     73        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     74    }
    7575
    76     protected:
    77         JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);
    78         JS_EXPORT_PRIVATE void finishCreation(VM&);
     76protected:
     77    JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);
     78    JS_EXPORT_PRIVATE void finishCreation(VM&);
    7979
    80         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
     80    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;
    8181
    82         static void visitChildren(JSCell*, SlotVisitor&);
     82    static void visitChildren(JSCell*, SlotVisitor&);
    8383
    84         JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
    85         JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
    86         JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
    87         JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
    88         JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
     84    JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
     85    JS_EXPORT_PRIVATE static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     86    JS_EXPORT_PRIVATE static void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     87    JS_EXPORT_PRIVATE static void getGenericPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     88    JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
    8989
    90     private:
    91         MatchResult match(ExecState*, JSString*);
     90private:
     91    MatchResult match(ExecState*, JSString*);
    9292
    93         WriteBarrier<RegExp> m_regExp;
    94         WriteBarrier<Unknown> m_lastIndex;
    95         bool m_lastIndexIsWritable;
    96     };
     93    WriteBarrier<RegExp> m_regExp;
     94    WriteBarrier<Unknown> m_lastIndex;
     95    bool m_lastIndexIsWritable;
     96};
    9797
    98     RegExpObject* asRegExpObject(JSValue);
     98RegExpObject* asRegExpObject(JSValue);
    9999
    100     inline RegExpObject* asRegExpObject(JSValue value)
    101     {
    102         ASSERT(asObject(value)->inherits(RegExpObject::info()));
    103         return static_cast<RegExpObject*>(asObject(value));
    104     }
     100inline RegExpObject* asRegExpObject(JSValue value)
     101{
     102    ASSERT(asObject(value)->inherits(RegExpObject::info()));
     103    return static_cast<RegExpObject*>(asObject(value));
     104}
    105105
    106106} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/RegExpPrototype.h

    r156668 r173269  
    2727namespace JSC {
    2828
    29     class RegExpPrototype : public RegExpObject {
    30     public:
    31         typedef RegExpObject Base;
     29class RegExpPrototype : public RegExpObject {
     30public:
     31    typedef RegExpObject Base;
    3232
    33         static RegExpPrototype* create(VM& vm, Structure* structure, RegExp* regExp)
    34         {
    35             RegExpPrototype* prototype = new (NotNull, allocateCell<RegExpPrototype>(vm.heap)) RegExpPrototype(vm, structure, regExp);
    36             prototype->finishCreation(vm);
    37             return prototype;
    38         }
    39        
    40         DECLARE_INFO;
     33    static RegExpPrototype* create(VM& vm, Structure* structure, RegExp* regExp)
     34    {
     35        RegExpPrototype* prototype = new (NotNull, allocateCell<RegExpPrototype>(vm.heap)) RegExpPrototype(vm, structure, regExp);
     36        prototype->finishCreation(vm);
     37        return prototype;
     38    }
    4139
    42         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    43         {
    44             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    45         }
     40    DECLARE_INFO;
    4641
    47     protected:
    48         RegExpPrototype(VM&, Structure*, RegExp*);
    49         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | RegExpObject::StructureFlags;
     42    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     43    {
     44        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     45    }
    5046
    51     private:
    52         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    53     };
     47protected:
     48    RegExpPrototype(VM&, Structure*, RegExp*);
     49    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | RegExpObject::StructureFlags;
     50
     51private:
     52    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     53};
    5454
    5555} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/SmallStrings.h

    r169316 r173269  
    4848namespace JSC {
    4949
    50     class HeapRootVisitor;
    51     class VM;
    52     class JSString;
    53     class SmallStringsStorage;
    54     class SlotVisitor;
     50class HeapRootVisitor;
     51class VM;
     52class JSString;
     53class SmallStringsStorage;
     54class SlotVisitor;
    5555
    56     static const unsigned maxSingleCharacterString = 0xFF;
     56static const unsigned maxSingleCharacterString = 0xFF;
    5757
    58     class SmallStrings {
    59         WTF_MAKE_NONCOPYABLE(SmallStrings);
    60     public:
    61         SmallStrings();
    62         ~SmallStrings();
     58class SmallStrings {
     59    WTF_MAKE_NONCOPYABLE(SmallStrings);
     60public:
     61    SmallStrings();
     62    ~SmallStrings();
    6363
    64         JSString* emptyString()
    65         {
    66             return m_emptyString;
    67         }
     64    JSString* emptyString()
     65    {
     66        return m_emptyString;
     67    }
    6868
    69         JSString* singleCharacterString(unsigned char character)
    70         {
    71             return m_singleCharacterStrings[character];
    72         }
     69    JSString* singleCharacterString(unsigned char character)
     70    {
     71        return m_singleCharacterStrings[character];
     72    }
    7373
    74         JS_EXPORT_PRIVATE WTF::StringImpl* singleCharacterStringRep(unsigned char character);
     74    JS_EXPORT_PRIVATE WTF::StringImpl* singleCharacterStringRep(unsigned char character);
    7575
    76         JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
     76    JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }
    7777
    78         void initializeCommonStrings(VM&);
    79         void visitStrongReferences(SlotVisitor&);
     78    void initializeCommonStrings(VM&);
     79    void visitStrongReferences(SlotVisitor&);
    8080
    8181#define JSC_COMMON_STRINGS_ACCESSOR_DEFINITION(name) \
    82         JSString* name##String() const \
    83         { \
    84             return m_##name; \
    85         }
    86         JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ACCESSOR_DEFINITION)
     82    JSString* name##String() const                  \
     83    {                                                \
     84        return m_##name;                            \
     85    }
     86    JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ACCESSOR_DEFINITION)
    8787#undef JSC_COMMON_STRINGS_ACCESSOR_DEFINITION
    8888
    89         JSString* nullObjectString() const { return m_nullObjectString; }
    90         JSString* undefinedObjectString() const { return m_undefinedObjectString; }
     89    JSString* nullObjectString() const { return m_nullObjectString; }
     90    JSString* undefinedObjectString() const { return m_undefinedObjectString; }
    9191
    92     private:
    93         static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
     92private:
     93    static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;
    9494
    95         JS_EXPORT_PRIVATE void createEmptyString(VM*);
    96         JS_EXPORT_PRIVATE void createSingleCharacterString(VM*, unsigned char);
     95    JS_EXPORT_PRIVATE void createEmptyString(VM*);
     96    JS_EXPORT_PRIVATE void createSingleCharacterString(VM*, unsigned char);
    9797
    98         void initialize(VM* vm, JSString*& string, const char* value) const;
     98    void initialize(VM*, JSString*&, const char* value) const;
    9999
    100         JSString* m_emptyString;
     100    JSString* m_emptyString;
    101101#define JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION(name) JSString* m_##name;
    102         JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION)
     102    JSC_COMMON_STRINGS_EACH_NAME(JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION)
    103103#undef JSC_COMMON_STRINGS_ATTRIBUTE_DECLARATION
    104         JSString* m_nullObjectString;
    105         JSString* m_undefinedObjectString;
    106         JSString* m_singleCharacterStrings[singleCharacterStringCount];
    107         OwnPtr<SmallStringsStorage> m_storage;
    108     };
     104    JSString* m_nullObjectString;
     105    JSString* m_undefinedObjectString;
     106    JSString* m_singleCharacterStrings[singleCharacterStringCount];
     107    OwnPtr<SmallStringsStorage> m_storage;
     108};
    109109
    110110} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/StringConstructor.h

    r156624 r173269  
    2626namespace JSC {
    2727
    28     class StringPrototype;
     28class StringPrototype;
    2929
    30     class StringConstructor : public InternalFunction {
    31     public:
    32         typedef InternalFunction Base;
     30class StringConstructor : public InternalFunction {
     31public:
     32    typedef InternalFunction Base;
    3333
    34         static StringConstructor* create(VM& vm, Structure* structure, StringPrototype* stringPrototype)
    35         {
    36             StringConstructor* constructor = new (NotNull, allocateCell<StringConstructor>(vm.heap)) StringConstructor(vm, structure);
    37             constructor->finishCreation(vm, stringPrototype);
    38             return constructor;
    39         }
     34    static StringConstructor* create(VM& vm, Structure* structure, StringPrototype* stringPrototype)
     35    {
     36        StringConstructor* constructor = new (NotNull, allocateCell<StringConstructor>(vm.heap)) StringConstructor(vm, structure);
     37        constructor->finishCreation(vm, stringPrototype);
     38        return constructor;
     39    }
    4040
    41         DECLARE_INFO;
     41    DECLARE_INFO;
    4242
    43         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    44         {
    45             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    46         }
     43    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     44    {
     45        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     46    }
    4747
    48     protected:
    49         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
     48protected:
     49    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;
    5050
    51     private:
    52         StringConstructor(VM&, Structure*);
    53         void finishCreation(VM&, StringPrototype*);
    54         static ConstructType getConstructData(JSCell*, ConstructData&);
    55         static CallType getCallData(JSCell*, CallData&);
     51private:
     52    StringConstructor(VM&, Structure*);
     53    void finishCreation(VM&, StringPrototype*);
     54    static ConstructType getConstructData(JSCell*, ConstructData&);
     55    static CallType getCallData(JSCell*, CallData&);
    5656
    57         static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    58     };
     57    static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     58};
    5959   
    60     JSCell* JSC_HOST_CALL stringFromCharCode(ExecState*, int32_t);
     60JSCell* JSC_HOST_CALL stringFromCharCode(ExecState*, int32_t);
    6161
    6262} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/StringObject.h

    r171391 r173269  
    2727namespace JSC {
    2828
    29     class StringObject : public JSWrapperObject {
    30     public:
    31         typedef JSWrapperObject Base;
     29class StringObject : public JSWrapperObject {
     30public:
     31    typedef JSWrapperObject Base;
    3232
    33         static StringObject* create(VM& vm, Structure* structure)
    34         {
    35             JSString* string = jsEmptyString(&vm);
    36             StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure);
    37             object->finishCreation(vm, string);
    38             return object;
    39         }
    40         static StringObject* create(VM& vm, Structure* structure, JSString* string)
    41         {
    42             StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure);
    43             object->finishCreation(vm, string);
    44             return object;
    45         }
    46         static StringObject* create(VM&, JSGlobalObject*, JSString*);
     33    static StringObject* create(VM& vm, Structure* structure)
     34    {
     35        JSString* string = jsEmptyString(&vm);
     36        StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure);
     37        object->finishCreation(vm, string);
     38        return object;
     39    }
     40    static StringObject* create(VM& vm, Structure* structure, JSString* string)
     41    {
     42        StringObject* object = new (NotNull, allocateCell<StringObject>(vm.heap)) StringObject(vm, structure);
     43        object->finishCreation(vm, string);
     44        return object;
     45    }
     46    static StringObject* create(VM&, JSGlobalObject*, JSString*);
    4747
    48         JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
    49         JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
     48    JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
     49    JS_EXPORT_PRIVATE static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
    5050
    51         JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
    52         JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
     51    JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);
     52    JS_EXPORT_PRIVATE static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
    5353
    54         JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
    55         JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
    56         JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
    57         JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
     54    JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName);
     55    JS_EXPORT_PRIVATE static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
     56    JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
     57    JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
    5858
    59         DECLARE_EXPORT_INFO;
     59    DECLARE_EXPORT_INFO;
    6060
    61         JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
     61    JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
    6262
    63         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    64         {
    65             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    66         }
    67 
    68     protected:
    69         JS_EXPORT_PRIVATE void finishCreation(VM&, JSString*);
    70         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
    71         JS_EXPORT_PRIVATE StringObject(VM&, Structure*);
    72     };
    73 
    74     StringObject* asStringObject(JSValue);
    75 
    76     inline StringObject* asStringObject(JSValue value)
     63    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    7764    {
    78         ASSERT(asObject(value)->inherits(StringObject::info()));
    79         return static_cast<StringObject*>(asObject(value));
     65        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    8066    }
    8167
    82     JS_EXPORT_PRIVATE StringObject* constructString(VM&, JSGlobalObject*, JSValue);
     68protected:
     69    JS_EXPORT_PRIVATE void finishCreation(VM&, JSString*);
     70    static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
     71    JS_EXPORT_PRIVATE StringObject(VM&, Structure*);
     72};
     73
     74StringObject* asStringObject(JSValue);
     75
     76inline StringObject* asStringObject(JSValue value)
     77{
     78    ASSERT(asObject(value)->inherits(StringObject::info()));
     79    return static_cast<StringObject*>(asObject(value));
     80}
     81
     82JS_EXPORT_PRIVATE StringObject* constructString(VM&, JSGlobalObject*, JSValue);
    8383
    8484} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.h

    r156620 r173269  
    2626namespace JSC {
    2727
    28     class ObjectPrototype;
     28class ObjectPrototype;
    2929
    30     class StringPrototype : public StringObject {
    31     private:
    32         StringPrototype(VM&, Structure*);
     30class StringPrototype : public StringObject {
     31private:
     32    StringPrototype(VM&, Structure*);
    3333
    34     public:
    35         typedef StringObject Base;
     34public:
     35    typedef StringObject Base;
    3636
    37         static StringPrototype* create(VM&, JSGlobalObject*, Structure*);
     37    static StringPrototype* create(VM&, JSGlobalObject*, Structure*);
    3838
    39         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    40         {
    41             return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
    42         }
     39    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     40    {
     41        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     42    }
    4343
    44         DECLARE_INFO;
    45        
    46     protected:
    47         void finishCreation(VM&, JSGlobalObject*, JSString*);
    48         static const unsigned StructureFlags = StringObject::StructureFlags;
     44    DECLARE_INFO;
    4945
    50     };
     46protected:
     47    void finishCreation(VM&, JSGlobalObject*, JSString*);
     48    static const unsigned StructureFlags = StringObject::StructureFlags;
     49};
    5150
    5251} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/StructureChain.h

    r171939 r173269  
    3838namespace JSC {
    3939
    40     class LLIntOffsetsExtractor;
    41     class Structure;
     40class LLIntOffsetsExtractor;
     41class Structure;
    4242
    43     class StructureChain : public JSCell {
    44         friend class JIT;
     43class StructureChain : public JSCell {
     44    friend class JIT;
    4545
    46     public:
    47         typedef JSCell Base;
     46public:
     47    typedef JSCell Base;
    4848
    49         static StructureChain* create(VM& vm, Structure* head)
    50         {
    51             StructureChain* chain = new (NotNull, allocateCell<StructureChain>(vm.heap)) StructureChain(vm, vm.structureChainStructure.get());
    52             chain->finishCreation(vm, head);
    53             return chain;
    54         }
    55         WriteBarrier<Structure>* head() { return m_vector.get(); }
    56         static void visitChildren(JSCell*, SlotVisitor&);
     49    static StructureChain* create(VM& vm, Structure* head)
     50    {
     51        StructureChain* chain = new (NotNull, allocateCell<StructureChain>(vm.heap)) StructureChain(vm, vm.structureChainStructure.get());
     52        chain->finishCreation(vm, head);
     53        return chain;
     54    }
     55    WriteBarrier<Structure>* head() { return m_vector.get(); }
     56    static void visitChildren(JSCell*, SlotVisitor&);
    5757
    58         static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
    59         {
    60             return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
    61         }
    62        
    63         DECLARE_INFO;
     58    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     59    {
     60        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
     61    }
    6462
    65         static const bool needsDestruction = true;
    66         static const bool hasImmortalStructure = true;
    67         static void destroy(JSCell*);
     63    DECLARE_INFO;
    6864
    69     protected:
    70         static const unsigned StructureFlags = StructureIsImmortal;
     65    static const bool needsDestruction = true;
     66    static const bool hasImmortalStructure = true;
     67    static void destroy(JSCell*);
    7168
    72         void finishCreation(VM& vm, Structure* head)
    73         {
    74             Base::finishCreation(vm);
    75             size_t size = 0;
    76             for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
    77                 ++size;
    78    
    79             m_vector = std::make_unique<WriteBarrier<Structure>[]>(size + 1);
     69protected:
     70    static const unsigned StructureFlags = StructureIsImmortal;
    8071
    81             size_t i = 0;
    82             for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
    83                 m_vector[i++].set(vm, this, current);
    84         }
     72    void finishCreation(VM& vm, Structure* head)
     73    {
     74        Base::finishCreation(vm);
     75        size_t size = 0;
     76        for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
     77            ++size;
    8578
    86     private:
    87         friend class LLIntOffsetsExtractor;
    88        
    89         StructureChain(VM&, Structure*);
    90         std::unique_ptr<WriteBarrier<Structure>[]> m_vector;
    91     };
     79        m_vector = std::make_unique<WriteBarrier<Structure>[]>(size + 1);
     80
     81        size_t i = 0;
     82        for (Structure* current = head; current; current = current->storedPrototype().isNull() ? 0 : asObject(current->storedPrototype())->structure())
     83            m_vector[i++].set(vm, this, current);
     84    }
     85
     86private:
     87    friend class LLIntOffsetsExtractor;
     88
     89    StructureChain(VM&, Structure*);
     90    std::unique_ptr<WriteBarrier<Structure>[]> m_vector;
     91};
    9292
    9393} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r173100 r173269  
    7171namespace JSC {
    7272
    73     class ArityCheckFailReturnThunks;
    74     class BuiltinExecutables;
    75     class CallEdgeLog;
    76     class CodeBlock;
    77     class CodeCache;
    78     class CommonIdentifiers;
    79     class ExecState;
    80     class HandleStack;
    81     class TypeProfiler;
    82     class TypeProfilerLog;
    83     class Identifier;
    84     class Interpreter;
    85     class JSGlobalObject;
    86     class JSObject;
    87     class Keywords;
    88     class LLIntOffsetsExtractor;
    89     class LegacyProfiler;
    90     class NativeExecutable;
    91     class ParserArena;
    92     class RegExpCache;
    93     class ScriptExecutable;
    94     class SourceProvider;
    95     class SourceProviderCache;
    96     struct StackFrame;
    97     class Stringifier;
    98     class Structure;
     73class ArityCheckFailReturnThunks;
     74class BuiltinExecutables;
     75class CallEdgeLog;
     76class CodeBlock;
     77class CodeCache;
     78class CommonIdentifiers;
     79class ExecState;
     80class HandleStack;
     81class TypeProfiler;
     82class TypeProfilerLog;
     83class Identifier;
     84class Interpreter;
     85class JSGlobalObject;
     86class JSObject;
     87class Keywords;
     88class LLIntOffsetsExtractor;
     89class LegacyProfiler;
     90class NativeExecutable;
     91class ParserArena;
     92class RegExpCache;
     93class ScriptExecutable;
     94class SourceProvider;
     95class SourceProviderCache;
     96struct StackFrame;
     97class Stringifier;
     98class Structure;
    9999#if ENABLE(REGEXP_TRACING)
    100     class RegExp;
    101 #endif
    102     class UnlinkedCodeBlock;
    103     class UnlinkedEvalCodeBlock;
    104     class UnlinkedFunctionExecutable;
    105     class UnlinkedProgramCodeBlock;
    106     class VirtualRegister;
    107     class VMEntryScope;
    108     class Watchpoint;
    109     class WatchpointSet;
     100class RegExp;
     101#endif
     102class UnlinkedCodeBlock;
     103class UnlinkedEvalCodeBlock;
     104class UnlinkedFunctionExecutable;
     105class UnlinkedProgramCodeBlock;
     106class VirtualRegister;
     107class VMEntryScope;
     108class Watchpoint;
     109class WatchpointSet;
    110110
    111111#if ENABLE(DFG_JIT)
    112     namespace DFG {
    113     class LongLivedState;
    114     }
     112namespace DFG {
     113class LongLivedState;
     114}
    115115#endif // ENABLE(DFG_JIT)
    116116#if ENABLE(FTL_JIT)
    117     namespace FTL {
    118     class Thunks;
    119     }
     117namespace FTL {
     118class Thunks;
     119}
    120120#endif // ENABLE(FTL_JIT)
    121     namespace CommonSlowPaths {
    122     struct ArityCheckData;
    123     }
    124     namespace Profiler {
    125     class Database;
    126     }
    127 
    128     struct HashTable;
    129     struct Instruction;
    130 
    131     struct LocalTimeOffsetCache {
    132         LocalTimeOffsetCache()
    133             : start(0.0)
    134             , end(-1.0)
    135             , increment(0.0)
    136         {
    137         }
    138        
    139         void reset()
    140         {
    141             offset = LocalTimeOffset();
    142             start = 0.0;
    143             end = -1.0;
    144             increment = 0.0;
    145         }
    146 
    147         LocalTimeOffset offset;
    148         double start;
    149         double end;
    150         double increment;
    151     };
    152 
    153     class ConservativeRoots;
     121namespace CommonSlowPaths {
     122struct ArityCheckData;
     123}
     124namespace Profiler {
     125class Database;
     126}
     127
     128struct HashTable;
     129struct Instruction;
     130
     131struct LocalTimeOffsetCache {
     132    LocalTimeOffsetCache()
     133        : start(0.0)
     134        , end(-1.0)
     135        , increment(0.0)
     136    {
     137    }
     138
     139    void reset()
     140    {
     141        offset = LocalTimeOffset();
     142        start = 0.0;
     143        end = -1.0;
     144        increment = 0.0;
     145    }
     146
     147    LocalTimeOffset offset;
     148    double start;
     149    double end;
     150    double increment;
     151};
     152
     153class ConservativeRoots;
    154154
    155155#if COMPILER(MSVC)
     
    157157#pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning
    158158#endif
    159     struct ScratchBuffer {
    160         ScratchBuffer()
    161         {
    162             u.m_activeLength = 0;
    163         }
    164 
    165         static ScratchBuffer* create(size_t size)
    166         {
    167             ScratchBuffer* result = new (fastMalloc(ScratchBuffer::allocationSize(size))) ScratchBuffer;
    168 
    169             return result;
    170         }
    171 
    172         static size_t allocationSize(size_t bufferSize) { return sizeof(ScratchBuffer) + bufferSize; }
    173         void setActiveLength(size_t activeLength) { u.m_activeLength = activeLength; }
    174         size_t activeLength() const { return u.m_activeLength; };
    175         size_t* activeLengthPtr() { return &u.m_activeLength; };
    176         void* dataBuffer() { return m_buffer; }
    177 
    178         union {
    179             size_t m_activeLength;
    180             double pad; // Make sure m_buffer is double aligned.
    181         } u;
     159struct ScratchBuffer {
     160    ScratchBuffer()
     161    {
     162        u.m_activeLength = 0;
     163    }
     164
     165    static ScratchBuffer* create(size_t size)
     166    {
     167        ScratchBuffer* result = new (fastMalloc(ScratchBuffer::allocationSize(size))) ScratchBuffer;
     168
     169        return result;
     170    }
     171
     172    static size_t allocationSize(size_t bufferSize) { return sizeof(ScratchBuffer) + bufferSize; }
     173    void setActiveLength(size_t activeLength) { u.m_activeLength = activeLength; }
     174    size_t activeLength() const { return u.m_activeLength; };
     175    size_t* activeLengthPtr() { return &u.m_activeLength; };
     176    void* dataBuffer() { return m_buffer; }
     177
     178    union {
     179        size_t m_activeLength;
     180        double pad; // Make sure m_buffer is double aligned.
     181    } u;
    182182#if CPU(MIPS) && (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == 2)
    183         void* m_buffer[0] __attribute__((aligned(8)));
     183    void* m_buffer[0] __attribute__((aligned(8)));
    184184#else
    185         void* m_buffer[0];
    186 #endif
    187     };
     185    void* m_buffer[0];
     186#endif
     187};
    188188#if COMPILER(MSVC)
    189189#pragma warning(pop)
    190190#endif
    191191
    192     class VM : public ThreadSafeRefCounted<VM> {
    193     public:
    194         // WebCore has a one-to-one mapping of threads to VMs;
    195         // either create() or createLeaked() should only be called once
    196         // on a thread, this is the 'default' VM (it uses the
    197         // thread's default string uniquing table from wtfThreadData).
    198         // API contexts created using the new context group aware interface
    199         // create APIContextGroup objects which require less locking of JSC
    200         // than the old singleton APIShared VM created for use by
    201         // the original API.
    202         enum VMType { Default, APIContextGroup, APIShared };
    203        
    204         struct ClientData {
    205             JS_EXPORT_PRIVATE virtual ~ClientData() = 0;
    206         };
    207 
    208         bool isSharedInstance() { return vmType == APIShared; }
    209         bool usingAPI() { return vmType != Default; }
    210         JS_EXPORT_PRIVATE static bool sharedInstanceExists();
    211         JS_EXPORT_PRIVATE static VM& sharedInstance();
    212 
    213         JS_EXPORT_PRIVATE static PassRefPtr<VM> create(HeapType = SmallHeap);
    214         JS_EXPORT_PRIVATE static PassRefPtr<VM> createLeaked(HeapType = SmallHeap);
    215         static PassRefPtr<VM> createContextGroup(HeapType = SmallHeap);
    216         JS_EXPORT_PRIVATE ~VM();
    217 
    218         void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
    219        
    220     private:
    221         RefPtr<JSLock> m_apiLock;
    222 
    223     public:
     192class VM : public ThreadSafeRefCounted<VM> {
     193public:
     194    // WebCore has a one-to-one mapping of threads to VMs;
     195    // either create() or createLeaked() should only be called once
     196    // on a thread, this is the 'default' VM (it uses the
     197    // thread's default string uniquing table from wtfThreadData).
     198    // API contexts created using the new context group aware interface
     199    // create APIContextGroup objects which require less locking of JSC
     200    // than the old singleton APIShared VM created for use by
     201    // the original API.
     202    enum VMType { Default, APIContextGroup, APIShared };
     203
     204    struct ClientData {
     205        JS_EXPORT_PRIVATE virtual ~ClientData() = 0;
     206    };
     207
     208    bool isSharedInstance() { return vmType == APIShared; }
     209    bool usingAPI() { return vmType != Default; }
     210    JS_EXPORT_PRIVATE static bool sharedInstanceExists();
     211    JS_EXPORT_PRIVATE static VM& sharedInstance();
     212
     213    JS_EXPORT_PRIVATE static PassRefPtr<VM> create(HeapType = SmallHeap);
     214    JS_EXPORT_PRIVATE static PassRefPtr<VM> createLeaked(HeapType = SmallHeap);
     215    static PassRefPtr<VM> createContextGroup(HeapType = SmallHeap);
     216    JS_EXPORT_PRIVATE ~VM();
     217
     218    void makeUsableFromMultipleThreads() { heap.machineThreads().makeUsableFromMultipleThreads(); }
     219
     220private:
     221    RefPtr<JSLock> m_apiLock;
     222
     223public:
    224224#if ENABLE(ASSEMBLER)
    225         // executableAllocator should be destructed after the heap, as the heap can call executableAllocator
    226         // in its destructor.
    227         ExecutableAllocator executableAllocator;
    228 #endif
    229 
    230         // The heap should be just after executableAllocator and before other members to ensure that it's
    231         // destructed after all the objects that reference it.
    232         Heap heap;
    233        
     225    // executableAllocator should be destructed after the heap, as the heap can call executableAllocator
     226    // in its destructor.
     227    ExecutableAllocator executableAllocator;
     228#endif
     229
     230    // The heap should be just after executableAllocator and before other members to ensure that it's
     231    // destructed after all the objects that reference it.
     232    Heap heap;
     233
    234234#if ENABLE(DFG_JIT)
    235         OwnPtr<DFG::LongLivedState> dfgState;
     235    OwnPtr<DFG::LongLivedState> dfgState;
    236236#endif // ENABLE(DFG_JIT)
    237        
    238         std::unique_ptr<CallEdgeLog> callEdgeLog;
    239         CallEdgeLog& ensureCallEdgeLog();
    240 
    241         VMType vmType;
    242         ClientData* clientData;
    243         VMEntryFrame* topVMEntryFrame;
    244         ExecState* topCallFrame;
    245         std::unique_ptr<Watchdog> watchdog;
    246 
    247         Strong<Structure> structureStructure;
    248         Strong<Structure> structureRareDataStructure;
    249         Strong<Structure> terminatedExecutionErrorStructure;
    250         Strong<Structure> stringStructure;
    251         Strong<Structure> notAnObjectStructure;
    252         Strong<Structure> propertyNameIteratorStructure;
    253         Strong<Structure> propertyNameEnumeratorStructure;
    254         Strong<Structure> getterSetterStructure;
    255         Strong<Structure> customGetterSetterStructure;
    256         Strong<Structure> apiWrapperStructure;
    257         Strong<Structure> JSScopeStructure;
    258         Strong<Structure> executableStructure;
    259         Strong<Structure> nativeExecutableStructure;
    260         Strong<Structure> evalExecutableStructure;
    261         Strong<Structure> programExecutableStructure;
    262         Strong<Structure> functionExecutableStructure;
    263         Strong<Structure> regExpStructure;
    264         Strong<Structure> symbolTableStructure;
    265         Strong<Structure> structureChainStructure;
    266         Strong<Structure> sparseArrayValueMapStructure;
    267         Strong<Structure> arrayBufferNeuteringWatchpointStructure;
    268         Strong<Structure> unlinkedFunctionExecutableStructure;
    269         Strong<Structure> unlinkedProgramCodeBlockStructure;
    270         Strong<Structure> unlinkedEvalCodeBlockStructure;
    271         Strong<Structure> unlinkedFunctionCodeBlockStructure;
    272         Strong<Structure> propertyTableStructure;
    273         Strong<Structure> mapDataStructure;
    274         Strong<Structure> weakMapDataStructure;
     237
     238    std::unique_ptr<CallEdgeLog> callEdgeLog;
     239    CallEdgeLog& ensureCallEdgeLog();
     240
     241    VMType vmType;
     242    ClientData* clientData;
     243    VMEntryFrame* topVMEntryFrame;
     244    ExecState* topCallFrame;
     245    std::unique_ptr<Watchdog> watchdog;
     246
     247    Strong<Structure> structureStructure;
     248    Strong<Structure> structureRareDataStructure;
     249    Strong<Structure> terminatedExecutionErrorStructure;
     250    Strong<Structure> stringStructure;
     251    Strong<Structure> notAnObjectStructure;
     252    Strong<Structure> propertyNameIteratorStructure;
     253    Strong<Structure> propertyNameEnumeratorStructure;
     254    Strong<Structure> getterSetterStructure;
     255    Strong<Structure> customGetterSetterStructure;
     256    Strong<Structure> apiWrapperStructure;
     257    Strong<Structure> JSScopeStructure;
     258    Strong<Structure> executableStructure;
     259    Strong<Structure> nativeExecutableStructure;
     260    Strong<Structure> evalExecutableStructure;
     261    Strong<Structure> programExecutableStructure;
     262    Strong<Structure> functionExecutableStructure;
     263    Strong<Structure> regExpStructure;
     264    Strong<Structure> symbolTableStructure;
     265    Strong<Structure> structureChainStructure;
     266    Strong<Structure> sparseArrayValueMapStructure;
     267    Strong<Structure> arrayBufferNeuteringWatchpointStructure;
     268    Strong<Structure> unlinkedFunctionExecutableStructure;
     269    Strong<Structure> unlinkedProgramCodeBlockStructure;
     270    Strong<Structure> unlinkedEvalCodeBlockStructure;
     271    Strong<Structure> unlinkedFunctionCodeBlockStructure;
     272    Strong<Structure> propertyTableStructure;
     273    Strong<Structure> mapDataStructure;
     274    Strong<Structure> weakMapDataStructure;
    275275#if ENABLE(PROMISES)
    276         Strong<Structure> promiseDeferredStructure;
    277         Strong<Structure> promiseReactionStructure;
    278 #endif
    279         Strong<JSCell> iterationTerminator;
    280         Strong<JSCell> emptyPropertyNameEnumerator;
    281 
    282         AtomicStringTable* m_atomicStringTable;
    283         CommonIdentifiers* propertyNames;
    284         const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
    285         SmallStrings smallStrings;
    286         NumericStrings numericStrings;
    287         DateInstanceCache dateInstanceCache;
    288         WTF::SimpleStats machineCodeBytesPerBytecodeWordForBaselineJIT;
    289         WeakGCMap<StringImpl*, JSString, PtrHash<StringImpl*>> stringCache;
    290         Strong<JSString> lastCachedString;
    291 
    292         AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; }
    293 
    294         void setInDefineOwnProperty(bool inDefineOwnProperty)
    295         {
    296             m_inDefineOwnProperty = inDefineOwnProperty;
     276    Strong<Structure> promiseDeferredStructure;
     277    Strong<Structure> promiseReactionStructure;
     278#endif
     279    Strong<JSCell> iterationTerminator;
     280    Strong<JSCell> emptyPropertyNameEnumerator;
     281
     282    AtomicStringTable* m_atomicStringTable;
     283    CommonIdentifiers* propertyNames;
     284    const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
     285    SmallStrings smallStrings;
     286    NumericStrings numericStrings;
     287    DateInstanceCache dateInstanceCache;
     288    WTF::SimpleStats machineCodeBytesPerBytecodeWordForBaselineJIT;
     289    WeakGCMap<StringImpl*, JSString, PtrHash<StringImpl*>> stringCache;
     290    Strong<JSString> lastCachedString;
     291
     292    AtomicStringTable* atomicStringTable() const { return m_atomicStringTable; }
     293
     294    void setInDefineOwnProperty(bool inDefineOwnProperty)
     295    {
     296        m_inDefineOwnProperty = inDefineOwnProperty;
     297    }
     298
     299    bool isInDefineOwnProperty()
     300    {
     301        return m_inDefineOwnProperty;
     302    }
     303
     304    LegacyProfiler* enabledProfiler() { return m_enabledProfiler; }
     305    void setEnabledProfiler(LegacyProfiler*);
     306
     307    void* enabledProfilerAddress() { return &m_enabledProfiler; }
     308
     309#if ENABLE(JIT)
     310    bool canUseJIT() { return m_canUseJIT; }
     311#else
     312    bool canUseJIT() { return false; } // interpreter only
     313#endif
     314
     315#if ENABLE(YARR_JIT)
     316    bool canUseRegExpJIT() { return m_canUseRegExpJIT; }
     317#else
     318    bool canUseRegExpJIT() { return false; } // interpreter only
     319#endif
     320
     321    SourceProviderCache* addSourceProviderCache(SourceProvider*);
     322    void clearSourceProviderCaches();
     323
     324    PrototypeMap prototypeMap;
     325
     326    OwnPtr<ParserArena> parserArena;
     327    typedef HashMap<RefPtr<SourceProvider>, RefPtr<SourceProviderCache>> SourceProviderCacheMap;
     328    SourceProviderCacheMap sourceProviderCacheMap;
     329    OwnPtr<Keywords> keywords;
     330    Interpreter* interpreter;
     331#if ENABLE(JIT)
     332    OwnPtr<JITThunks> jitStubs;
     333    MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
     334    {
     335        return jitStubs->ctiStub(this, generator);
     336    }
     337    NativeExecutable* getHostFunction(NativeFunction, Intrinsic);
     338
     339    std::unique_ptr<ArityCheckFailReturnThunks> arityCheckFailReturnThunks;
     340#endif // ENABLE(JIT)
     341    std::unique_ptr<CommonSlowPaths::ArityCheckData> arityCheckData;
     342#if ENABLE(FTL_JIT)
     343    std::unique_ptr<FTL::Thunks> ftlThunks;
     344#endif
     345    NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor);
     346
     347    static ptrdiff_t exceptionOffset()
     348    {
     349        return OBJECT_OFFSETOF(VM, m_exception);
     350    }
     351
     352    static ptrdiff_t vmEntryFrameForThrowOffset()
     353    {
     354        return OBJECT_OFFSETOF(VM, vmEntryFrameForThrow);
     355    }
     356
     357    static ptrdiff_t topVMEntryFrameOffset()
     358    {
     359        return OBJECT_OFFSETOF(VM, topVMEntryFrame);
     360    }
     361
     362    static ptrdiff_t callFrameForThrowOffset()
     363    {
     364        return OBJECT_OFFSETOF(VM, callFrameForThrow);
     365    }
     366
     367    static ptrdiff_t targetMachinePCForThrowOffset()
     368    {
     369        return OBJECT_OFFSETOF(VM, targetMachinePCForThrow);
     370    }
     371
     372    JS_EXPORT_PRIVATE void clearException();
     373    JS_EXPORT_PRIVATE void clearExceptionStack();
     374    void getExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack);
     375    void setExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack);
     376    JSValue exception() const { return m_exception; }
     377    JSValue* addressOfException() { return &m_exception; }
     378    const RefCountedArray<StackFrame>& exceptionStack() const { return m_exceptionStack; }
     379
     380    JS_EXPORT_PRIVATE JSValue throwException(ExecState*, JSValue);
     381    JS_EXPORT_PRIVATE JSObject* throwException(ExecState*, JSObject*);
     382
     383    void* stackPointerAtVMEntry() const { return m_stackPointerAtVMEntry; }
     384    void setStackPointerAtVMEntry(void*);
     385
     386    size_t reservedZoneSize() const { return m_reservedZoneSize; }
     387    size_t updateReservedZoneSize(size_t reservedZoneSize);
     388
     389#if ENABLE(FTL_JIT)
     390    void updateFTLLargestStackSize(size_t);
     391    void** addressOfFTLStackLimit() { return &m_ftlStackLimit; }
     392#endif
     393
     394#if !ENABLE(JIT)
     395    void* jsStackLimit() { return m_jsStackLimit; }
     396    void setJSStackLimit(void* limit) { m_jsStackLimit = limit; }
     397#endif
     398    void* stackLimit() { return m_stackLimit; }
     399    void** addressOfStackLimit() { return &m_stackLimit; }
     400
     401    bool isSafeToRecurse(size_t neededStackInBytes = 0) const
     402    {
     403        ASSERT(wtfThreadData().stack().isGrowingDownward());
     404        int8_t* curr = reinterpret_cast<int8_t*>(&curr);
     405        int8_t* limit = reinterpret_cast<int8_t*>(m_stackLimit);
     406        return curr >= limit && static_cast<size_t>(curr - limit) >= neededStackInBytes;
     407    }
     408
     409    void* lastStackTop() { return m_lastStackTop; }
     410    void setLastStackTop(void* lastStackTop) { m_lastStackTop = lastStackTop; }
     411
     412    const ClassInfo* const jsArrayClassInfo;
     413    const ClassInfo* const jsFinalObjectClassInfo;
     414
     415    JSValue hostCallReturnValue;
     416    ExecState* newCallFrameReturnValue;
     417    VMEntryFrame* vmEntryFrameForThrow;
     418    ExecState* callFrameForThrow;
     419    void* targetMachinePCForThrow;
     420    Instruction* targetInterpreterPCForThrow;
     421    uint32_t osrExitIndex;
     422    void* osrExitJumpDestination;
     423    Vector<ScratchBuffer*> scratchBuffers;
     424    size_t sizeOfLastScratchBuffer;
     425
     426    ScratchBuffer* scratchBufferForSize(size_t size)
     427    {
     428        if (!size)
     429            return 0;
     430
     431        if (size > sizeOfLastScratchBuffer) {
     432            // Protect against a N^2 memory usage pathology by ensuring
     433            // that at worst, we get a geometric series, meaning that the
     434            // total memory usage is somewhere around
     435            // max(scratch buffer size) * 4.
     436            sizeOfLastScratchBuffer = size * 2;
     437
     438            ScratchBuffer* newBuffer = ScratchBuffer::create(sizeOfLastScratchBuffer);
     439            RELEASE_ASSERT(newBuffer);
     440            scratchBuffers.append(newBuffer);
    297441        }
    298442
    299         bool isInDefineOwnProperty()
    300         {
    301             return m_inDefineOwnProperty;
    302         }
    303 
    304         LegacyProfiler* enabledProfiler() { return m_enabledProfiler; }
    305         void setEnabledProfiler(LegacyProfiler*);
    306 
    307         void* enabledProfilerAddress() { return &m_enabledProfiler; }
    308 
     443        ScratchBuffer* result = scratchBuffers.last();
     444        result->setActiveLength(0);
     445        return result;
     446    }
     447
     448    void gatherConservativeRoots(ConservativeRoots&);
     449
     450    VMEntryScope* entryScope;
     451
     452    HashSet<JSObject*> stringRecursionCheckVisitedObjects;
     453
     454    LocalTimeOffsetCache localTimeOffsetCache;
     455
     456    String cachedDateString;
     457    double cachedDateStringValue;
     458
     459    OwnPtr<Profiler::Database> m_perBytecodeProfiler;
     460    RefPtr<TypedArrayController> m_typedArrayController;
     461    RegExpCache* m_regExpCache;
     462    BumpPointerAllocator m_regExpAllocator;
     463
     464#if ENABLE(REGEXP_TRACING)
     465    typedef ListHashSet<RegExp*> RTTraceList;
     466    RTTraceList* m_rtTraceList;
     467#endif
     468
     469    bool hasExclusiveThread() const { return m_apiLock->hasExclusiveThread(); }
     470    std::thread::id exclusiveThread() const { return m_apiLock->exclusiveThread(); }
     471    void setExclusiveThread(std::thread::id threadId) { m_apiLock->setExclusiveThread(threadId); }
     472
     473    JS_EXPORT_PRIVATE void resetDateCache();
     474
     475    JS_EXPORT_PRIVATE void startSampling();
     476    JS_EXPORT_PRIVATE void stopSampling();
     477    JS_EXPORT_PRIVATE void dumpSampleData(ExecState*);
     478    RegExpCache* regExpCache() { return m_regExpCache; }
     479#if ENABLE(REGEXP_TRACING)
     480    void addRegExpToTrace(RegExp*);
     481#endif
     482    JS_EXPORT_PRIVATE void dumpRegExpTrace();
     483
     484    bool isCollectorBusy() { return heap.isBusy(); }
     485    JS_EXPORT_PRIVATE void releaseExecutableMemory();
     486
     487#if ENABLE(GC_VALIDATION)
     488    bool isInitializingObject() const;
     489    void setInitializingObjectClass(const ClassInfo*);
     490#endif
     491
     492    unsigned m_newStringsSinceLastHashCons;
     493
     494    static const unsigned s_minNumberOfNewStringsToHashCons = 100;
     495
     496    bool haveEnoughNewStringsToHashCons() { return m_newStringsSinceLastHashCons > s_minNumberOfNewStringsToHashCons; }
     497    void resetNewStringsSinceLastHashCons() { m_newStringsSinceLastHashCons = 0; }
     498
     499    bool currentThreadIsHoldingAPILock() const { return m_apiLock->currentThreadIsHoldingLock(); }
     500
     501    JSLock& apiLock() { return *m_apiLock; }
     502    CodeCache* codeCache() { return m_codeCache.get(); }
     503
     504    void waitForCompilationsToComplete();
     505
     506    JS_EXPORT_PRIVATE void discardAllCode();
     507
     508    void registerWatchpointForImpureProperty(const Identifier&, Watchpoint*);
     509    // FIXME: Use AtomicString once it got merged with Identifier.
     510    JS_EXPORT_PRIVATE void addImpureProperty(const String&);
     511
     512    BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
     513
     514    bool enableTypeProfiler();
     515    bool disableTypeProfiler();
     516    TypeProfilerLog* typeProfilerLog() { return m_typeProfilerLog.get(); }
     517    TypeProfiler* typeProfiler() { return m_typeProfiler.get(); }
     518    TypeLocation* nextTypeLocation();
     519    JS_EXPORT_PRIVATE void dumpTypeProfilerData();
     520    void invalidateTypeSetCache();
     521    GlobalVariableID getNextUniqueVariableID() { return m_nextUniqueVariableID++; }
     522
     523private:
     524    friend class LLIntOffsetsExtractor;
     525    friend class ClearExceptionScope;
     526    friend class RecursiveAllocationScope;
     527
     528    VM(VMType, HeapType);
     529    static VM*& sharedInstanceInternal();
     530    void createNativeThunk();
     531
     532    void updateStackLimit();
     533
     534#if ENABLE(ASSEMBLER)
     535    bool m_canUseAssembler;
     536#endif
    309537#if ENABLE(JIT)
    310         bool canUseJIT() { return m_canUseJIT; }
     538    bool m_canUseJIT;
     539#endif
     540#if ENABLE(YARR_JIT)
     541    bool m_canUseRegExpJIT;
     542#endif
     543#if ENABLE(GC_VALIDATION)
     544    const ClassInfo* m_initializingObjectClass;
     545#endif
     546    void* m_stackPointerAtVMEntry;
     547    size_t m_reservedZoneSize;
     548#if !ENABLE(JIT)
     549    struct {
     550        void* m_stackLimit;
     551        void* m_jsStackLimit;
     552    };
    311553#else
    312         bool canUseJIT() { return false; } // interpreter only
    313 #endif
    314 
    315 #if ENABLE(YARR_JIT)
    316         bool canUseRegExpJIT() { return m_canUseRegExpJIT; }
    317 #else
    318         bool canUseRegExpJIT() { return false; } // interpreter only
    319 #endif
    320 
    321         SourceProviderCache* addSourceProviderCache(SourceProvider*);
    322         void clearSourceProviderCaches();
    323 
    324         PrototypeMap prototypeMap;
    325 
    326         OwnPtr<ParserArena> parserArena;
    327         typedef HashMap<RefPtr<SourceProvider>, RefPtr<SourceProviderCache>> SourceProviderCacheMap;
    328         SourceProviderCacheMap sourceProviderCacheMap;
    329         OwnPtr<Keywords> keywords;
    330         Interpreter* interpreter;
     554    union {
     555        void* m_stackLimit;
     556        void* m_jsStackLimit;
     557    };
     558#if ENABLE(FTL_JIT)
     559    void* m_ftlStackLimit;
     560    size_t m_largestFTLStackSize;
     561#endif
     562#endif
     563    void* m_lastStackTop;
     564    JSValue m_exception;
     565    bool m_inDefineOwnProperty;
     566    OwnPtr<CodeCache> m_codeCache;
     567    LegacyProfiler* m_enabledProfiler;
     568    OwnPtr<BuiltinExecutables> m_builtinExecutables;
     569    RefCountedArray<StackFrame> m_exceptionStack;
     570    HashMap<String, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
     571    std::unique_ptr<TypeProfiler> m_typeProfiler;
     572    std::unique_ptr<TypeProfilerLog> m_typeProfilerLog;
     573    GlobalVariableID m_nextUniqueVariableID;
     574    unsigned m_typeProfilerEnabledCount;
     575    std::unique_ptr<Bag<TypeLocation>> m_typeLocationInfo;
     576};
     577
     578#if ENABLE(GC_VALIDATION)
     579inline bool VM::isInitializingObject() const
     580{
     581    return !!m_initializingObjectClass;
     582}
     583
     584inline void VM::setInitializingObjectClass(const ClassInfo* initializingObjectClass)
     585{
     586    m_initializingObjectClass = initializingObjectClass;
     587}
     588#endif
     589
     590inline Heap* WeakSet::heap() const
     591{
     592    return &m_vm->heap;
     593}
     594
    331595#if ENABLE(JIT)
    332         OwnPtr<JITThunks> jitStubs;
    333         MacroAssemblerCodeRef getCTIStub(ThunkGenerator generator)
    334         {
    335             return jitStubs->ctiStub(this, generator);
    336         }
    337         NativeExecutable* getHostFunction(NativeFunction, Intrinsic);
    338        
    339         std::unique_ptr<ArityCheckFailReturnThunks> arityCheckFailReturnThunks;
    340 #endif // ENABLE(JIT)
    341         std::unique_ptr<CommonSlowPaths::ArityCheckData> arityCheckData;
    342 #if ENABLE(FTL_JIT)
    343         std::unique_ptr<FTL::Thunks> ftlThunks;
    344 #endif
    345         NativeExecutable* getHostFunction(NativeFunction, NativeFunction constructor);
    346 
    347         static ptrdiff_t exceptionOffset()
    348         {
    349             return OBJECT_OFFSETOF(VM, m_exception);
    350         }
    351 
    352         static ptrdiff_t vmEntryFrameForThrowOffset()
    353         {
    354             return OBJECT_OFFSETOF(VM, vmEntryFrameForThrow);
    355         }
    356 
    357         static ptrdiff_t topVMEntryFrameOffset()
    358         {
    359             return OBJECT_OFFSETOF(VM, topVMEntryFrame);
    360         }
    361 
    362         static ptrdiff_t callFrameForThrowOffset()
    363         {
    364             return OBJECT_OFFSETOF(VM, callFrameForThrow);
    365         }
    366 
    367         static ptrdiff_t targetMachinePCForThrowOffset()
    368         {
    369             return OBJECT_OFFSETOF(VM, targetMachinePCForThrow);
    370         }
    371 
    372         JS_EXPORT_PRIVATE void clearException();
    373         JS_EXPORT_PRIVATE void clearExceptionStack();
    374         void getExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack);
    375         void setExceptionInfo(JSValue& exception, RefCountedArray<StackFrame>& exceptionStack);
    376         JSValue exception() const { return m_exception; }
    377         JSValue* addressOfException() { return &m_exception; }
    378         const RefCountedArray<StackFrame>& exceptionStack() const { return m_exceptionStack; }
    379 
    380         JS_EXPORT_PRIVATE JSValue throwException(ExecState*, JSValue);
    381         JS_EXPORT_PRIVATE JSObject* throwException(ExecState*, JSObject*);
    382        
    383         void* stackPointerAtVMEntry() const { return m_stackPointerAtVMEntry; }
    384         void setStackPointerAtVMEntry(void*);
    385 
    386         size_t reservedZoneSize() const { return m_reservedZoneSize; }
    387         size_t updateReservedZoneSize(size_t reservedZoneSize);
    388 
    389 #if ENABLE(FTL_JIT)
    390         void updateFTLLargestStackSize(size_t);
    391         void** addressOfFTLStackLimit() { return &m_ftlStackLimit; }
    392 #endif
    393 
    394 #if !ENABLE(JIT)
    395         void* jsStackLimit() { return m_jsStackLimit; }
    396         void setJSStackLimit(void* limit) { m_jsStackLimit = limit; }
    397 #endif
    398         void* stackLimit() { return m_stackLimit; }
    399         void** addressOfStackLimit() { return &m_stackLimit; }
    400 
    401         bool isSafeToRecurse(size_t neededStackInBytes = 0) const
    402         {
    403             ASSERT(wtfThreadData().stack().isGrowingDownward());
    404             int8_t* curr = reinterpret_cast<int8_t*>(&curr);
    405             int8_t* limit = reinterpret_cast<int8_t*>(m_stackLimit);
    406             return curr >= limit && static_cast<size_t>(curr - limit) >= neededStackInBytes;
    407         }
    408 
    409         void* lastStackTop() { return m_lastStackTop; }
    410         void setLastStackTop(void* lastStackTop) { m_lastStackTop = lastStackTop; }
    411 
    412         const ClassInfo* const jsArrayClassInfo;
    413         const ClassInfo* const jsFinalObjectClassInfo;
    414 
    415         JSValue hostCallReturnValue;
    416         ExecState* newCallFrameReturnValue;
    417         VMEntryFrame* vmEntryFrameForThrow;
    418         ExecState* callFrameForThrow;
    419         void* targetMachinePCForThrow;
    420         Instruction* targetInterpreterPCForThrow;
    421         uint32_t osrExitIndex;
    422         void* osrExitJumpDestination;
    423         Vector<ScratchBuffer*> scratchBuffers;
    424         size_t sizeOfLastScratchBuffer;
    425        
    426         ScratchBuffer* scratchBufferForSize(size_t size)
    427         {
    428             if (!size)
    429                 return 0;
    430            
    431             if (size > sizeOfLastScratchBuffer) {
    432                 // Protect against a N^2 memory usage pathology by ensuring
    433                 // that at worst, we get a geometric series, meaning that the
    434                 // total memory usage is somewhere around
    435                 // max(scratch buffer size) * 4.
    436                 sizeOfLastScratchBuffer = size * 2;
    437 
    438                 ScratchBuffer* newBuffer = ScratchBuffer::create(sizeOfLastScratchBuffer);
    439                 RELEASE_ASSERT(newBuffer);
    440                 scratchBuffers.append(newBuffer);
    441             }
    442 
    443             ScratchBuffer* result = scratchBuffers.last();
    444             result->setActiveLength(0);
    445             return result;
    446         }
    447 
    448         void gatherConservativeRoots(ConservativeRoots&);
    449 
    450         VMEntryScope* entryScope;
    451 
    452         HashSet<JSObject*> stringRecursionCheckVisitedObjects;
    453 
    454         LocalTimeOffsetCache localTimeOffsetCache;
    455        
    456         String cachedDateString;
    457         double cachedDateStringValue;
    458 
    459         OwnPtr<Profiler::Database> m_perBytecodeProfiler;
    460         RefPtr<TypedArrayController> m_typedArrayController;
    461         RegExpCache* m_regExpCache;
    462         BumpPointerAllocator m_regExpAllocator;
    463 
    464 #if ENABLE(REGEXP_TRACING)
    465         typedef ListHashSet<RegExp*> RTTraceList;
    466         RTTraceList* m_rtTraceList;
    467 #endif
    468 
    469         bool hasExclusiveThread() const { return m_apiLock->hasExclusiveThread(); }
    470         std::thread::id exclusiveThread() const { return m_apiLock->exclusiveThread(); }
    471         void setExclusiveThread(std::thread::id threadId) { m_apiLock->setExclusiveThread(threadId); }
    472 
    473         JS_EXPORT_PRIVATE void resetDateCache();
    474 
    475         JS_EXPORT_PRIVATE void startSampling();
    476         JS_EXPORT_PRIVATE void stopSampling();
    477         JS_EXPORT_PRIVATE void dumpSampleData(ExecState* exec);
    478         RegExpCache* regExpCache() { return m_regExpCache; }
    479 #if ENABLE(REGEXP_TRACING)
    480         void addRegExpToTrace(RegExp*);
    481 #endif
    482         JS_EXPORT_PRIVATE void dumpRegExpTrace();
    483 
    484         bool isCollectorBusy() { return heap.isBusy(); }
    485         JS_EXPORT_PRIVATE void releaseExecutableMemory();
    486 
    487 #if ENABLE(GC_VALIDATION)
    488         bool isInitializingObject() const;
    489         void setInitializingObjectClass(const ClassInfo*);
    490 #endif
    491 
    492         unsigned m_newStringsSinceLastHashCons;
    493 
    494         static const unsigned s_minNumberOfNewStringsToHashCons = 100;
    495 
    496         bool haveEnoughNewStringsToHashCons() { return m_newStringsSinceLastHashCons > s_minNumberOfNewStringsToHashCons; }
    497         void resetNewStringsSinceLastHashCons() { m_newStringsSinceLastHashCons = 0; }
    498 
    499         bool currentThreadIsHoldingAPILock() const { return m_apiLock->currentThreadIsHoldingLock(); }
    500 
    501         JSLock& apiLock() { return *m_apiLock; }
    502         CodeCache* codeCache() { return m_codeCache.get(); }
    503 
    504         void waitForCompilationsToComplete();
    505        
    506         JS_EXPORT_PRIVATE void discardAllCode();
    507 
    508         void registerWatchpointForImpureProperty(const Identifier&, Watchpoint*);
    509         // FIXME: Use AtomicString once it got merged with Identifier.
    510         JS_EXPORT_PRIVATE void addImpureProperty(const String&);
    511        
    512         BuiltinExecutables* builtinExecutables() { return m_builtinExecutables.get(); }
    513 
    514         bool enableTypeProfiler();
    515         bool disableTypeProfiler();
    516         TypeProfilerLog* typeProfilerLog() { return m_typeProfilerLog.get(); }
    517         TypeProfiler* typeProfiler() { return m_typeProfiler.get(); }
    518         TypeLocation* nextTypeLocation();
    519         JS_EXPORT_PRIVATE void dumpTypeProfilerData();
    520         void invalidateTypeSetCache();
    521         GlobalVariableID getNextUniqueVariableID() { return m_nextUniqueVariableID++; }
    522 
    523     private:
    524         friend class LLIntOffsetsExtractor;
    525         friend class ClearExceptionScope;
    526         friend class RecursiveAllocationScope;
    527        
    528         VM(VMType, HeapType);
    529         static VM*& sharedInstanceInternal();
    530         void createNativeThunk();
    531 
    532         void updateStackLimit();
    533 
    534 #if ENABLE(ASSEMBLER)
    535         bool m_canUseAssembler;
    536 #endif
    537 #if ENABLE(JIT)
    538         bool m_canUseJIT;
    539 #endif
    540 #if ENABLE(YARR_JIT)
    541         bool m_canUseRegExpJIT;
    542 #endif
    543 #if ENABLE(GC_VALIDATION)
    544         const ClassInfo* m_initializingObjectClass;
    545 #endif
    546         void* m_stackPointerAtVMEntry;
    547         size_t m_reservedZoneSize;
    548 #if !ENABLE(JIT)
    549         struct {
    550             void* m_stackLimit;
    551             void* m_jsStackLimit;
    552         };
    553 #else
    554         union {
    555             void* m_stackLimit;
    556             void* m_jsStackLimit;
    557         };
    558 #if ENABLE(FTL_JIT)
    559         void* m_ftlStackLimit;
    560         size_t m_largestFTLStackSize;
    561 #endif
    562 #endif
    563         void* m_lastStackTop;
    564         JSValue m_exception;
    565         bool m_inDefineOwnProperty;
    566         OwnPtr<CodeCache> m_codeCache;
    567         LegacyProfiler* m_enabledProfiler;
    568         OwnPtr<BuiltinExecutables> m_builtinExecutables;
    569         RefCountedArray<StackFrame> m_exceptionStack;
    570         HashMap<String, RefPtr<WatchpointSet>> m_impurePropertyWatchpointSets;
    571         std::unique_ptr<TypeProfiler> m_typeProfiler;
    572         std::unique_ptr<TypeProfilerLog> m_typeProfilerLog;
    573         GlobalVariableID m_nextUniqueVariableID;
    574         unsigned m_typeProfilerEnabledCount;
    575         std::unique_ptr<Bag<TypeLocation>> m_typeLocationInfo;
    576     };
    577 
    578 #if ENABLE(GC_VALIDATION)
    579     inline bool VM::isInitializingObject() const
    580     {
    581         return !!m_initializingObjectClass;
    582     }
    583 
    584     inline void VM::setInitializingObjectClass(const ClassInfo* initializingObjectClass)
    585     {
    586         m_initializingObjectClass = initializingObjectClass;
    587     }
    588 #endif
    589 
    590     inline Heap* WeakSet::heap() const
    591     {
    592         return &m_vm->heap;
    593     }
    594 
    595 #if ENABLE(JIT)
    596     extern "C" void sanitizeStackForVMImpl(VM*);
    597 #endif
    598 
    599     void sanitizeStackForVM(VM*);
    600     void logSanitizeStack(VM*);
     596extern "C" void sanitizeStackForVMImpl(VM*);
     597#endif
     598
     599void sanitizeStackForVM(VM*);
     600void logSanitizeStack(VM*);
    601601
    602602} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.