]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/JSGlobalObject.h
JavaScriptCore-721.26.tar.gz
[apple/javascriptcore.git] / runtime / JSGlobalObject.h
index bad3a45a9f9f5e59a79b96c25e5b5b93aac1ee4f..dff45182d2b508a2c7812ab46a7297391c35e7ed 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 #ifndef JSGlobalObject_h
 #define JSGlobalObject_h
 
+#include "JSArray.h"
 #include "JSGlobalData.h"
 #include "JSVariableObject.h"
+#include "JSWeakObjectMapRefInternal.h"
 #include "NativeFunctionWrapper.h"
 #include "NumberPrototype.h"
 #include "StringPrototype.h"
 #include <wtf/HashSet.h>
 #include <wtf/OwnPtr.h>
+#include <wtf/RandomNumber.h>
 
 namespace JSC {
 
@@ -38,6 +41,7 @@ namespace JSC {
     class Debugger;
     class ErrorConstructor;
     class FunctionPrototype;
+    class GlobalCodeBlock;
     class GlobalEvalFunction;
     class NativeErrorConstructor;
     class ProgramCodeBlock;
@@ -50,14 +54,23 @@ namespace JSC {
     struct HashTable;
 
     typedef Vector<ExecState*, 16> ExecStateStack;
-
+    
     class JSGlobalObject : public JSVariableObject {
     protected:
         using JSVariableObject::JSVariableObjectData;
+        typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
 
         struct JSGlobalObjectData : public JSVariableObjectData {
-            JSGlobalObjectData()
+            // We use an explicit destructor function pointer instead of a
+            // virtual destructor because we want to avoid adding a vtable
+            // pointer to this struct. Adding a vtable pointer would force the
+            // compiler to emit costly pointer fixup code when casting from
+            // JSVariableObjectData* to JSGlobalObjectData*.
+            typedef void (*Destructor)(void*);
+
+            JSGlobalObjectData(Destructor destructor)
                 : JSVariableObjectData(&symbolTable, 0)
+                , destructor(destructor)
                 , registerArraySize(0)
                 , globalScopeChain(NoScopeChain())
                 , regExpConstructor(0)
@@ -80,13 +93,12 @@ namespace JSC {
                 , datePrototype(0)
                 , regExpPrototype(0)
                 , methodCallDummy(0)
+                , weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
             {
             }
             
-            virtual ~JSGlobalObjectData()
-            {
-            }
-
+            Destructor destructor;
+            
             size_t registerArraySize;
 
             JSGlobalObject* next;
@@ -144,20 +156,22 @@ namespace JSC {
 
             RefPtr<JSGlobalData> globalData;
 
-            HashSet<ProgramCodeBlock*> codeBlocks;
+            HashSet<GlobalCodeBlock*> codeBlocks;
+            WeakMapSet weakMaps;
+            WeakRandom weakRandom;
         };
 
     public:
         void* operator new(size_t, JSGlobalData*);
 
         explicit JSGlobalObject()
-            : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData)
+            : JSVariableObject(JSGlobalObject::createStructure(jsNull()), new JSGlobalObjectData(destroyJSGlobalObjectData))
         {
             init(this);
         }
 
     protected:
-        JSGlobalObject(PassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
+        JSGlobalObject(NonNullPassRefPtr<Structure> structure, JSGlobalObjectData* data, JSObject* thisValue)
             : JSVariableObject(structure, data)
         {
             init(thisValue);
@@ -166,15 +180,16 @@ namespace JSC {
     public:
         virtual ~JSGlobalObject();
 
-        virtual void mark();
+        virtual void markChildren(MarkStack&);
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+        virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
         virtual bool hasOwnPropertyForWrite(ExecState*, const Identifier&);
         virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
         virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes);
 
-        virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc);
-        virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc);
+        virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc, unsigned attributes);
+        virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc, unsigned attributes);
 
         // Linked list of all global objects that use the same JSGlobalData.
         JSGlobalObject*& head() { return d()->globalData->head; }
@@ -245,9 +260,9 @@ namespace JSC {
 
         virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
 
-        virtual bool isDynamicScope() const;
+        virtual bool isDynamicScope(bool& requiresDynamicChecks) const;
 
-        HashSet<ProgramCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
+        HashSet<GlobalCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
 
         void copyGlobalsFrom(RegisterFile&);
         void copyGlobalsTo(RegisterFile&);
@@ -259,10 +274,24 @@ namespace JSC {
 
         static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
-            return Structure::create(prototype, TypeInfo(ObjectType));
+            return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
+        }
+
+        void registerWeakMap(OpaqueJSWeakObjectMap* map)
+        {
+            d()->weakMaps.add(map);
+        }
+
+        void deregisterWeakMap(OpaqueJSWeakObjectMap* map)
+        {
+            d()->weakMaps.remove(map);
         }
 
+        double weakRandomNumber() { return d()->weakRandom.get(); }
     protected:
+
+        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
+
         struct GlobalPropertyInfo {
             GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
                 : identifier(i)
@@ -278,6 +307,8 @@ namespace JSC {
         void addStaticGlobals(GlobalPropertyInfo*, int count);
 
     private:
+        static void destroyJSGlobalObjectData(void*);
+
         // FIXME: Fold reset into init.
         void init(JSObject* thisValue);
         void reset(JSValue prototype);
@@ -326,6 +357,13 @@ namespace JSC {
         return symbolTableGet(propertyName, slot);
     }
 
+    inline bool JSGlobalObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
+    {
+        if (symbolTableGet(propertyName, descriptor))
+            return true;
+        return JSVariableObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+    }
+
     inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, const Identifier& propertyName)
     {
         PropertySlot slot;
@@ -335,14 +373,6 @@ namespace JSC {
         return symbolTableGet(propertyName, slot, slotIsWriteable);
     }
 
-    inline JSGlobalObject* ScopeChainNode::globalObject() const
-    {
-        const ScopeChainNode* n = this;
-        while (n->next)
-            n = n->next;
-        return asGlobalObject(n->object);
-    }
-
     inline JSValue Structure::prototypeForLookup(ExecState* exec) const
     {
         if (typeInfo().type() == ObjectType)
@@ -397,14 +427,46 @@ namespace JSC {
         return globalData().dynamicGlobalObject;
     }
 
-    class DynamicGlobalObjectScope : Noncopyable {
+    inline JSObject* constructEmptyObject(ExecState* exec)
+    {
+        return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
+    }
+    
+    inline JSObject* constructEmptyObject(ExecState* exec, JSGlobalObject* globalObject)
+    {
+        return new (exec) JSObject(globalObject->emptyObjectStructure());
+    }
+
+    inline JSArray* constructEmptyArray(ExecState* exec)
+    {
+        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure());
+    }
+    
+    inline JSArray* constructEmptyArray(ExecState* exec, JSGlobalObject* globalObject)
+    {
+        return new (exec) JSArray(globalObject->arrayStructure());
+    }
+
+    inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
+    {
+        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
+    }
+
+    inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
+    {
+        MarkedArgumentBuffer values;
+        values.append(singleItemValue);
+        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+    }
+
+    inline JSArray* constructArray(ExecState* exec, const ArgList& values)
+    {
+        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
+    }
+
+    class DynamicGlobalObjectScope : public Noncopyable {
     public:
-        DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject) 
-            : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
-            , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
-        {
-            m_dynamicGlobalObjectSlot = dynamicGlobalObject;
-        }
+        DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject);
 
         ~DynamicGlobalObjectScope()
         {