Changeset 173269 in webkit
- Timestamp:
- Sep 4, 2014, 12:10:36 PM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 50 edited
-
ChangeLog (modified) (1 diff)
-
runtime/Completion.h (modified) (1 diff)
-
runtime/ConstructData.h (modified) (1 diff)
-
runtime/DateConstructor.h (modified) (1 diff)
-
runtime/DateInstance.h (modified) (1 diff)
-
runtime/DateInstanceCache.h (modified) (1 diff)
-
runtime/DatePrototype.h (modified) (1 diff)
-
runtime/Error.h (modified) (1 diff)
-
runtime/ErrorConstructor.h (modified) (1 diff)
-
runtime/ErrorInstance.h (modified) (1 diff)
-
runtime/ErrorPrototype.h (modified) (1 diff)
-
runtime/FunctionConstructor.h (modified) (1 diff)
-
runtime/FunctionPrototype.h (modified) (1 diff)
-
runtime/GetterSetter.h (modified) (1 diff)
-
runtime/Identifier.h (modified) (1 diff)
-
runtime/InitializeThreading.h (modified) (1 diff)
-
runtime/InternalFunction.h (modified) (1 diff)
-
runtime/JSAPIValueWrapper.h (modified) (1 diff)
-
runtime/JSFunction.h (modified) (1 diff)
-
runtime/JSLock.h (modified) (1 diff)
-
runtime/JSNotAnObject.h (modified) (1 diff)
-
runtime/JSONObject.h (modified) (1 diff)
-
runtime/JSString.h (modified) (1 diff)
-
runtime/JSTypeInfo.h (modified) (1 diff)
-
runtime/JSWrapperObject.h (modified) (1 diff)
-
runtime/Lookup.h (modified) (1 diff)
-
runtime/MathObject.h (modified) (1 diff)
-
runtime/NativeErrorConstructor.h (modified) (1 diff)
-
runtime/NativeErrorPrototype.h (modified) (1 diff)
-
runtime/NumberConstructor.h (modified) (1 diff)
-
runtime/NumberObject.h (modified) (1 diff)
-
runtime/NumberPrototype.h (modified) (1 diff)
-
runtime/NumericStrings.h (modified) (1 diff)
-
runtime/ObjectConstructor.h (modified) (1 diff)
-
runtime/ObjectPrototype.h (modified) (1 diff)
-
runtime/PropertyDescriptor.h (modified) (1 diff)
-
runtime/Protect.h (modified) (1 diff)
-
runtime/PutPropertySlot.h (modified) (1 diff)
-
runtime/RegExp.h (modified) (1 diff)
-
runtime/RegExpCachedResult.h (modified) (1 diff)
-
runtime/RegExpConstructor.h (modified) (1 diff)
-
runtime/RegExpMatchesArray.h (modified) (1 diff)
-
runtime/RegExpObject.h (modified) (1 diff)
-
runtime/RegExpPrototype.h (modified) (1 diff)
-
runtime/SmallStrings.h (modified) (1 diff)
-
runtime/StringConstructor.h (modified) (1 diff)
-
runtime/StringObject.h (modified) (1 diff)
-
runtime/StringPrototype.h (modified) (1 diff)
-
runtime/StructureChain.h (modified) (1 diff)
-
runtime/VM.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r173268 r173269 1 2014-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 1 60 2014-09-04 Eva Balazsfalvi <evab.u-szeged@partner.samsung.com> 2 61 -
trunk/Source/JavaScriptCore/runtime/Completion.h
r149130 r173269 28 28 namespace JSC { 29 29 30 struct ParserError;31 class ExecState;32 class JSScope;33 class SourceCode;34 class VM;30 struct ParserError; 31 class ExecState; 32 class JSScope; 33 class SourceCode; 34 class VM; 35 35 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);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); 39 39 40 40 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ConstructData.h
r165676 r173269 35 35 namespace JSC { 36 36 37 class ArgList;38 class ExecState;39 class FunctionExecutable;40 class JSObject;41 class JSScope;37 class ArgList; 38 class ExecState; 39 class FunctionExecutable; 40 class JSObject; 41 class JSScope; 42 42 43 enum ConstructType {44 ConstructTypeNone,45 ConstructTypeHost,46 ConstructTypeJS47 };43 enum ConstructType { 44 ConstructTypeNone, 45 ConstructTypeHost, 46 ConstructTypeJS 47 }; 48 48 49 union ConstructData {50 struct {51 NativeFunction function;52 } native;53 struct {54 FunctionExecutable* functionExecutable;55 JSScope* scope;56 } js;57 };49 union ConstructData { 50 struct { 51 NativeFunction function; 52 } native; 53 struct { 54 FunctionExecutable* functionExecutable; 55 JSScope* scope; 56 } js; 57 }; 58 58 59 JS_EXPORT_PRIVATE JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);59 JS_EXPORT_PRIVATE JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&); 60 60 61 61 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/DateConstructor.h
r156624 r173269 26 26 namespace JSC { 27 27 28 class DatePrototype;28 class DatePrototype; 29 29 30 class DateConstructor : public InternalFunction {31 public:32 typedef InternalFunction Base;30 class DateConstructor : public InternalFunction { 31 public: 32 typedef InternalFunction Base; 33 33 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 } 40 40 41 DECLARE_INFO;41 DECLARE_INFO; 42 42 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 } 47 47 48 protected:49 void finishCreation(VM&, DatePrototype*);50 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;48 protected: 49 void finishCreation(VM&, DatePrototype*); 50 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags; 51 51 52 private:53 DateConstructor(VM&, Structure*);54 static ConstructType getConstructData(JSCell*, ConstructData&);55 static CallType getCallData(JSCell*, CallData&);52 private: 53 DateConstructor(VM&, Structure*); 54 static ConstructType getConstructData(JSCell*, ConstructData&); 55 static CallType getCallData(JSCell*, CallData&); 56 56 57 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);58 };57 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 58 }; 59 59 60 JSObject* constructDate(ExecState*, JSGlobalObject*, const ArgList&);60 JSObject* constructDate(ExecState*, JSGlobalObject*, const ArgList&); 61 61 62 62 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/DateInstance.h
r171391 r173269 26 26 namespace JSC { 27 27 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);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); 33 33 34 JS_EXPORT_PRIVATE static void destroy(JSCell*); 35 36 public: 37 typedef JSWrapperObject Base; 34 JS_EXPORT_PRIVATE static void destroy(JSCell*); 38 35 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 } 36 public: 37 typedef JSWrapperObject Base; 45 38 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 } 52 45 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 } 54 52 55 DECLARE_EXPORT_INFO;53 double internalNumber() const { return internalValue().asNumber(); } 56 54 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; 70 56 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 } 75 63 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 } 79 70 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 } 82 75 83 DateInstance* asDateInstance(JSValue); 76 private: 77 JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTime(ExecState*) const; 78 JS_EXPORT_PRIVATE const GregorianDateTime* calculateGregorianDateTimeUTC(ExecState*) const; 84 79 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 83 DateInstance* asDateInstance(JSValue); 84 85 inline DateInstance* asDateInstance(JSValue value) 86 { 87 ASSERT(asObject(value)->inherits(DateInstance::info())); 88 return static_cast<DateInstance*>(asObject(value)); 89 } 90 90 91 91 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/DateInstanceCache.h
r167394 r173269 36 36 namespace JSC { 37 37 38 class DateInstanceData : public RefCounted<DateInstanceData> {39 public:40 static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); }38 class DateInstanceData : public RefCounted<DateInstanceData> { 39 public: 40 static PassRefPtr<DateInstanceData> create() { return adoptRef(new DateInstanceData); } 41 41 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; 46 46 47 private: 48 DateInstanceData() 49 : m_gregorianDateTimeCachedForMS(PNaN) 50 , m_gregorianDateTimeUTCCachedForMS(PNaN) 51 { 52 } 47 private: 48 DateInstanceData() 49 : m_gregorianDateTimeCachedForMS(PNaN) 50 , m_gregorianDateTimeUTCCachedForMS(PNaN) 51 { 52 } 53 }; 54 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(); 73 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; 53 85 }; 54 86 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)]; } 73 88 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 }; 91 91 92 92 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/DatePrototype.h
r156620 r173269 26 26 namespace JSC { 27 27 28 class ObjectPrototype;28 class ObjectPrototype; 29 29 30 class DatePrototype : public DateInstance {31 private:32 DatePrototype(VM&, Structure*);30 class DatePrototype : public DateInstance { 31 private: 32 DatePrototype(VM&, Structure*); 33 33 34 public:35 typedef DateInstance Base;34 public: 35 typedef DateInstance Base; 36 36 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&); 44 44 45 DECLARE_INFO;45 DECLARE_INFO; 46 46 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 } 51 51 52 protected:53 void finishCreation(VM&, JSGlobalObject*);54 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags;55 };52 protected: 53 void finishCreation(VM&, JSGlobalObject*); 54 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | DateInstance::StructureFlags; 55 }; 56 56 57 57 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/Error.h
r165640 r173269 31 31 namespace JSC { 32 32 33 class ExecState;34 class VM;35 class JSGlobalObject;36 class JSObject;37 class SourceCode;38 class Structure;33 class ExecState; 34 class VM; 35 class JSGlobalObject; 36 class JSObject; 37 class SourceCode; 38 class Structure; 39 39 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. 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&); 58 58 59 // Methods to add60 bool hasErrorInfo(ExecState*, JSObject* error);61 // ExecState wrappers.62 JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&);59 // Methods to add 60 bool hasErrorInfo(ExecState*, JSObject* error); 61 // ExecState wrappers. 62 JSObject* addErrorInfo(ExecState*, JSObject* error, int line, const SourceCode&); 63 63 64 // Methods to throw Errors.64 // Methods to throw Errors. 65 65 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. 67 JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*); 68 JS_EXPORT_PRIVATE JSObject* throwSyntaxError(ExecState*); 69 69 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. 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)); } 82 74 83 static void destroy(JSCell*); 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 } 84 82 85 public: 86 typedef InternalFunction Base; 83 static void destroy(JSCell*); 87 84 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 } 85 public: 86 typedef InternalFunction Base; 112 87 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 } 118 94 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 } 120 100 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 } 125 106 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 126 private: 127 String m_message; 128 }; 129 129 130 130 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ErrorConstructor.h
r156624 r173269 27 27 namespace JSC { 28 28 29 class ErrorPrototype;29 class ErrorPrototype; 30 30 31 class ErrorConstructor : public InternalFunction {32 public:33 typedef InternalFunction Base;31 class ErrorConstructor : public InternalFunction { 32 public: 33 typedef InternalFunction Base; 34 34 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 } 41 41 42 DECLARE_INFO;42 DECLARE_INFO; 43 43 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 } 48 48 49 protected:50 void finishCreation(VM&, ErrorPrototype*);49 protected: 50 void finishCreation(VM&, ErrorPrototype*); 51 51 52 private:53 ErrorConstructor(VM&, Structure*);54 static ConstructType getConstructData(JSCell*, ConstructData&);55 static CallType getCallData(JSCell*, CallData&);56 };52 private: 53 ErrorConstructor(VM&, Structure*); 54 static ConstructType getConstructData(JSCell*, ConstructData&); 55 static CallType getCallData(JSCell*, CallData&); 56 }; 57 57 58 58 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ErrorInstance.h
r154038 r173269 28 28 namespace JSC { 29 29 30 class ErrorInstance : public JSNonFinalObject {31 public:32 typedef JSNonFinalObject Base;30 class ErrorInstance : public JSNonFinalObject { 31 public: 32 typedef JSNonFinalObject Base; 33 33 34 DECLARE_INFO;34 DECLARE_INFO; 35 35 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 } 40 40 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 } 47 47 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 } 52 52 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; } 56 56 57 protected:58 explicit ErrorInstance(VM&, Structure*);57 protected: 58 explicit ErrorInstance(VM&, Structure*); 59 59 60 void finishCreation(VM&, const String&, Vector<StackFrame> = Vector<StackFrame>());60 void finishCreation(VM&, const String&, Vector<StackFrame> = Vector<StackFrame>()); 61 61 62 bool m_appendSourceToMessage;63 };62 bool m_appendSourceToMessage; 63 }; 64 64 65 65 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ErrorPrototype.h
r156620 r173269 26 26 namespace JSC { 27 27 28 class ObjectPrototype;28 class ObjectPrototype; 29 29 30 class ErrorPrototype : public ErrorInstance {31 public:32 typedef ErrorInstance Base;30 class ErrorPrototype : public ErrorInstance { 31 public: 32 typedef ErrorInstance Base; 33 33 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 } 42 40 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; 47 42 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 } 51 47 52 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ErrorInstance::StructureFlags; 48 protected: 49 ErrorPrototype(VM&, Structure*); 50 void finishCreation(VM&, JSGlobalObject*); 53 51 54 private: 55 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 56 }; 52 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ErrorInstance::StructureFlags; 53 54 private: 55 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 56 }; 57 57 58 58 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/FunctionConstructor.h
r156624 r173269 30 30 namespace JSC { 31 31 32 class FunctionPrototype;32 class FunctionPrototype; 33 33 34 class FunctionConstructor : public InternalFunction {35 public:36 typedef InternalFunction Base;34 class FunctionConstructor : public InternalFunction { 35 public: 36 typedef InternalFunction Base; 37 37 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 } 44 44 45 DECLARE_INFO;45 DECLARE_INFO; 46 46 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 } 51 51 52 private:53 FunctionConstructor(VM&, Structure*);54 void finishCreation(VM&, FunctionPrototype*);55 static ConstructType getConstructData(JSCell*, ConstructData&);56 static CallType getCallData(JSCell*, CallData&);57 };52 private: 53 FunctionConstructor(VM&, Structure*); 54 void finishCreation(VM&, FunctionPrototype*); 55 static ConstructType getConstructData(JSCell*, ConstructData&); 56 static CallType getCallData(JSCell*, CallData&); 57 }; 58 58 59 JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const String& sourceURL, const WTF::TextPosition&);60 JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&);59 JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const String& sourceURL, const WTF::TextPosition&); 60 JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&); 61 61 62 JS_EXPORT_PRIVATE JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, const String&, const WTF::TextPosition&);62 JS_EXPORT_PRIVATE JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, const String&, const WTF::TextPosition&); 63 63 64 64 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/FunctionPrototype.h
r156624 r173269 26 26 namespace JSC { 27 27 28 class FunctionPrototype : public InternalFunction {29 public:30 typedef InternalFunction Base;28 class FunctionPrototype : public InternalFunction { 29 public: 30 typedef InternalFunction Base; 31 31 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 } 45 38 46 DECLARE_INFO;39 void addFunctionProperties(ExecState*, JSGlobalObject*, JSFunction** callFunction, JSFunction** applyFunction); 47 40 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 } 50 45 51 private: 52 FunctionPrototype(VM&, Structure*); 53 static CallType getCallData(JSCell*, CallData&); 54 }; 46 DECLARE_INFO; 47 48 protected: 49 void finishCreation(VM&, const String& name); 50 51 private: 52 FunctionPrototype(VM&, Structure*); 53 static CallType getCallData(JSCell*, CallData&); 54 }; 55 55 56 56 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/GetterSetter.h
r172129 r173269 31 31 namespace JSC { 32 32 33 class JSObject;33 class JSObject; 34 34 35 // This is an internal value object which stores getter and setter functions36 // for a property. Instances of this class have the property that once a getter37 // or setter is set to a non-null value, then they cannot be changed. This means38 // that if a property holding a GetterSetter reference is constant-inferred and39 // that constant is observed to have a non-null setter (or getter) then we can40 // 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). 41 class GetterSetter : public JSCell { 42 friend class JIT; 43 43 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) 44 private: 45 GetterSetter(VM& vm) 46 : JSCell(vm, vm.getterSetterStructure.get()) 126 47 { 127 ASSERT_WITH_SECURITY_IMPLICATION(value.asCell()->isGetterSetter());128 return static_cast<GetterSetter*>(value.asCell());129 48 } 130 49 131 JSValue callGetter(ExecState*, JSValue base, JSValue getterSetter); 132 void callSetter(ExecState*, JSValue base, JSValue getterSetter, JSValue value, ECMAMode); 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) 126 { 127 ASSERT_WITH_SECURITY_IMPLICATION(value.asCell()->isGetterSetter()); 128 return static_cast<GetterSetter*>(value.asCell()); 129 } 130 131 JSValue callGetter(ExecState*, JSValue base, JSValue getterSetter); 132 void callSetter(ExecState*, JSValue base, JSValue getterSetter, JSValue, ECMAMode); 133 133 134 134 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/Identifier.h
r172129 r173269 30 30 namespace JSC { 31 31 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*);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*, 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 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*); 117 117 118 118 #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*); 121 121 #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*); 124 124 #endif 125 }; 126 127 template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(LChar) 128 { 129 ASSERT(maxSingleCharacterString == 0xff); 130 return true; 125 }; 126 127 template <> ALWAYS_INLINE bool Identifier::canUseSingleCharacterString(LChar) 128 { 129 ASSERT(maxSingleCharacterString == 0xff); 130 return true; 131 } 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); 131 145 } 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 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; 209 209 210 210 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/InitializeThreading.h
r165676 r173269 32 32 namespace JSC { 33 33 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. 36 JS_EXPORT_PRIVATE void initializeThreading(); 37 37 38 38 } -
trunk/Source/JavaScriptCore/runtime/InternalFunction.h
r156624 r173269 30 30 namespace JSC { 31 31 32 class FunctionPrototype;32 class FunctionPrototype; 33 33 34 class InternalFunction : public JSDestructibleObject {35 public:36 typedef JSDestructibleObject Base;34 class InternalFunction : public JSDestructibleObject { 35 public: 36 typedef JSDestructibleObject Base; 37 37 38 DECLARE_EXPORT_INFO;38 DECLARE_EXPORT_INFO; 39 39 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*); 43 43 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 } 48 48 49 protected:50 static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags;49 protected: 50 static const unsigned StructureFlags = ImplementsHasInstance | JSObject::StructureFlags; 51 51 52 JS_EXPORT_PRIVATE InternalFunction(VM&, Structure*);52 JS_EXPORT_PRIVATE InternalFunction(VM&, Structure*); 53 53 54 JS_EXPORT_PRIVATE void finishCreation(VM&, const String& name);54 JS_EXPORT_PRIVATE void finishCreation(VM&, const String& name); 55 55 56 static CallType getCallData(JSCell*, CallData&);57 };56 static CallType getCallData(JSCell*, CallData&); 57 }; 58 58 59 InternalFunction* asInternalFunction(JSValue);59 InternalFunction* asInternalFunction(JSValue); 60 60 61 inline InternalFunction* asInternalFunction(JSValue value)62 {63 ASSERT(asObject(value)->inherits(InternalFunction::info()));64 return static_cast<InternalFunction*>(asObject(value));65 }61 inline InternalFunction* asInternalFunction(JSValue value) 62 { 63 ASSERT(asObject(value)->inherits(InternalFunction::info())); 64 return static_cast<InternalFunction*>(asObject(value)); 65 } 66 66 67 67 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
r171939 r173269 31 31 namespace JSC { 32 32 33 class JSAPIValueWrapper : public JSCell {34 friend JSValue jsAPIValueWrapper(ExecState*, JSValue);35 public:36 typedef JSCell Base;33 class JSAPIValueWrapper : public JSCell { 34 friend JSValue jsAPIValueWrapper(ExecState*, JSValue); 35 public: 36 typedef JSCell Base; 37 37 38 JSValue value() const { return m_value.get(); }38 JSValue value() const { return m_value.get(); } 39 39 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 } 54 44 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; 62 46 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 } 68 54 69 WriteBarrier<Unknown> m_value; 70 }; 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 } 71 62 72 inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value) 63 private: 64 JSAPIValueWrapper(ExecState* exec) 65 : JSCell(exec->vm(), exec->vm().apiWrapperStructure.get()) 73 66 { 74 return JSAPIValueWrapper::create(exec, value);75 67 } 68 69 WriteBarrier<Unknown> m_value; 70 }; 71 72 inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value) 73 { 74 return JSAPIValueWrapper::create(exec, value); 75 } 76 76 77 77 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSFunction.h
r171939 r173269 33 33 namespace JSC { 34 34 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; 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; 46 } 47 48 JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*); 49 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; 57 58 public: 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; 46 69 } 47 70 48 JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*);71 static JSFunction* createBuiltinFunction(VM&, FunctionExecutable*, JSGlobalObject*); 49 72 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*); 57 74 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*); 60 78 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&); 62 99 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(); } 78 101 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; 99 105 100 ExecutableBase* executable() const { return m_executable.get(); }106 JS_EXPORT_PRIVATE const SourceCode* sourceCode() const; 101 107 102 // To call either of these methods include Executable.h 103 bool isHostFunction() const; 104 FunctionExecutable* jsExecutable() const; 108 DECLARE_EXPORT_INFO; 105 109 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 } 107 115 108 DECLARE_EXPORT_INFO; 116 NativeFunction nativeFunction(); 117 NativeFunction nativeConstructor(); 109 118 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&); 115 121 116 NativeFunction nativeFunction(); 117 NativeFunction nativeConstructor(); 122 static inline ptrdiff_t offsetOfScopeChain() 123 { 124 return OBJECT_OFFSETOF(JSFunction, m_scope); 125 } 118 126 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 } 121 131 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 } 126 136 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 } 131 143 132 static inline ptrdiff_t offsetOfAllocationProfile() 133 { 134 return OBJECT_OFFSETOF(JSFunction, m_allocationProfile); 135 } 144 Structure* allocationStructure() { return m_allocationProfile.structure(); } 136 145 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 } 145 150 146 InlineWatchpointSet& allocationProfileWatchpointSet() 147 { 148 return m_allocationProfileWatchpoint; 149 } 151 bool isHostOrBuiltinFunction() const; 152 bool isBuiltinFunction() const; 153 JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const; 150 154 151 bool isHostOrBuiltinFunction() const; 152 bool isBuiltinFunction() const; 153 JS_EXPORT_PRIVATE bool isHostFunctionNonInline() const; 155 protected: 156 const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesGetPropertyNames | JSObject::StructureFlags; 154 157 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*); 157 160 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; 163 163 164 ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity);164 ObjectAllocationProfile* createAllocationProfile(ExecState*, size_t inlineCapacity); 165 165 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); 169 169 170 static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&);170 static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); 171 171 172 static bool deleteProperty(JSCell*, ExecState*, PropertyName);172 static bool deleteProperty(JSCell*, ExecState*, PropertyName); 173 173 174 static void visitChildren(JSCell*, SlotVisitor&);174 static void visitChildren(JSCell*, SlotVisitor&); 175 175 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); 176 private: 177 friend class LLIntOffsetsExtractor; 183 178 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 }; 189 189 190 190 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSLock.h
r165999 r173269 32 32 namespace JSC { 33 33 34 // To make it safe to use JavaScript on multiple threads, it is35 // important to lock before doing anything that allocates a36 // JavaScript data structure or that interacts with shared state37 // such as the protect count hash table. The simplest way to lock38 // is to create a local JSLockHolder object in the scope where the lock39 // must be held and pass it the context that requires protection.40 // The lock is recursive so nesting is ok. The JSLock41 // object also acts as a convenience short-hand for running important42 // 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. 43 43 44 // To avoid deadlock, sometimes it is necessary to temporarily45 // release the lock. Since it is recursive you actually have to46 // release all locks held by your thread. This is safe to do if47 // you are executing code that doesn't require the lock, and you48 // reacquire the right number of locks at the end. You can do this49 // by constructing a locally scoped JSLock::DropAllLocks object. The50 // DropAllLocks object takes care to release the JSLock only if your51 // 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. 52 52 53 class ExecState;54 class VM;53 class ExecState; 54 class VM; 55 55 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. 58 class GlobalJSLock { 59 WTF_MAKE_NONCOPYABLE(GlobalJSLock); 60 public: 61 JS_EXPORT_PRIVATE GlobalJSLock(); 62 JS_EXPORT_PRIVATE ~GlobalJSLock(); 63 64 static void initialize(); 65 private: 66 static std::mutex* s_sharedInstanceMutex; 67 }; 68 69 class JSLockHolder { 70 public: 71 JS_EXPORT_PRIVATE JSLockHolder(VM*); 72 JS_EXPORT_PRIVATE JSLockHolder(VM&); 73 JS_EXPORT_PRIVATE JSLockHolder(ExecState*); 74 75 JS_EXPORT_PRIVATE ~JSLockHolder(); 76 private: 77 void init(); 78 79 RefPtr<VM> m_vm; 80 }; 81 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); 60 111 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(); 63 116 64 static void initialize(); 117 void setDropDepth(unsigned depth) { m_dropDepth = depth; } 118 unsigned dropDepth() const { return m_dropDepth; } 119 65 120 private: 66 static std::mutex* s_sharedInstanceMutex; 121 intptr_t m_droppedLockCount; 122 RefPtr<VM> m_vm; 123 unsigned m_dropDepth; 67 124 }; 68 125 69 class JSLockHolder { 70 public: 71 JS_EXPORT_PRIVATE JSLockHolder(VM*); 72 JS_EXPORT_PRIVATE JSLockHolder(VM&); 73 JS_EXPORT_PRIVATE JSLockHolder(ExecState*); 126 private: 127 void lock(intptr_t lockCount); 128 void unlock(intptr_t unlockCount); 74 129 75 JS_EXPORT_PRIVATE ~JSLockHolder(); 76 private: 77 void init(); 130 void didAcquireLock(); 131 void willReleaseLock(); 78 132 79 RefPtr<VM> m_vm;80 };133 unsigned dropAllLocks(DropAllLocks*); 134 void grabAllLocks(DropAllLocks*, unsigned lockCount); 81 135 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 }; 144 144 145 145 } // namespace -
trunk/Source/JavaScriptCore/runtime/JSNotAnObject.h
r165676 r173269 34 34 namespace JSC { 35 35 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. 39 class JSNotAnObject : public JSNonFinalObject { 40 private: 41 explicit JSNotAnObject(VM& vm) 42 : JSNonFinalObject(vm, vm.notAnObjectStructure.get()) 43 { 44 } 48 45 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 } 46 public: 47 typedef JSNonFinalObject Base; 55 48 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 } 60 55 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 } 62 60 63 private: 64 65 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | JSObject::StructureFlags; 61 DECLARE_INFO; 66 62 67 // JSValue methods 68 static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); 63 private: 69 64 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; 73 66 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); 76 69 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&); 79 73 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 }; 82 82 83 83 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSONObject.h
r159377 r173269 31 31 namespace JSC { 32 32 33 class Stringifier;33 class Stringifier; 34 34 35 class JSONObject : public JSNonFinalObject {36 public:37 typedef JSNonFinalObject Base;35 class JSONObject : public JSNonFinalObject { 36 public: 37 typedef JSNonFinalObject Base; 38 38 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 } 52 45 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 } 56 50 57 private: 58 JSONObject(VM&, Structure*); 59 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 51 DECLARE_INFO; 60 52 61 }; 53 protected: 54 void finishCreation(VM&); 55 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; 62 56 63 JS_EXPORT_PRIVATE JSValue JSONParse(ExecState*, const String&); 64 JS_EXPORT_PRIVATE String JSONStringify(ExecState*, JSValue, unsigned indent); 57 private: 58 JSONObject(VM&, Structure*); 59 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 60 }; 65 61 66 void escapeStringToBuilder(StringBuilder&, const String&); 62 JS_EXPORT_PRIVATE JSValue JSONParse(ExecState*, const String&); 63 JS_EXPORT_PRIVATE String JSONStringify(ExecState*, JSValue, unsigned indent); 64 65 void escapeStringToBuilder(StringBuilder&, const String&); 67 66 68 67 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSString.h
r172727 r173269 34 34 namespace JSC { 35 35 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 { 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 { 65 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) 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 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; 209 210 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); 219 }; 220 221 class JSRopeString : public JSString { 222 friend class JSString; 223 224 friend JSRopeString* jsStringBuilder(VM*); 225 226 class RopeBuilder { 65 227 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) 85 232 { 86 233 } 87 234 88 JSString(VM& vm) 89 : JSCell(vm, vm.stringStructure.get()) 90 , m_flags(0) 235 bool append(JSString* jsString) 91 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; 92 245 } 93 246 94 void finishCreation(VM& vm, size_t length)247 JSRopeString* release() 95 248 { 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; 101 253 } 102 254 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; } 209 256 210 257 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; 219 263 }; 220 264 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 { 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 { 434 return vm->smallStrings.emptyString(); 435 } 436 437 ALWAYS_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 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())); 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 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) 434 513 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); 439 516 if (c <= maxSingleCharacterString) 440 517 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 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) { 448 542 UChar c = s.characterAt(offset); 449 543 if (c <= maxSingleCharacterString) 450 544 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 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 } 699 699 700 700 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSTypeInfo.h
r171939 r173269 35 35 namespace JSC { 36 36 37 class LLIntOffsetsExtractor;37 class LLIntOffsetsExtractor; 38 38 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;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; 46 46 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;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; 52 52 53 class TypeInfo {54 public:55 typedef uint8_t InlineTypeFlags;56 typedef uint8_t OutOfLineTypeFlags;53 class TypeInfo { 54 public: 55 typedef uint8_t InlineTypeFlags; 56 typedef uint8_t OutOfLineTypeFlags; 57 57 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 } 74 62 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 } 81 74 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; } 96 81 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); } 101 96 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 } 106 101 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 } 109 106 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; } 115 109 116 unsigned char m_type; 117 unsigned char m_flags; 118 unsigned char m_flags2; 119 }; 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); } 115 116 unsigned char m_type; 117 unsigned char m_flags; 118 unsigned char m_flags2; 119 }; 120 120 121 121 } -
trunk/Source/JavaScriptCore/runtime/JSWrapperObject.h
r171939 r173269 27 27 namespace JSC { 28 28 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. 31 class JSWrapperObject : public JSDestructibleObject { 32 public: 33 typedef JSDestructibleObject Base; 34 34 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) 70 36 { 37 ASSERT_UNUSED(inlineCapacity, !inlineCapacity); 38 return sizeof(JSWrapperObject); 71 39 } 72 40 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()); 76 47 } 77 48 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() 79 51 { 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 83 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) 70 { 71 } 72 73 inline JSValue JSWrapperObject::internalValue() const 74 { 75 return m_internalValue.get(); 76 } 77 78 inline void JSWrapperObject::setInternalValue(VM& vm, JSValue value) 79 { 80 ASSERT(value); 81 ASSERT(!value.isObject()); 82 m_internalValue.set(vm, this, value); 83 } 84 84 85 85 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/Lookup.h
r171824 r173269 34 34 35 35 namespace JSC { 36 struct CompactHashIndex { 37 const int16_t value; 38 const int16_t next; 36 37 struct 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) 44 typedef PropertySlot::GetValueFunc GetFunction; 45 typedef PutPropertySlot::PutValueFunc PutFunction; 46 typedef FunctionExecutable* (*BuiltinGenerator)(VM&); 47 48 // Hash table generated by the create_hash_table script. 49 struct 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 71 struct 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; 39 172 }; 40 173 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 185 private: 186 // Convert the hash table keys to identifiers. 187 JS_EXPORT_PRIVATE void createTable() const; 188 }; 189 190 JS_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 */ 198 template <class ThisImp, class ParentImp> 199 inline 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())); 214 211 return true; 215 212 } 216 213 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 */ 223 template <class ParentImp> 224 inline bool getStaticFunctionSlot(ExecState* exec, const HashTable& table, JSObject* thisObj, PropertyName propertyName, PropertySlot& slot) 225 { 226 if (ParentImp::getOwnPropertySlot(thisObj, exec, propertyName, slot)) 255 227 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 */ 240 template <class ThisImp, class ParentImp> 241 inline 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())); 284 252 return true; 285 253 } 286 254 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 259 inline 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 */ 277 inline 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 288 template<unsigned numberOfValues> 289 inline 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 } 321 322 322 323 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/MathObject.h
r156679 r173269 26 26 namespace JSC { 27 27 28 class MathObject : public JSNonFinalObject {29 private:30 MathObject(VM&, Structure*);28 class MathObject : public JSNonFinalObject { 29 private: 30 MathObject(VM&, Structure*); 31 31 32 public:33 typedef JSNonFinalObject Base;32 public: 33 typedef JSNonFinalObject Base; 34 34 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 } 41 41 42 DECLARE_INFO;42 DECLARE_INFO; 43 43 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 } 48 48 49 protected:50 void finishCreation(VM&, JSGlobalObject*);51 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags;52 };49 protected: 50 void finishCreation(VM&, JSGlobalObject*); 51 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | JSObject::StructureFlags; 52 }; 53 53 54 54 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/NativeErrorConstructor.h
r171939 r173269 27 27 namespace JSC { 28 28 29 class ErrorInstance;30 class FunctionPrototype;31 class NativeErrorPrototype;29 class ErrorInstance; 30 class FunctionPrototype; 31 class NativeErrorPrototype; 32 32 33 class NativeErrorConstructor : public InternalFunction {34 public:35 typedef InternalFunction Base;33 class NativeErrorConstructor : public InternalFunction { 34 public: 35 typedef InternalFunction Base; 36 36 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 } 45 43 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; 50 45 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 } 52 50 53 protected: 54 void finishCreation(VM&, JSGlobalObject*, Structure* prototypeStructure, const String& name); 51 Structure* errorStructure() { return m_errorStructure.get(); } 55 52 56 private: 57 NativeErrorConstructor(VM&, Structure*); 58 static ConstructType getConstructData(JSCell*, ConstructData&); 59 static CallType getCallData(JSCell*, CallData&); 60 static void visitChildren(JSCell*, SlotVisitor&); 53 protected: 54 void finishCreation(VM&, JSGlobalObject*, Structure* prototypeStructure, const String& name); 61 55 62 WriteBarrier<Structure> m_errorStructure; 63 }; 56 private: 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 }; 64 64 65 65 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/NativeErrorPrototype.h
r156620 r173269 25 25 26 26 namespace JSC { 27 class NativeErrorConstructor;28 27 29 class NativeErrorPrototype : public ErrorPrototype { 30 private: 31 NativeErrorPrototype(VM&, Structure*); 32 33 public: 34 typedef ErrorPrototype Base; 28 class NativeErrorConstructor; 35 29 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 } 30 class NativeErrorPrototype : public ErrorPrototype { 31 private: 32 NativeErrorPrototype(VM&, Structure*); 42 33 43 protected: 44 void finishCreation(VM&, JSGlobalObject*, const String& nameAndMessage, NativeErrorConstructor*); 45 }; 34 public: 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 44 protected: 45 void finishCreation(VM&, JSGlobalObject*, const String& nameAndMessage, NativeErrorConstructor*); 46 }; 46 47 47 48 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/NumberConstructor.h
r162740 r173269 26 26 namespace JSC { 27 27 28 class NumberPrototype;28 class NumberPrototype; 29 29 30 class NumberConstructor : public InternalFunction {31 public:32 typedef InternalFunction Base;30 class NumberConstructor : public InternalFunction { 31 public: 32 typedef InternalFunction Base; 33 33 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 } 40 40 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; 43 43 44 DECLARE_INFO;44 DECLARE_INFO; 45 45 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 } 50 50 51 enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };51 enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue }; 52 52 53 protected:54 void finishCreation(VM&, NumberPrototype*);55 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;53 protected: 54 void finishCreation(VM&, NumberPrototype*); 55 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags; 56 56 57 private:58 NumberConstructor(VM&, Structure*);59 static ConstructType getConstructData(JSCell*, ConstructData&);60 static CallType getCallData(JSCell*, CallData&);61 };57 private: 58 NumberConstructor(VM&, Structure*); 59 static ConstructType getConstructData(JSCell*, ConstructData&); 60 static CallType getCallData(JSCell*, CallData&); 61 }; 62 62 63 63 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/NumberObject.h
r154038 r173269 26 26 namespace JSC { 27 27 28 class NumberObject : public JSWrapperObject {29 protected:30 NumberObject(VM&, Structure*);31 void finishCreation(VM&);28 class NumberObject : public JSWrapperObject { 29 protected: 30 NumberObject(VM&, Structure*); 31 void finishCreation(VM&); 32 32 33 public:34 typedef JSWrapperObject Base;33 public: 34 typedef JSWrapperObject Base; 35 35 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 } 42 42 43 DECLARE_EXPORT_INFO;43 DECLARE_EXPORT_INFO; 44 44 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 }; 50 50 51 JS_EXPORT_PRIVATE NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue);51 JS_EXPORT_PRIVATE NumberObject* constructNumber(ExecState*, JSGlobalObject*, JSValue); 52 52 53 53 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/NumberPrototype.h
r156620 r173269 26 26 namespace JSC { 27 27 28 class NumberPrototype : public NumberObject {29 public:30 typedef NumberObject Base;28 class NumberPrototype : public NumberObject { 29 public: 30 typedef NumberObject Base; 31 31 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 } 40 38 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; 45 40 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 } 49 45 50 private: 51 NumberPrototype(VM&, Structure*); 52 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 53 }; 46 protected: 47 void finishCreation(VM&, JSGlobalObject*); 48 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | NumberObject::StructureFlags; 49 50 private: 51 NumberPrototype(VM&, Structure*); 52 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 53 }; 54 54 55 55 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/NumericStrings.h
r160344 r173269 33 33 namespace JSC { 34 34 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); 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()) 44 41 return entry.value; 45 } 42 entry.key = d; 43 entry.value = String::numberToStringECMAScript(d); 44 return entry.value; 45 } 46 46 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()) 56 53 return entry.value; 57 } 54 entry.key = i; 55 entry.value = String::number(i); 56 return entry.value; 57 } 58 58 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()) 68 65 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 } 70 private: 71 static const size_t cacheSize = 64; 72 72 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 }; 78 78 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 } 89 89 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 }; 95 95 96 96 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h
r156624 r173269 28 28 namespace JSC { 29 29 30 class ObjectPrototype;30 class ObjectPrototype; 31 31 32 class ObjectConstructor : public InternalFunction {33 public:34 typedef InternalFunction Base;32 class ObjectConstructor : public InternalFunction { 33 public: 34 typedef InternalFunction Base; 35 35 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) 63 37 { 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; 65 41 } 66 42 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) 68 48 { 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()); 74 50 } 75 51 76 inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype) 77 { 78 return constructEmptyObject(exec, prototype, JSFinalObject::defaultInlineCapacity()); 79 } 52 protected: 53 void finishCreation(VM&, ObjectPrototype*); 54 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags; 80 55 81 inline JSObject* constructEmptyObject(ExecState* exec) 82 { 83 return constructEmptyObject(exec, exec->lexicalGlobalObject()->objectPrototype()); 84 } 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) 63 { 64 return JSFinalObject::create(exec, structure); 65 } 66 67 inline 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 76 inline JSObject* constructEmptyObject(ExecState* exec, JSObject* prototype) 77 { 78 return constructEmptyObject(exec, prototype, JSFinalObject::defaultInlineCapacity()); 79 } 80 81 inline JSObject* constructEmptyObject(ExecState* exec) 82 { 83 return constructEmptyObject(exec, exec->lexicalGlobalObject()->objectPrototype()); 84 } 85 85 86 86 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/ObjectPrototype.h
r156680 r173269 26 26 namespace JSC { 27 27 28 class ObjectPrototype : public JSNonFinalObject {29 public:30 typedef JSNonFinalObject Base;28 class ObjectPrototype : public JSNonFinalObject { 29 public: 30 typedef JSNonFinalObject Base; 31 31 32 static ObjectPrototype* create(VM&, JSGlobalObject*, Structure*);32 static ObjectPrototype* create(VM&, JSGlobalObject*, Structure*); 33 33 34 DECLARE_INFO;34 DECLARE_INFO; 35 35 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 } 40 40 41 protected:42 void finishCreation(VM&, JSGlobalObject*);41 protected: 42 void finishCreation(VM&, JSGlobalObject*); 43 43 44 private:45 ObjectPrototype(VM&, Structure*);46 };44 private: 45 ObjectPrototype(VM&, Structure*); 46 }; 47 47 48 JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*);48 JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*); 49 49 50 50 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/PropertyDescriptor.h
r169703 r173269 30 30 31 31 namespace JSC { 32 class GetterSetter;33 32 34 // See ES5.1 9.12 35 bool sameValue(ExecState*, JSValue, JSValue); 33 class GetterSetter; 36 34 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 36 bool sameValue(ExecState*, JSValue, JSValue); 84 37 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 }; 38 class PropertyDescriptor { 39 public: 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 86 private: 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 96 98 } 97 99 -
trunk/Source/JavaScriptCore/runtime/Protect.h
r140718 r173269 28 28 namespace JSC { 29 29 30 inline void gcProtect(JSCell* val)31 {32 Heap::heap(val)->protect(val);33 }30 inline void gcProtect(JSCell* val) 31 { 32 Heap::heap(val)->protect(val); 33 } 34 34 35 inline void gcUnprotect(JSCell* val)36 {37 Heap::heap(val)->unprotect(val);38 }35 inline void gcUnprotect(JSCell* val) 36 { 37 Heap::heap(val)->unprotect(val); 38 } 39 39 40 inline void gcProtectNullTolerant(JSCell* val)41 {42 if (val)43 gcProtect(val);44 }40 inline void gcProtectNullTolerant(JSCell* val) 41 { 42 if (val) 43 gcProtect(val); 44 } 45 45 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 } 46 inline void gcUnprotectNullTolerant(JSCell* val) 47 { 48 if (val) 49 gcUnprotect(val); 50 } 57 51 58 inline void gcUnprotect(JSValue value) 59 { 60 if (value && value.isCell()) 61 gcUnprotect(value.asCell()); 62 } 52 inline void gcProtect(JSValue value) 53 { 54 if (value && value.isCell()) 55 gcProtect(value.asCell()); 56 } 57 58 inline void gcUnprotect(JSValue value) 59 { 60 if (value && value.isCell()) 61 gcUnprotect(value.asCell()); 62 } 63 63 64 64 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/PutPropertySlot.h
r173100 r173269 34 34 namespace JSC { 35 35 36 class JSObject;37 class JSFunction;36 class JSObject; 37 class JSFunction; 38 38 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);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); 44 44 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 } 54 54 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 } 61 61 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 } 68 68 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 } 82 75 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 } 87 82 88 PutValueFunc customSetter() const { return m_putFunction; } 83 void setThisValue(JSValue thisValue) 84 { 85 m_thisValue = thisValue; 86 } 89 87 90 Context context() const { return static_cast<Context>(m_context); }88 PutValueFunc customSetter() const { return m_putFunction; } 91 89 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); } 95 91 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; } 100 95 101 PropertyOffset cachedOffset() const102 {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; } 105 100 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 } 114 105 115 }; 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; 114 }; 116 115 117 116 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/RegExp.h
r171660 r173269 38 38 namespace JSC { 39 39 40 struct RegExpRepresentation;41 class VM;40 struct RegExpRepresentation; 41 class VM; 42 42 43 JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);43 JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&); 44 44 45 class RegExp : public JSCell {46 public:47 typedef JSCell Base;45 class RegExp : public JSCell { 46 public: 47 typedef JSCell Base; 48 48 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*); 53 53 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; } 57 57 58 const String& pattern() const { return m_patternString; }58 const String& pattern() const { return m_patternString; } 59 59 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; } 62 62 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; } 66 66 67 bool hasCode()68 {69 return m_state != NotCompiled;70 }67 bool hasCode() 68 { 69 return m_state != NotCompiled; 70 } 71 71 72 void invalidateCode();73 72 void invalidateCode(); 73 74 74 #if ENABLE(REGEXP_TRACING) 75 void printTraceData();75 void printTraceData(); 76 76 #endif 77 77 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 } 84 82 85 RegExpKey key() { return RegExpKey(m_flags, m_patternString); }83 DECLARE_INFO; 86 84 87 protected: 88 static const unsigned StructureFlags = StructureIsImmortal; 85 RegExpKey key() { return RegExpKey(m_flags, m_patternString); } 89 86 90 void finishCreation(VM&); 87 protected: 88 static const unsigned StructureFlags = StructureIsImmortal; 91 89 92 private: 93 friend class RegExpCache; 94 RegExp(VM&, const String&, RegExpFlags); 90 void finishCreation(VM&); 95 91 96 static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags); 92 private: 93 friend class RegExpCache; 94 RegExp(VM&, const String&, RegExpFlags); 97 95 98 enum RegExpState { 99 ParseError, 100 JITCode, 101 ByteCode, 102 NotCompiled 103 } m_state; 96 static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags); 104 97 105 void compile(VM*, Yarr::YarrCharSize); 106 void compileIfNecessary(VM&, Yarr::YarrCharSize); 98 enum RegExpState { 99 ParseError, 100 JITCode, 101 ByteCode, 102 NotCompiled 103 }; 107 104 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); 110 112 111 113 #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); 113 115 #endif 114 116 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; 119 121 #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; 126 128 #endif 127 129 128 130 #if ENABLE(YARR_JIT) 129 Yarr::YarrCodeBlock m_regExpJITCode;131 Yarr::YarrCodeBlock m_regExpJITCode; 130 132 #endif 131 OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;132 };133 OwnPtr<Yarr::BytecodePattern> m_regExpBytecode; 134 }; 133 135 134 136 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/RegExpCachedResult.h
r148696 r173269 31 31 namespace JSC { 32 32 33 class JSString;34 class RegExpMatchesArray;33 class JSString; 34 class RegExpMatchesArray; 35 35 36 // RegExpCachedResult is used to track the cached results of the last37 // match, stores on the RegExp constructor (e.g. $&, $_, $1, $2 ...).38 // These values will be lazily generated on demand, so the cached result39 // may be in a lazy or reified state. A lazy state is indicated by a40 // value of m_result indicating a successful match, and a reified state41 // is indicated by setting m_result to MatchResult::failed().42 // Following a successful match, m_result, m_lastInput and m_lastRegExp43 // can be used to reify the results from the match, following reification44 // 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. 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 } 53 53 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 } 60 60 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*); 63 63 64 JSString* input()65 {66 // If m_result showas a match then we're in a lazy state, so m_lastInput67 // is the most recent value of the input property. If not then we have68 // 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 } 71 71 72 void visitChildren(SlotVisitor&);72 void visitChildren(SlotVisitor&); 73 73 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 };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 }; 81 81 82 82 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/RegExpConstructor.h
r171939 r173269 31 31 namespace JSC { 32 32 33 class RegExpPrototype;33 class RegExpPrototype; 34 34 35 class RegExpConstructor : public InternalFunction {36 public:37 typedef InternalFunction Base;35 class RegExpConstructor : public InternalFunction { 36 public: 37 typedef InternalFunction Base; 38 38 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) 91 40 { 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; 94 44 } 95 45 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) 102 47 { 103 int position = regExp->match(vm, input, startOffset, m_ovector); 48 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 49 } 104 50 105 if (ovector) 106 *ovector = m_ovector.data(); 51 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 107 52 108 if (position == -1) 109 return MatchResult::failed(); 53 DECLARE_INFO; 110 54 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); 115 57 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; } 117 60 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 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) 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 */ 101 ALWAYS_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 } 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 } 127 127 128 128 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
r171939 r173269 27 27 namespace JSC { 28 28 29 class RegExpMatchesArray : public JSArray {30 private:31 RegExpMatchesArray(VM&, Butterfly*, JSGlobalObject*, JSString*, RegExp*, MatchResult);29 class RegExpMatchesArray : public JSArray { 30 private: 31 RegExpMatchesArray(VM&, Butterfly*, JSGlobalObject*, JSString*, RegExp*, MatchResult); 32 32 33 enum ReifiedState { ReifiedNone, ReifiedMatch, ReifiedAll };33 enum ReifiedState { ReifiedNone, ReifiedMatch, ReifiedAll }; 34 34 35 public:36 typedef JSArray Base;35 public: 36 typedef JSArray Base; 37 37 38 static RegExpMatchesArray* create(ExecState*, JSString*, RegExp*, MatchResult);38 static RegExpMatchesArray* create(ExecState*, JSString*, RegExp*, MatchResult); 39 39 40 JSString* leftContext(ExecState*);41 JSString* rightContext(ExecState*);40 JSString* leftContext(ExecState*); 41 JSString* rightContext(ExecState*); 42 42 43 DECLARE_INFO;43 DECLARE_INFO; 44 44 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 } 49 49 50 static void visitChildren(JSCell*, SlotVisitor&);50 static void visitChildren(JSCell*, SlotVisitor&); 51 51 52 protected:53 void finishCreation(VM&);52 protected: 53 void finishCreation(VM&); 54 54 55 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;55 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags; 56 56 57 private:58 ALWAYS_INLINE void reifyAllPropertiesIfNecessary(ExecState* exec)59 {60 if (m_state != ReifiedAll)61 reifyAllProperties(exec);62 }57 private: 58 ALWAYS_INLINE void reifyAllPropertiesIfNecessary(ExecState* exec) 59 { 60 if (m_state != ReifiedAll) 61 reifyAllProperties(exec); 62 } 63 63 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 } 69 69 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) 73 81 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 } 76 86 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 } 86 93 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 } 100 100 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 } 107 107 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 } 114 114 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 } 121 121 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 } 128 128 129 void reifyAllProperties(ExecState*);130 void reifyMatchProperty(ExecState*);129 void reifyAllProperties(ExecState*); 130 void reifyMatchProperty(ExecState*); 131 131 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; 136 136 }; 137 137 -
trunk/Source/JavaScriptCore/runtime/RegExpObject.h
r172176 r173269 27 27 namespace JSC { 28 28 29 class RegExpObject : public JSNonFinalObject {30 public:31 typedef JSNonFinalObject Base;29 class RegExpObject : public JSNonFinalObject { 30 public: 31 typedef JSNonFinalObject Base; 32 32 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 } 39 39 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(); } 42 42 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)) 45 47 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 } 62 62 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*); 65 65 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&); 68 68 69 DECLARE_EXPORT_INFO;69 DECLARE_EXPORT_INFO; 70 70 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 } 75 75 76 protected:77 JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*);78 JS_EXPORT_PRIVATE void finishCreation(VM&);76 protected: 77 JS_EXPORT_PRIVATE RegExpObject(VM&, Structure*, RegExp*); 78 JS_EXPORT_PRIVATE void finishCreation(VM&); 79 79 80 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags;80 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | Base::StructureFlags; 81 81 82 static void visitChildren(JSCell*, SlotVisitor&);82 static void visitChildren(JSCell*, SlotVisitor&); 83 83 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); 89 89 90 private:91 MatchResult match(ExecState*, JSString*);90 private: 91 MatchResult match(ExecState*, JSString*); 92 92 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 }; 97 97 98 RegExpObject* asRegExpObject(JSValue);98 RegExpObject* asRegExpObject(JSValue); 99 99 100 inline RegExpObject* asRegExpObject(JSValue value)101 {102 ASSERT(asObject(value)->inherits(RegExpObject::info()));103 return static_cast<RegExpObject*>(asObject(value));104 }100 inline RegExpObject* asRegExpObject(JSValue value) 101 { 102 ASSERT(asObject(value)->inherits(RegExpObject::info())); 103 return static_cast<RegExpObject*>(asObject(value)); 104 } 105 105 106 106 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.h
r156668 r173269 27 27 namespace JSC { 28 28 29 class RegExpPrototype : public RegExpObject {30 public:31 typedef RegExpObject Base;29 class RegExpPrototype : public RegExpObject { 30 public: 31 typedef RegExpObject Base; 32 32 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 } 41 39 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; 46 41 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 } 50 46 51 private: 52 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 53 }; 47 protected: 48 RegExpPrototype(VM&, Structure*, RegExp*); 49 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | RegExpObject::StructureFlags; 50 51 private: 52 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 53 }; 54 54 55 55 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/SmallStrings.h
r169316 r173269 48 48 namespace JSC { 49 49 50 class HeapRootVisitor;51 class VM;52 class JSString;53 class SmallStringsStorage;54 class SlotVisitor;50 class HeapRootVisitor; 51 class VM; 52 class JSString; 53 class SmallStringsStorage; 54 class SlotVisitor; 55 55 56 static const unsigned maxSingleCharacterString = 0xFF;56 static const unsigned maxSingleCharacterString = 0xFF; 57 57 58 class SmallStrings {59 WTF_MAKE_NONCOPYABLE(SmallStrings);60 public:61 SmallStrings();62 ~SmallStrings();58 class SmallStrings { 59 WTF_MAKE_NONCOPYABLE(SmallStrings); 60 public: 61 SmallStrings(); 62 ~SmallStrings(); 63 63 64 JSString* emptyString()65 {66 return m_emptyString;67 }64 JSString* emptyString() 65 { 66 return m_emptyString; 67 } 68 68 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 } 73 73 74 JS_EXPORT_PRIVATE WTF::StringImpl* singleCharacterStringRep(unsigned char character);74 JS_EXPORT_PRIVATE WTF::StringImpl* singleCharacterStringRep(unsigned char character); 75 75 76 JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; }76 JSString** singleCharacterStrings() { return &m_singleCharacterStrings[0]; } 77 77 78 void initializeCommonStrings(VM&);79 void visitStrongReferences(SlotVisitor&);78 void initializeCommonStrings(VM&); 79 void visitStrongReferences(SlotVisitor&); 80 80 81 81 #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) 87 87 #undef JSC_COMMON_STRINGS_ACCESSOR_DEFINITION 88 88 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; } 91 91 92 private:93 static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1;92 private: 93 static const unsigned singleCharacterStringCount = maxSingleCharacterString + 1; 94 94 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); 97 97 98 void initialize(VM* vm, JSString*& string, const char* value) const;98 void initialize(VM*, JSString*&, const char* value) const; 99 99 100 JSString* m_emptyString;100 JSString* m_emptyString; 101 101 #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) 103 103 #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 }; 109 109 110 110 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/StringConstructor.h
r156624 r173269 26 26 namespace JSC { 27 27 28 class StringPrototype;28 class StringPrototype; 29 29 30 class StringConstructor : public InternalFunction {31 public:32 typedef InternalFunction Base;30 class StringConstructor : public InternalFunction { 31 public: 32 typedef InternalFunction Base; 33 33 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 } 40 40 41 DECLARE_INFO;41 DECLARE_INFO; 42 42 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 } 47 47 48 protected:49 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags;48 protected: 49 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | InternalFunction::StructureFlags; 50 50 51 private:52 StringConstructor(VM&, Structure*);53 void finishCreation(VM&, StringPrototype*);54 static ConstructType getConstructData(JSCell*, ConstructData&);55 static CallType getCallData(JSCell*, CallData&);51 private: 52 StringConstructor(VM&, Structure*); 53 void finishCreation(VM&, StringPrototype*); 54 static ConstructType getConstructData(JSCell*, ConstructData&); 55 static CallType getCallData(JSCell*, CallData&); 56 56 57 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);58 };57 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); 58 }; 59 59 60 JSCell* JSC_HOST_CALL stringFromCharCode(ExecState*, int32_t);60 JSCell* JSC_HOST_CALL stringFromCharCode(ExecState*, int32_t); 61 61 62 62 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/StringObject.h
r171391 r173269 27 27 namespace JSC { 28 28 29 class StringObject : public JSWrapperObject {30 public:31 typedef JSWrapperObject Base;29 class StringObject : public JSWrapperObject { 30 public: 31 typedef JSWrapperObject Base; 32 32 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*); 47 47 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&); 50 50 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); 53 53 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); 58 58 59 DECLARE_EXPORT_INFO;59 DECLARE_EXPORT_INFO; 60 60 61 JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}61 JSString* internalValue() const { return asString(JSWrapperObject::internalValue());} 62 62 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) 77 64 { 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()); 80 66 } 81 67 82 JS_EXPORT_PRIVATE StringObject* constructString(VM&, JSGlobalObject*, JSValue); 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) 77 { 78 ASSERT(asObject(value)->inherits(StringObject::info())); 79 return static_cast<StringObject*>(asObject(value)); 80 } 81 82 JS_EXPORT_PRIVATE StringObject* constructString(VM&, JSGlobalObject*, JSValue); 83 83 84 84 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/StringPrototype.h
r156620 r173269 26 26 namespace JSC { 27 27 28 class ObjectPrototype;28 class ObjectPrototype; 29 29 30 class StringPrototype : public StringObject {31 private:32 StringPrototype(VM&, Structure*);30 class StringPrototype : public StringObject { 31 private: 32 StringPrototype(VM&, Structure*); 33 33 34 public:35 typedef StringObject Base;34 public: 35 typedef StringObject Base; 36 36 37 static StringPrototype* create(VM&, JSGlobalObject*, Structure*);37 static StringPrototype* create(VM&, JSGlobalObject*, Structure*); 38 38 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 } 43 43 44 DECLARE_INFO; 45 46 protected: 47 void finishCreation(VM&, JSGlobalObject*, JSString*); 48 static const unsigned StructureFlags = StringObject::StructureFlags; 44 DECLARE_INFO; 49 45 50 }; 46 protected: 47 void finishCreation(VM&, JSGlobalObject*, JSString*); 48 static const unsigned StructureFlags = StringObject::StructureFlags; 49 }; 51 50 52 51 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/StructureChain.h
r171939 r173269 38 38 namespace JSC { 39 39 40 class LLIntOffsetsExtractor;41 class Structure;40 class LLIntOffsetsExtractor; 41 class Structure; 42 42 43 class StructureChain : public JSCell {44 friend class JIT;43 class StructureChain : public JSCell { 44 friend class JIT; 45 45 46 public:47 typedef JSCell Base;46 public: 47 typedef JSCell Base; 48 48 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&); 57 57 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 } 64 62 65 static const bool needsDestruction = true; 66 static const bool hasImmortalStructure = true; 67 static void destroy(JSCell*); 63 DECLARE_INFO; 68 64 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*); 71 68 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); 69 protected: 70 static const unsigned StructureFlags = StructureIsImmortal; 80 71 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; 85 78 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 86 private: 87 friend class LLIntOffsetsExtractor; 88 89 StructureChain(VM&, Structure*); 90 std::unique_ptr<WriteBarrier<Structure>[]> m_vector; 91 }; 92 92 93 93 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/VM.h
r173100 r173269 71 71 namespace JSC { 72 72 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;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; 99 99 #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;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; 110 110 111 111 #if ENABLE(DFG_JIT) 112 namespace DFG {113 class LongLivedState;114 }112 namespace DFG { 113 class LongLivedState; 114 } 115 115 #endif // ENABLE(DFG_JIT) 116 116 #if ENABLE(FTL_JIT) 117 namespace FTL {118 class Thunks;119 }117 namespace FTL { 118 class Thunks; 119 } 120 120 #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;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; 154 154 155 155 #if COMPILER(MSVC) … … 157 157 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" warning 158 158 #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;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; 182 182 #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))); 184 184 #else 185 void* m_buffer[0];186 #endif 187 };185 void* m_buffer[0]; 186 #endif 187 }; 188 188 #if COMPILER(MSVC) 189 189 #pragma warning(pop) 190 190 #endif 191 191 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 once196 // on a thread, this is the 'default' VM (it uses the197 // thread's default string uniquing table from wtfThreadData).198 // API contexts created using the new context group aware interface199 // create APIContextGroup objects which require less locking of JSC200 // than the old singleton APIShared VM created for use by201 // 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: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: 224 224 #if ENABLE(ASSEMBLER) 225 // executableAllocator should be destructed after the heap, as the heap can call executableAllocator226 // 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's231 // 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 234 234 #if ENABLE(DFG_JIT) 235 OwnPtr<DFG::LongLivedState> dfgState;235 OwnPtr<DFG::LongLivedState> dfgState; 236 236 #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; 275 275 #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); 297 441 } 298 442 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 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 309 537 #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 }; 311 553 #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) 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 331 595 #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*); 596 extern "C" void sanitizeStackForVMImpl(VM*); 597 #endif 598 599 void sanitizeStackForVM(VM*); 600 void logSanitizeStack(VM*); 601 601 602 602 } // namespace JSC
Note:
See TracChangeset
for help on using the changeset viewer.