From d441d6f39bb846989d95bcf5caf387b42414718d Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 13 Sep 2013 12:51:20 +0200 Subject: Import Qt5x2 branch of QtWebkit for Qt 5.2 Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen --- Source/JavaScriptCore/runtime/JSGlobalObject.h | 876 ++++++++++++------------- 1 file changed, 418 insertions(+), 458 deletions(-) (limited to 'Source/JavaScriptCore/runtime/JSGlobalObject.h') diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h index e6edd0be7..a2c99fccb 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.h +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h @@ -24,564 +24,524 @@ #include "ArrayAllocationProfile.h" #include "JSArray.h" -#include "JSGlobalData.h" +#include "JSClassRef.h" +#include "VM.h" #include "JSSegmentedVariableObject.h" #include "JSWeakObjectMapRefInternal.h" #include "NumberPrototype.h" #include "SpecialPointer.h" #include "StringPrototype.h" #include "StructureChain.h" +#include "StructureRareDataInlines.h" #include "Watchpoint.h" +#include #include #include #include +struct OpaqueJSClass; +struct OpaqueJSClassContextData; + namespace JSC { - class ArrayPrototype; - class BooleanPrototype; - class DatePrototype; - class Debugger; - class ErrorConstructor; - class ErrorPrototype; - class EvalCodeBlock; - class EvalExecutable; - class FunctionCodeBlock; - class FunctionExecutable; - class FunctionPrototype; - class GetterSetter; - class GlobalCodeBlock; - class JSStack; - class LLIntOffsetsExtractor; - class NativeErrorConstructor; - class ProgramCodeBlock; - class ProgramExecutable; - class RegExpConstructor; - class RegExpPrototype; - class SourceCode; - struct ActivationStackNode; - struct HashTable; - - typedef Vector ExecStateStack; +class ArrayPrototype; +class BooleanPrototype; +class DatePrototype; +class Debugger; +class ErrorConstructor; +class ErrorPrototype; +class EvalCodeBlock; +class EvalExecutable; +class FunctionCodeBlock; +class FunctionExecutable; +class FunctionPrototype; +class GetterSetter; +class GlobalCodeBlock; +class JSStack; +class LLIntOffsetsExtractor; +class NativeErrorConstructor; +class ProgramCodeBlock; +class ProgramExecutable; +class RegExpConstructor; +class RegExpPrototype; +class SourceCode; +struct ActivationStackNode; +struct HashTable; + +typedef Vector ExecStateStack; - struct GlobalObjectMethodTable { - typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*); - AllowsAccessFromFunctionPtr allowsAccessFrom; - - typedef bool (*SupportsProfilingFunctionPtr)(const JSGlobalObject*); - SupportsProfilingFunctionPtr supportsProfiling; - - typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*); - SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo; - - typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*); - ShouldInterruptScriptFunctionPtr shouldInterruptScript; - - typedef bool (*JavaScriptExperimentsEnabledFunctionPtr)(const JSGlobalObject*); - JavaScriptExperimentsEnabledFunctionPtr javaScriptExperimentsEnabled; - }; - - class JSGlobalObject : public JSSegmentedVariableObject { - private: - typedef HashSet > WeakMapSet; - - struct JSGlobalObjectRareData { - JSGlobalObjectRareData() - : profileGroup(0) - { - } - - WeakMapSet weakMaps; - unsigned profileGroup; - }; - - protected: - - Register m_globalCallFrame[JSStack::CallFrameHeaderSize]; - - WriteBarrier m_globalThis; - - WriteBarrier m_regExpConstructor; - WriteBarrier m_errorConstructor; - WriteBarrier m_evalErrorConstructor; - WriteBarrier m_rangeErrorConstructor; - WriteBarrier m_referenceErrorConstructor; - WriteBarrier m_syntaxErrorConstructor; - WriteBarrier m_typeErrorConstructor; - WriteBarrier m_URIErrorConstructor; - - WriteBarrier m_evalFunction; - WriteBarrier m_callFunction; - WriteBarrier m_applyFunction; - WriteBarrier m_throwTypeErrorGetterSetter; - - WriteBarrier m_objectPrototype; - WriteBarrier m_functionPrototype; - WriteBarrier m_arrayPrototype; - WriteBarrier m_booleanPrototype; - WriteBarrier m_stringPrototype; - WriteBarrier m_numberPrototype; - WriteBarrier m_datePrototype; - WriteBarrier m_regExpPrototype; - WriteBarrier m_errorPrototype; - - WriteBarrier m_withScopeStructure; - WriteBarrier m_strictEvalActivationStructure; - WriteBarrier m_activationStructure; - WriteBarrier m_nameScopeStructure; - WriteBarrier m_argumentsStructure; - - // Lists the actual structures used for having these particular indexing shapes. - WriteBarrier m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes]; - // Lists the structures we should use during allocation for these particular indexing shapes. - WriteBarrier m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes]; - - WriteBarrier m_booleanObjectStructure; - WriteBarrier m_callbackConstructorStructure; - WriteBarrier m_callbackFunctionStructure; - WriteBarrier m_callbackObjectStructure; - WriteBarrier m_dateStructure; - WriteBarrier m_emptyObjectStructure; - WriteBarrier m_nullPrototypeObjectStructure; - WriteBarrier m_errorStructure; - WriteBarrier m_functionStructure; - WriteBarrier m_boundFunctionStructure; - WriteBarrier m_namedFunctionStructure; - PropertyOffset m_functionNameOffset; - WriteBarrier m_numberObjectStructure; - WriteBarrier m_privateNameStructure; - WriteBarrier m_regExpMatchesArrayStructure; - WriteBarrier m_regExpStructure; - WriteBarrier m_stringObjectStructure; - WriteBarrier m_internalFunctionStructure; - - void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT. - - Debugger* m_debugger; - - RefPtr m_masqueradesAsUndefinedWatchpoint; - RefPtr m_havingABadTimeWatchpoint; - - OwnPtr m_rareData; - - WeakRandom m_weakRandom; - - bool m_evalEnabled; - String m_evalDisabledErrorMessage; - bool m_experimentsEnabled; - - static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable; - const GlobalObjectMethodTable* m_globalObjectMethodTable; - - void createRareDataIfNeeded() - { - if (m_rareData) - return; - m_rareData = adoptPtr(new JSGlobalObjectRareData); - } - - public: - typedef JSSegmentedVariableObject Base; - - static JSGlobalObject* create(JSGlobalData& globalData, Structure* structure) - { - JSGlobalObject* globalObject = new (NotNull, allocateCell(globalData.heap)) JSGlobalObject(globalData, structure); - globalObject->finishCreation(globalData); - globalData.heap.addFinalizer(globalObject, destroy); - return globalObject; - } - - static JS_EXPORTDATA const ClassInfo s_info; - - bool hasDebugger() const { return m_debugger; } - bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); } - - protected: - JS_EXPORT_PRIVATE explicit JSGlobalObject(JSGlobalData&, Structure*, const GlobalObjectMethodTable* = 0); - - void finishCreation(JSGlobalData& globalData) - { - Base::finishCreation(globalData); - structure()->setGlobalObject(globalData, this); - m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); - init(this); - } - - void finishCreation(JSGlobalData& globalData, JSObject* thisValue) - { - Base::finishCreation(globalData); - structure()->setGlobalObject(globalData, this); - m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); - init(thisValue); - } - - public: - JS_EXPORT_PRIVATE ~JSGlobalObject(); - JS_EXPORT_PRIVATE static void destroy(JSCell*); - // We don't need a destructor because we use a finalizer instead. - static const bool needsDestruction = false; - - JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); +struct GlobalObjectMethodTable { + typedef bool (*AllowsAccessFromFunctionPtr)(const JSGlobalObject*, ExecState*); + AllowsAccessFromFunctionPtr allowsAccessFrom; - JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); - JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); - bool hasOwnPropertyForWrite(ExecState*, PropertyName); - JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); + typedef bool (*SupportsProfilingFunctionPtr)(const JSGlobalObject*); + SupportsProfilingFunctionPtr supportsProfiling; - JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes); + typedef bool (*SupportsRichSourceInfoFunctionPtr)(const JSGlobalObject*); + SupportsRichSourceInfoFunctionPtr supportsRichSourceInfo; - JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes); - JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes); - JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow); + typedef bool (*ShouldInterruptScriptFunctionPtr)(const JSGlobalObject*); + ShouldInterruptScriptFunctionPtr shouldInterruptScript; - // We use this in the code generator as we perform symbol table - // lookups prior to initializing the properties - bool symbolTableHasProperty(PropertyName); + typedef bool (*JavaScriptExperimentsEnabledFunctionPtr)(const JSGlobalObject*); + JavaScriptExperimentsEnabledFunctionPtr javaScriptExperimentsEnabled; +}; - // The following accessors return pristine values, even if a script - // replaces the global object's associated property. +class JSGlobalObject : public JSSegmentedVariableObject { +private: + typedef HashSet > WeakMapSet; + typedef HashMap > OpaqueJSClassDataMap; - RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); } - - ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); } - NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); } - NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); } - NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); } - NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); } - NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); } - NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); } - - JSFunction* evalFunction() const { return m_evalFunction.get(); } - JSFunction* callFunction() const { return m_callFunction.get(); } - JSFunction* applyFunction() const { return m_applyFunction.get(); } - GetterSetter* throwTypeErrorGetterSetter(ExecState* exec) + struct JSGlobalObjectRareData { + JSGlobalObjectRareData() + : profileGroup(0) { - if (!m_throwTypeErrorGetterSetter) - createThrowTypeError(exec); - return m_throwTypeErrorGetterSetter.get(); } - ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); } - FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); } - ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); } - BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); } - StringPrototype* stringPrototype() const { return m_stringPrototype.get(); } - NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); } - DatePrototype* datePrototype() const { return m_datePrototype.get(); } - RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); } - ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); } - - Structure* withScopeStructure() const { return m_withScopeStructure.get(); } - Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); } - Structure* activationStructure() const { return m_activationStructure.get(); } - Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); } - Structure* argumentsStructure() const { return m_argumentsStructure.get(); } - Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const - { - ASSERT(indexingType & IsArray); - return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); - } - Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const - { - ASSERT(indexingType & IsArray); - return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); - } - Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const - { - return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile)); - } - - bool isOriginalArrayStructure(Structure* structure) - { - return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure; - } + WeakMapSet weakMaps; + unsigned profileGroup; - Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); } - Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); } - Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); } - Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); } - Structure* dateStructure() const { return m_dateStructure.get(); } - Structure* emptyObjectStructure() const { return m_emptyObjectStructure.get(); } - Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); } - Structure* errorStructure() const { return m_errorStructure.get(); } - Structure* functionStructure() const { return m_functionStructure.get(); } - Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); } - Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); } - PropertyOffset functionNameOffset() const { return m_functionNameOffset; } - Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); } - Structure* privateNameStructure() const { return m_privateNameStructure.get(); } - Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); } - Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } - Structure* regExpStructure() const { return m_regExpStructure.get(); } - Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); } - - void* actualPointerFor(Special::Pointer pointer) - { - ASSERT(pointer < Special::TableSize); - return m_specialPointers[pointer]; - } + OpaqueJSClassDataMap opaqueJSClassData; + }; - WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); } - WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); } +protected: + + Register m_globalCallFrame[JSStack::CallFrameHeaderSize]; + + WriteBarrier m_globalThis; + + WriteBarrier m_regExpConstructor; + WriteBarrier m_errorConstructor; + WriteBarrier m_evalErrorConstructor; + WriteBarrier m_rangeErrorConstructor; + WriteBarrier m_referenceErrorConstructor; + WriteBarrier m_syntaxErrorConstructor; + WriteBarrier m_typeErrorConstructor; + WriteBarrier m_URIErrorConstructor; + + WriteBarrier m_evalFunction; + WriteBarrier m_callFunction; + WriteBarrier m_applyFunction; + WriteBarrier m_throwTypeErrorGetterSetter; + + WriteBarrier m_objectPrototype; + WriteBarrier m_functionPrototype; + WriteBarrier m_arrayPrototype; + WriteBarrier m_booleanPrototype; + WriteBarrier m_stringPrototype; + WriteBarrier m_numberPrototype; + WriteBarrier m_datePrototype; + WriteBarrier m_regExpPrototype; + WriteBarrier m_errorPrototype; + + WriteBarrier m_withScopeStructure; + WriteBarrier m_strictEvalActivationStructure; + WriteBarrier m_activationStructure; + WriteBarrier m_nameScopeStructure; + WriteBarrier m_argumentsStructure; - bool isHavingABadTime() const - { - return m_havingABadTimeWatchpoint->hasBeenInvalidated(); - } + // Lists the actual structures used for having these particular indexing shapes. + WriteBarrier m_originalArrayStructureForIndexingShape[NumberOfIndexingShapes]; + // Lists the structures we should use during allocation for these particular indexing shapes. + WriteBarrier m_arrayStructureForIndexingShapeDuringAllocation[NumberOfIndexingShapes]; - void haveABadTime(JSGlobalData&); + WriteBarrier m_booleanObjectStructure; + WriteBarrier m_callbackConstructorStructure; + WriteBarrier m_callbackFunctionStructure; + WriteBarrier m_callbackObjectStructure; +#if JSC_OBJC_API_ENABLED + WriteBarrier m_objcCallbackFunctionStructure; + WriteBarrier m_objcWrapperObjectStructure; +#endif + WriteBarrier m_dateStructure; + WriteBarrier m_nullPrototypeObjectStructure; + WriteBarrier m_errorStructure; + WriteBarrier m_functionStructure; + WriteBarrier m_boundFunctionStructure; + WriteBarrier m_namedFunctionStructure; + PropertyOffset m_functionNameOffset; + WriteBarrier m_numberObjectStructure; + WriteBarrier m_privateNameStructure; + WriteBarrier m_regExpMatchesArrayStructure; + WriteBarrier m_regExpStructure; + WriteBarrier m_stringObjectStructure; + WriteBarrier m_internalFunctionStructure; - bool arrayPrototypeChainIsSane(); - - void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; } - unsigned profileGroup() const - { - if (!m_rareData) - return 0; - return m_rareData->profileGroup; - } + void* m_specialPointers[Special::TableSize]; // Special pointers used by the LLInt and JIT. - Debugger* debugger() const { return m_debugger; } - void setDebugger(Debugger* debugger) { m_debugger = debugger; } + Debugger* m_debugger; - const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; } + RefPtr m_masqueradesAsUndefinedWatchpoint; + RefPtr m_havingABadTimeWatchpoint; - static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; } - static bool supportsProfiling(const JSGlobalObject*) { return false; } - static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; } + OwnPtr m_rareData; - JS_EXPORT_PRIVATE ExecState* globalExec(); + WeakRandom m_weakRandom; - static bool shouldInterruptScript(const JSGlobalObject*) { return true; } - static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return false; } + bool m_evalEnabled; + String m_evalDisabledErrorMessage; + bool m_experimentsEnabled; - bool isDynamicScope(bool& requiresDynamicChecks) const; + static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable; + const GlobalObjectMethodTable* m_globalObjectMethodTable; - bool evalEnabled() const { return m_evalEnabled; } - const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; } - void setEvalEnabled(bool enabled, const String& errorMessage = String()) - { - m_evalEnabled = enabled; - m_evalDisabledErrorMessage = errorMessage; - } - - void resetPrototype(JSGlobalData&, JSValue prototype); - - JSGlobalData& globalData() const { return *Heap::heap(this)->globalData(); } - JSObject* globalThis() const; + void createRareDataIfNeeded() + { + if (m_rareData) + return; + m_rareData = adoptPtr(new JSGlobalObjectRareData); + } + +public: + typedef JSSegmentedVariableObject Base; - static Structure* createStructure(JSGlobalData& globalData, JSValue prototype) - { - return Structure::create(globalData, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info); - } + static JSGlobalObject* create(VM& vm, Structure* structure) + { + JSGlobalObject* globalObject = new (NotNull, allocateCell(vm.heap)) JSGlobalObject(vm, structure); + globalObject->finishCreation(vm); + vm.heap.addFinalizer(globalObject, destroy); + return globalObject; + } - void registerWeakMap(OpaqueJSWeakObjectMap* map) - { - createRareDataIfNeeded(); - m_rareData->weakMaps.add(map); - } + static JS_EXPORTDATA const ClassInfo s_info; - void unregisterWeakMap(OpaqueJSWeakObjectMap* map) - { - if (m_rareData) - m_rareData->weakMaps.remove(map); - } + bool hasDebugger() const { return m_debugger; } + bool hasProfiler() const { return globalObjectMethodTable()->supportsProfiling(this); } - double weakRandomNumber() { return m_weakRandom.get(); } - unsigned weakRandomInteger() { return m_weakRandom.getUint32(); } +protected: + JS_EXPORT_PRIVATE explicit JSGlobalObject(VM&, Structure*, const GlobalObjectMethodTable* = 0); - UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception); - UnlinkedEvalCodeBlock* createEvalCodeBlock(CallFrame*, EvalExecutable*, JSObject** exception); - UnlinkedFunctionExecutable* createFunctionExecutableFromGlobalCode(CallFrame*, const Identifier&, const SourceCode&, JSObject** exception); + void finishCreation(VM& vm) + { + Base::finishCreation(vm); + structure()->setGlobalObject(vm, this); + m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); + init(this); + } - protected: + void finishCreation(VM& vm, JSObject* thisValue) + { + Base::finishCreation(vm); + structure()->setGlobalObject(vm, this); + m_experimentsEnabled = m_globalObjectMethodTable->javaScriptExperimentsEnabled(this); + init(thisValue); + } - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; +public: + JS_EXPORT_PRIVATE ~JSGlobalObject(); + JS_EXPORT_PRIVATE static void destroy(JSCell*); + // We don't need a destructor because we use a finalizer instead. + static const bool needsDestruction = false; - struct GlobalPropertyInfo { - GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) - : identifier(i) - , value(v) - , attributes(a) - { - } + JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); - const Identifier identifier; - JSValue value; - unsigned attributes; - }; - JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count); + JS_EXPORT_PRIVATE static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); + JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); + bool hasOwnPropertyForWrite(ExecState*, PropertyName); + JS_EXPORT_PRIVATE static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); - JS_EXPORT_PRIVATE static JSC::JSObject* toThisObject(JSC::JSCell*, JSC::ExecState*); + JS_EXPORT_PRIVATE static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes); - JS_EXPORT_PRIVATE void setGlobalThis(JSGlobalData&, JSObject* globalThis); + JS_EXPORT_PRIVATE static void defineGetter(JSObject*, ExecState*, PropertyName, JSObject* getterFunc, unsigned attributes); + JS_EXPORT_PRIVATE static void defineSetter(JSObject*, ExecState*, PropertyName, JSObject* setterFunc, unsigned attributes); + JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow); - private: - friend class LLIntOffsetsExtractor; - - // FIXME: Fold reset into init. - JS_EXPORT_PRIVATE void init(JSObject* thisValue); - void reset(JSValue prototype); + // We use this in the code generator as we perform symbol table + // lookups prior to initializing the properties + bool symbolTableHasProperty(PropertyName); - void createThrowTypeError(ExecState*); + // The following accessors return pristine values, even if a script + // replaces the global object's associated property. - JS_EXPORT_PRIVATE static void clearRareData(JSCell*); - }; + RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); } - JSGlobalObject* asGlobalObject(JSValue); + ErrorConstructor* errorConstructor() const { return m_errorConstructor.get(); } + NativeErrorConstructor* evalErrorConstructor() const { return m_evalErrorConstructor.get(); } + NativeErrorConstructor* rangeErrorConstructor() const { return m_rangeErrorConstructor.get(); } + NativeErrorConstructor* referenceErrorConstructor() const { return m_referenceErrorConstructor.get(); } + NativeErrorConstructor* syntaxErrorConstructor() const { return m_syntaxErrorConstructor.get(); } + NativeErrorConstructor* typeErrorConstructor() const { return m_typeErrorConstructor.get(); } + NativeErrorConstructor* URIErrorConstructor() const { return m_URIErrorConstructor.get(); } - inline JSGlobalObject* asGlobalObject(JSValue value) + JSFunction* evalFunction() const { return m_evalFunction.get(); } + JSFunction* callFunction() const { return m_callFunction.get(); } + JSFunction* applyFunction() const { return m_applyFunction.get(); } + GetterSetter* throwTypeErrorGetterSetter(ExecState* exec) { - ASSERT(asObject(value)->isGlobalObject()); - return jsCast(asObject(value)); + if (!m_throwTypeErrorGetterSetter) + createThrowTypeError(exec); + return m_throwTypeErrorGetterSetter.get(); } - inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName) + ObjectPrototype* objectPrototype() const { return m_objectPrototype.get(); } + FunctionPrototype* functionPrototype() const { return m_functionPrototype.get(); } + ArrayPrototype* arrayPrototype() const { return m_arrayPrototype.get(); } + BooleanPrototype* booleanPrototype() const { return m_booleanPrototype.get(); } + StringPrototype* stringPrototype() const { return m_stringPrototype.get(); } + NumberPrototype* numberPrototype() const { return m_numberPrototype.get(); } + DatePrototype* datePrototype() const { return m_datePrototype.get(); } + RegExpPrototype* regExpPrototype() const { return m_regExpPrototype.get(); } + ErrorPrototype* errorPrototype() const { return m_errorPrototype.get(); } + + Structure* withScopeStructure() const { return m_withScopeStructure.get(); } + Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); } + Structure* activationStructure() const { return m_activationStructure.get(); } + Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); } + Structure* argumentsStructure() const { return m_argumentsStructure.get(); } + Structure* originalArrayStructureForIndexingType(IndexingType indexingType) const { - PropertySlot slot; - if (Base::getOwnPropertySlot(this, exec, propertyName, slot)) - return true; - bool slotIsWriteable; - return symbolTableGet(this, propertyName, slot, slotIsWriteable); + ASSERT(indexingType & IsArray); + return m_originalArrayStructureForIndexingShape[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); } - - inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName) + Structure* arrayStructureForIndexingTypeDuringAllocation(IndexingType indexingType) const { - SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName()); - return !entry.isNull(); + ASSERT(indexingType & IsArray); + return m_arrayStructureForIndexingShapeDuringAllocation[(indexingType & IndexingShapeMask) >> IndexingShapeShift].get(); } - - inline JSValue Structure::prototypeForLookup(JSGlobalObject* globalObject) const + Structure* arrayStructureForProfileDuringAllocation(ArrayAllocationProfile* profile) const { - if (isObject()) - return m_prototype.get(); - - ASSERT(typeInfo().type() == StringType); - return globalObject->stringPrototype(); + return arrayStructureForIndexingTypeDuringAllocation(ArrayAllocationProfile::selectIndexingTypeFor(profile)); } - - inline JSValue Structure::prototypeForLookup(ExecState* exec) const + + bool isOriginalArrayStructure(Structure* structure) { - return prototypeForLookup(exec->lexicalGlobalObject()); + return originalArrayStructureForIndexingType(structure->indexingType() | IsArray) == structure; } - - inline StructureChain* Structure::prototypeChain(JSGlobalData& globalData, JSGlobalObject* globalObject) const + + Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); } + Structure* callbackConstructorStructure() const { return m_callbackConstructorStructure.get(); } + Structure* callbackFunctionStructure() const { return m_callbackFunctionStructure.get(); } + Structure* callbackObjectStructure() const { return m_callbackObjectStructure.get(); } +#if JSC_OBJC_API_ENABLED + Structure* objcCallbackFunctionStructure() const { return m_objcCallbackFunctionStructure.get(); } + Structure* objcWrapperObjectStructure() const { return m_objcWrapperObjectStructure.get(); } +#endif + Structure* dateStructure() const { return m_dateStructure.get(); } + Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); } + Structure* errorStructure() const { return m_errorStructure.get(); } + Structure* functionStructure() const { return m_functionStructure.get(); } + Structure* boundFunctionStructure() const { return m_boundFunctionStructure.get(); } + Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); } + PropertyOffset functionNameOffset() const { return m_functionNameOffset; } + Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); } + Structure* privateNameStructure() const { return m_privateNameStructure.get(); } + Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); } + Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); } + Structure* regExpStructure() const { return m_regExpStructure.get(); } + Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); } + + void* actualPointerFor(Special::Pointer pointer) { - // We cache our prototype chain so our clients can share it. - if (!isValid(globalObject, m_cachedPrototypeChain.get())) { - JSValue prototype = prototypeForLookup(globalObject); - m_cachedPrototypeChain.set(globalData, this, StructureChain::create(globalData, prototype.isNull() ? 0 : asObject(prototype)->structure())); - } - return m_cachedPrototypeChain.get(); + ASSERT(pointer < Special::TableSize); + return m_specialPointers[pointer]; } - inline StructureChain* Structure::prototypeChain(ExecState* exec) const + WatchpointSet* masqueradesAsUndefinedWatchpoint() { return m_masqueradesAsUndefinedWatchpoint.get(); } + WatchpointSet* havingABadTimeWatchpoint() { return m_havingABadTimeWatchpoint.get(); } + + bool isHavingABadTime() const { - return prototypeChain(exec->globalData(), exec->lexicalGlobalObject()); + return m_havingABadTimeWatchpoint->hasBeenInvalidated(); } + + void haveABadTime(VM&); + + bool arrayPrototypeChainIsSane(); - inline bool Structure::isValid(JSGlobalObject* globalObject, StructureChain* cachedPrototypeChain) const - { - if (!cachedPrototypeChain) - return false; - - JSValue prototype = prototypeForLookup(globalObject); - WriteBarrier* cachedStructure = cachedPrototypeChain->head(); - while(*cachedStructure && !prototype.isNull()) { - if (asObject(prototype)->structure() != cachedStructure->get()) - return false; - ++cachedStructure; - prototype = asObject(prototype)->prototype(); - } - return prototype.isNull() && !*cachedStructure; + void setProfileGroup(unsigned value) { createRareDataIfNeeded(); m_rareData->profileGroup = value; } + unsigned profileGroup() const + { + if (!m_rareData) + return 0; + return m_rareData->profileGroup; } - inline bool Structure::isValid(ExecState* exec, StructureChain* cachedPrototypeChain) const - { - return isValid(exec->lexicalGlobalObject(), cachedPrototypeChain); - } + Debugger* debugger() const { return m_debugger; } + void setDebugger(Debugger* debugger) { m_debugger = debugger; } - inline JSGlobalObject* ExecState::dynamicGlobalObject() - { - if (this == lexicalGlobalObject()->globalExec()) - return lexicalGlobalObject(); + const GlobalObjectMethodTable* globalObjectMethodTable() const { return m_globalObjectMethodTable; } - // For any ExecState that's not a globalExec, the - // dynamic global object must be set since code is running - ASSERT(globalData().dynamicGlobalObject); - return globalData().dynamicGlobalObject; - } + static bool allowsAccessFrom(const JSGlobalObject*, ExecState*) { return true; } + static bool supportsProfiling(const JSGlobalObject*) { return false; } + static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; } - inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject) - { - return constructEmptyObject(exec, globalObject->emptyObjectStructure()); - } + JS_EXPORT_PRIVATE ExecState* globalExec(); - inline JSObject* constructEmptyObject(ExecState* exec) - { - return constructEmptyObject(exec, exec->lexicalGlobalObject()); - } + static bool shouldInterruptScript(const JSGlobalObject*) { return true; } + static bool javaScriptExperimentsEnabled(const JSGlobalObject*) { return false; } - inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0) - { - return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->globalData(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength)); - } + bool isDynamicScope(bool& requiresDynamicChecks) const; - inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0) + bool evalEnabled() const { return m_evalEnabled; } + const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; } + void setEvalEnabled(bool enabled, const String& errorMessage = String()) { - return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength); + m_evalEnabled = enabled; + m_evalDisabledErrorMessage = errorMessage; } - - inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values) + + void resetPrototype(VM&, JSValue prototype); + + VM& vm() const { return *Heap::heap(this)->vm(); } + JSObject* globalThis() const; + + static Structure* createStructure(VM& vm, JSValue prototype) { - return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values)); + return Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), &s_info); } - inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values) + void registerWeakMap(OpaqueJSWeakObjectMap* map) { - return constructArray(exec, profile, exec->lexicalGlobalObject(), values); + createRareDataIfNeeded(); + m_rareData->weakMaps.add(map); } - inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) + void unregisterWeakMap(OpaqueJSWeakObjectMap* map) { - return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); + if (m_rareData) + m_rareData->weakMaps.remove(map); } - inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) + OpaqueJSClassDataMap& opaqueJSClassData() { - return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length); + createRareDataIfNeeded(); + return m_rareData->opaqueJSClassData; } - class DynamicGlobalObjectScope { - WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope); - public: - JS_EXPORT_PRIVATE DynamicGlobalObjectScope(JSGlobalData&, JSGlobalObject*); + double weakRandomNumber() { return m_weakRandom.get(); } + unsigned weakRandomInteger() { return m_weakRandom.getUint32(); } + + UnlinkedProgramCodeBlock* createProgramCodeBlock(CallFrame*, ProgramExecutable*, JSObject** exception); + UnlinkedEvalCodeBlock* createEvalCodeBlock(CodeCache*, CallFrame*, JSScope*, EvalExecutable*, JSObject** exception); + +protected: - ~DynamicGlobalObjectScope() + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; + + struct GlobalPropertyInfo { + GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) + : identifier(i) + , value(v) + , attributes(a) { - m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject; } - private: - JSGlobalObject*& m_dynamicGlobalObjectSlot; - JSGlobalObject* m_savedDynamicGlobalObject; + const Identifier identifier; + JSValue value; + unsigned attributes; }; + JS_EXPORT_PRIVATE void addStaticGlobals(GlobalPropertyInfo*, int count); - inline bool JSGlobalObject::isDynamicScope(bool&) const - { - return true; - } + JS_EXPORT_PRIVATE static JSC::JSObject* toThisObject(JSC::JSCell*, JSC::ExecState*); - inline JSObject* JSScope::globalThis() - { - return globalObject()->globalThis(); - } + JS_EXPORT_PRIVATE void setGlobalThis(VM&, JSObject* globalThis); - inline JSObject* JSGlobalObject::globalThis() const - { - return m_globalThis.get(); +private: + friend class LLIntOffsetsExtractor; + + // FIXME: Fold reset into init. + JS_EXPORT_PRIVATE void init(JSObject* thisValue); + void reset(JSValue prototype); + + void createThrowTypeError(ExecState*); + + JS_EXPORT_PRIVATE static void clearRareData(JSCell*); +}; + +JSGlobalObject* asGlobalObject(JSValue); + +inline JSGlobalObject* asGlobalObject(JSValue value) +{ + ASSERT(asObject(value)->isGlobalObject()); + return jsCast(asObject(value)); +} + +inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName) +{ + PropertySlot slot; + if (Base::getOwnPropertySlot(this, exec, propertyName, slot)) + return true; + bool slotIsWriteable; + return symbolTableGet(this, propertyName, slot, slotIsWriteable); +} + +inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName) +{ + SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName()); + return !entry.isNull(); +} + +inline JSGlobalObject* ExecState::dynamicGlobalObject() +{ + if (this == lexicalGlobalObject()->globalExec()) + return lexicalGlobalObject(); + + // For any ExecState that's not a globalExec, the + // dynamic global object must be set since code is running + ASSERT(vm().dynamicGlobalObject); + return vm().dynamicGlobalObject; +} + +inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, unsigned initialLength = 0) +{ + return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), initialLength >= MIN_SPARSE_ARRAY_INDEX ? globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage) : globalObject->arrayStructureForProfileDuringAllocation(profile), initialLength)); +} + +inline JSArray* constructEmptyArray(ExecState* exec, ArrayAllocationProfile* profile, unsigned initialLength = 0) +{ + return constructEmptyArray(exec, profile, exec->lexicalGlobalObject(), initialLength); +} + +inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const ArgList& values) +{ + return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values)); +} + +inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const ArgList& values) +{ + return constructArray(exec, profile, exec->lexicalGlobalObject(), values); +} + +inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, JSGlobalObject* globalObject, const JSValue* values, unsigned length) +{ + return ArrayAllocationProfile::updateLastAllocationFor(profile, constructArray(exec, globalObject->arrayStructureForProfileDuringAllocation(profile), values, length)); +} + +inline JSArray* constructArray(ExecState* exec, ArrayAllocationProfile* profile, const JSValue* values, unsigned length) +{ + return constructArray(exec, profile, exec->lexicalGlobalObject(), values, length); +} + +class DynamicGlobalObjectScope { + WTF_MAKE_NONCOPYABLE(DynamicGlobalObjectScope); +public: + JS_EXPORT_PRIVATE DynamicGlobalObjectScope(VM&, JSGlobalObject*); + + ~DynamicGlobalObjectScope() + { + m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject; } +private: + JSGlobalObject*& m_dynamicGlobalObjectSlot; + JSGlobalObject* m_savedDynamicGlobalObject; +}; + +inline bool JSGlobalObject::isDynamicScope(bool&) const +{ + return true; +} + +inline JSObject* JSScope::globalThis() +{ + return globalObject()->globalThis(); +} + +inline JSObject* JSGlobalObject::globalThis() const +{ + return m_globalThis.get(); +} + } // namespace JSC #endif // JSGlobalObject_h -- cgit v1.2.1