Reviewed by Darin.
authorap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jun 2008 17:29:29 +0000 (17:29 +0000)
committerap@webkit.org <ap@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jun 2008 17:29:29 +0000 (17:29 +0000)
        Prepare JavaScript heap for being per-thread.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@34659 268f45cc-cd09-0410-ab3c-d52691b4dbfc

155 files changed:
JavaScriptCore/API/JSBase.cpp
JavaScriptCore/API/JSCallbackObjectFunctions.h
JavaScriptCore/API/JSClassRef.cpp
JavaScriptCore/API/JSContextRef.cpp
JavaScriptCore/API/JSObjectRef.cpp
JavaScriptCore/API/JSValueRef.cpp
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/VM/CodeGenerator.cpp
JavaScriptCore/VM/CodeGenerator.h
JavaScriptCore/VM/JSPropertyNameIterator.cpp
JavaScriptCore/VM/Machine.cpp
JavaScriptCore/VM/RegisterFile.h
JavaScriptCore/VM/RegisterFileStack.h
JavaScriptCore/kjs/AllInOneFile.cpp
JavaScriptCore/kjs/ArrayPrototype.cpp
JavaScriptCore/kjs/BooleanObject.cpp
JavaScriptCore/kjs/ExecState.h
JavaScriptCore/kjs/FunctionPrototype.cpp
JavaScriptCore/kjs/InitializeThreading.cpp
JavaScriptCore/kjs/JSActivation.cpp
JavaScriptCore/kjs/JSArray.cpp
JavaScriptCore/kjs/JSFunction.cpp
JavaScriptCore/kjs/JSGlobalData.cpp
JavaScriptCore/kjs/JSGlobalData.h
JavaScriptCore/kjs/JSGlobalObject.cpp
JavaScriptCore/kjs/JSGlobalObject.h
JavaScriptCore/kjs/JSImmediate.cpp
JavaScriptCore/kjs/JSImmediate.h
JavaScriptCore/kjs/JSLock.cpp
JavaScriptCore/kjs/JSObject.cpp
JavaScriptCore/kjs/JSObject.h
JavaScriptCore/kjs/JSString.h
JavaScriptCore/kjs/JSValue.cpp
JavaScriptCore/kjs/JSValue.h
JavaScriptCore/kjs/MathObject.cpp
JavaScriptCore/kjs/NumberObject.cpp
JavaScriptCore/kjs/PropertyMap.h
JavaScriptCore/kjs/RegExpObject.cpp
JavaScriptCore/kjs/RegExpObject.h
JavaScriptCore/kjs/Shell.cpp
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/kjs/collector.h
JavaScriptCore/kjs/date_object.cpp
JavaScriptCore/kjs/error_object.cpp
JavaScriptCore/kjs/identifier.h
JavaScriptCore/kjs/internal.cpp
JavaScriptCore/kjs/interpreter.cpp
JavaScriptCore/kjs/list.cpp
JavaScriptCore/kjs/list.h
JavaScriptCore/kjs/lookup.h
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/nodes.h
JavaScriptCore/kjs/object_object.cpp
JavaScriptCore/kjs/protect.h
JavaScriptCore/kjs/string_object.cpp
JavaScriptCore/kjs/string_object.h
JavaScriptCore/kjs/ustring.h
JavaScriptGlue/ChangeLog
JavaScriptGlue/JSRun.cpp
JavaScriptGlue/JSUtils.cpp
JavaScriptGlue/JSUtils.h
JavaScriptGlue/JSValueWrapper.cpp
JavaScriptGlue/JavaScriptGlue.cpp
JavaScriptGlue/UserObjectImp.cpp
WebCore/ChangeLog
WebCore/ForwardingHeaders/kjs/JSGlobalData.h [new file with mode: 0644]
WebCore/ForwardingHeaders/kjs/completion.h [new file with mode: 0644]
WebCore/bindings/js/GCController.cpp
WebCore/bindings/js/JSAudioConstructor.cpp
WebCore/bindings/js/JSCSSRuleCustom.cpp
WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp
WebCore/bindings/js/JSCSSValueCustom.cpp
WebCore/bindings/js/JSCanvasPixelArrayCustom.cpp
WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp
WebCore/bindings/js/JSClipboardCustom.cpp
WebCore/bindings/js/JSCustomXPathNSResolver.cpp
WebCore/bindings/js/JSDOMApplicationCacheCustom.cpp
WebCore/bindings/js/JSDOMBinding.cpp
WebCore/bindings/js/JSDOMBinding.h
WebCore/bindings/js/JSDOMWindowBase.cpp
WebCore/bindings/js/JSDOMWindowBase.h
WebCore/bindings/js/JSDOMWindowShell.cpp
WebCore/bindings/js/JSDOMWindowShell.h
WebCore/bindings/js/JSDocumentCustom.cpp
WebCore/bindings/js/JSElementCustom.cpp
WebCore/bindings/js/JSEventCustom.cpp
WebCore/bindings/js/JSEventListener.cpp
WebCore/bindings/js/JSEventTargetBase.cpp
WebCore/bindings/js/JSEventTargetBase.h
WebCore/bindings/js/JSEventTargetNode.cpp
WebCore/bindings/js/JSHTMLCollectionCustom.cpp
WebCore/bindings/js/JSHTMLFormElementCustom.cpp
WebCore/bindings/js/JSHTMLInputElementBase.cpp
WebCore/bindings/js/JSHTMLOptionElementConstructor.cpp
WebCore/bindings/js/JSHTMLOptionsCollectionCustom.cpp
WebCore/bindings/js/JSInspectedObjectWrapper.cpp
WebCore/bindings/js/JSInspectorCallbackWrapper.cpp
WebCore/bindings/js/JSJavaScriptCallFrameCustom.cpp
WebCore/bindings/js/JSLocationCustom.cpp
WebCore/bindings/js/JSNamedNodesCollection.cpp
WebCore/bindings/js/JSNavigatorCustom.cpp
WebCore/bindings/js/JSNodeCustom.cpp
WebCore/bindings/js/JSNodeFilterCustom.cpp
WebCore/bindings/js/JSPluginElementFunctions.cpp
WebCore/bindings/js/JSRGBColor.cpp
WebCore/bindings/js/JSSQLResultSetRowListCustom.cpp
WebCore/bindings/js/JSSVGLazyEventListener.cpp
WebCore/bindings/js/JSStorageCustom.cpp
WebCore/bindings/js/JSStyleSheetCustom.cpp
WebCore/bindings/js/JSTextCustom.cpp
WebCore/bindings/js/JSXMLHttpRequestConstructor.cpp
WebCore/bindings/js/JSXMLHttpRequestCustom.cpp
WebCore/bindings/js/JSXSLTProcessorConstructor.cpp
WebCore/bindings/js/JSXSLTProcessorCustom.cpp
WebCore/bindings/js/ScriptController.cpp
WebCore/bindings/objc/WebScriptObject.mm
WebCore/bindings/scripts/CodeGeneratorJS.pm
WebCore/bridge/NP_jsobject.cpp
WebCore/bridge/c/c_instance.cpp
WebCore/bridge/c/c_instance.h
WebCore/bridge/c/c_utility.cpp
WebCore/bridge/jni/jni_instance.cpp
WebCore/bridge/jni/jni_instance.h
WebCore/bridge/jni/jni_jsobject.h
WebCore/bridge/jni/jni_jsobject.mm
WebCore/bridge/jni/jni_objc.mm
WebCore/bridge/jni/jni_runtime.cpp
WebCore/bridge/jni/jni_utility.h
WebCore/bridge/objc/objc_class.mm
WebCore/bridge/objc/objc_instance.h
WebCore/bridge/objc/objc_instance.mm
WebCore/bridge/objc/objc_utility.h
WebCore/bridge/objc/objc_utility.mm
WebCore/bridge/qt/qt_class.cpp
WebCore/bridge/qt/qt_instance.cpp
WebCore/bridge/qt/qt_instance.h
WebCore/bridge/qt/qt_runtime.cpp
WebCore/bridge/runtime.cpp
WebCore/bridge/runtime.h
WebCore/bridge/runtime_array.cpp
WebCore/bridge/runtime_method.cpp
WebCore/bridge/runtime_object.cpp
WebCore/dom/make_names.pl
WebCore/page/Console.cpp
WebCore/xml/XMLHttpRequest.cpp
WebKit/mac/ChangeLog
WebKit/mac/Misc/WebCoreStatistics.mm
WebKit/qt/Api/qwebframe.cpp
WebKit/qt/ChangeLog
WebKit/win/ChangeLog
WebKit/win/WebCoreStatistics.cpp
WebKit/win/WebJavaScriptCollector.cpp
WebKit/win/WebScriptCallFrame.cpp

index 8fa8820..e9921a9 100644 (file)
@@ -28,6 +28,7 @@
 #include "JSBase.h"
 
 #include "APICast.h"
+#include "completion.h"
 #include <kjs/ExecState.h>
 #include <kjs/InitializeThreading.h>
 #include <kjs/interpreter.h>
@@ -85,9 +86,21 @@ void JSGarbageCollect(JSContextRef ctx)
     if (!ctx)
         initializeThreading();
 
+    // It might seem that we have a context passed to this function, and can use toJS(ctx)->heap(), but the parameter is likely to be NULL,
+    // and it may actually be garbage for some clients (most likely, because of JSGarbageCollect being called after releasing the context).
+
     JSLock lock;
-    if (!Collector::isBusy())
-        Collector::collect();
+
+    // FIXME: It would be good to avoid creating a JSGlobalData instance if it didn't exist for this thread yet.
+    Heap* heap = JSGlobalData::threadInstance().heap;
+    if (!heap->isBusy())
+        heap->collect();
+
+    // FIXME: Similarly, we shouldn't create a shared instance here.
+    heap = JSGlobalData::sharedInstance().heap;
+    if (!heap->isBusy())
+        heap->collect();
+
     // FIXME: Perhaps we should trigger a second mark and sweep
     // once the garbage collector is done if this is called when
     // the collector is busy.
index d7c048e..61eab2e 100644 (file)
@@ -470,7 +470,7 @@ JSValue* JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Ide
         if (OpaqueJSClass::StaticFunctionsTable* staticFunctions = jsClass->staticFunctions) {
             if (StaticFunctionEntry* entry = staticFunctions->get(propertyName.ustring().rep())) {
                 if (JSObjectCallAsFunctionCallback callAsFunction = entry->callAsFunction) {
-                    JSObject* o = new JSCallbackFunction(exec, callAsFunction, propertyName);
+                    JSObject* o = new (exec) JSCallbackFunction(exec, callAsFunction, propertyName);
                     thisObj->putDirect(propertyName, o, entry->attributes);
                     return o;
                 }
index 11ed8dc..0f878df 100644 (file)
@@ -162,7 +162,7 @@ JSObject* OpaqueJSClass::prototype(JSContextRef ctx)
             parentPrototype = parentClass->prototype(ctx); // can be null
         if (!parentPrototype)
             parentPrototype = exec->dynamicGlobalObject()->objectPrototype();
-        cachedPrototype = new JSCallbackObject<JSObject>(exec, prototypeClass, parentPrototype, this); // set ourself as the object's private data, so it can clear our reference on destruction
+        cachedPrototype = new (exec) JSCallbackObject<JSObject>(exec, prototypeClass, parentPrototype, this); // set ourself as the object's private data, so it can clear our reference on destruction
     }
     return cachedPrototype;
 }
index 57ba5ce..322370c 100644 (file)
@@ -44,11 +44,11 @@ JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
     JSLock lock;
 
     if (!globalObjectClass) {
-        JSGlobalObject* globalObject = new JSGlobalObject;
+        JSGlobalObject* globalObject = new (JSGlobalObject::Shared) JSGlobalObject;
         return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec()));
     }
 
-    JSGlobalObject* globalObject = new JSCallbackObject<JSGlobalObject>(globalObjectClass);
+    JSGlobalObject* globalObject = new (JSGlobalObject::Shared) JSCallbackObject<JSGlobalObject>(globalObjectClass);
     JSGlobalContextRef ctx = toGlobalRef(globalObject->globalExec());
     JSValue* prototype = globalObjectClass->prototype(ctx);
     if (!prototype)
index 427bd58..6e7cb5b 100644 (file)
@@ -74,13 +74,13 @@ JSObjectRef JSObjectMake(JSContextRef ctx, JSClassRef jsClass, void* data)
     ExecState* exec = toJS(ctx);
 
     if (!jsClass)
-        return toRef(new JSObject(exec->lexicalGlobalObject()->objectPrototype())); // slightly more efficient
+        return toRef(new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype())); // slightly more efficient
 
     JSValue* jsPrototype = jsClass->prototype(ctx);
     if (!jsPrototype)
         jsPrototype = exec->lexicalGlobalObject()->objectPrototype();
 
-    return toRef(new JSCallbackObject<JSObject>(exec, jsClass, jsPrototype, data));
+    return toRef(new (exec) JSCallbackObject<JSObject>(exec, jsClass, jsPrototype, data));
 }
 
 JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name, JSObjectCallAsFunctionCallback callAsFunction)
@@ -89,7 +89,7 @@ JSObjectRef JSObjectMakeFunctionWithCallback(JSContextRef ctx, JSStringRef name,
     ExecState* exec = toJS(ctx);
     Identifier nameID = name ? Identifier(exec, toJS(name)) : Identifier(exec, "anonymous");
     
-    return toRef(new JSCallbackFunction(exec, callAsFunction, nameID));
+    return toRef(new (exec) JSCallbackFunction(exec, callAsFunction, nameID));
 }
 
 JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObjectCallAsConstructorCallback callAsConstructor)
@@ -101,7 +101,7 @@ JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObje
         ? jsClass->prototype(ctx)
         : exec->dynamicGlobalObject()->objectPrototype();
     
-    JSCallbackConstructor* constructor = new JSCallbackConstructor(exec, jsClass, callAsConstructor);
+    JSCallbackConstructor* constructor = new (exec) JSCallbackConstructor(exec, jsClass, callAsConstructor);
     constructor->putDirect(exec->propertyNames().prototype, jsPrototype, DontEnum | DontDelete | ReadOnly);
     return toRef(constructor);
 }
@@ -118,8 +118,8 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
     
     ArgList args;
     for (unsigned i = 0; i < parameterCount; i++)
-        args.append(jsString(UString(toJS(parameterNames[i]))));
-    args.append(jsString(UString(bodyRep)));
+        args.append(jsString(exec, UString(toJS(parameterNames[i]))));
+    args.append(jsString(exec, UString(bodyRep)));
 
     JSObject* result = exec->dynamicGlobalObject()->functionConstructor()->construct(exec, args, nameID, UString(sourceURLRep), startingLineNumber);
     if (exec->hadException()) {
index 8ad5100..ffc8ba3 100644 (file)
@@ -176,17 +176,17 @@ JSValueRef JSValueMakeBoolean(JSContextRef, bool value)
     return toRef(jsBoolean(value));
 }
 
-JSValueRef JSValueMakeNumber(JSContextRef, double value)
+JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
 {
     JSLock lock;
-    return toRef(jsNumber(value));
+    return toRef(jsNumber(toJS(ctx), value));
 }
 
-JSValueRef JSValueMakeString(JSContextRef, JSStringRef string)
+JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
 {
     JSLock lock;
     UString::Rep* rep = toJS(string);
-    return toRef(jsString(UString(rep)));
+    return toRef(jsString(toJS(ctx), UString(rep)));
 }
 
 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
index 231d132..e37ac98 100644 (file)
@@ -1,3 +1,358 @@
+2008-06-17  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        Prepare JavaScript heap for being per-thread.
+
+        * kjs/ExecState.h: Shuffle includes, making it possible to include ExecState.h in JSValue.h.
+        (KJS::ExecState::heap): Added an accessor.
+
+        * API/JSBase.cpp: (JSGarbageCollect): Collect both shared and per-thread heaps.
+
+        * API/JSContextRef.cpp: (JSGlobalContextCreate): When allocating JSGlobalObject, indicate
+        that it belongs to a shared heap.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * kjs/AllInOneFile.cpp:
+        Moved JSGlobalObject.cpp to AllInOneFile, as a build fix for inlineAllocate magic.
+
+        * VM/CodeGenerator.h: (KJS::CodeGenerator::globalExec): Added an accessor (working via
+        m_scopeChain).
+
+        * VM/RegisterFile.h:
+        (KJS::RegisterFile::mark):
+        * VM/RegisterFileStack.h:
+        (KJS::RegisterFileStack::mark):
+        Made these pseudo-mark functions take Heap*.
+
+        * kjs/InitializeThreading.cpp:
+        (KJS::initializeThreading): Initialize heap introspector.
+
+        * kjs/JSGlobalData.h: Added Heap to the structure.
+
+        * kjs/JSGlobalData.cpp:
+        (KJS::JSGlobalData::JSGlobalData): Initialize Heap.
+        (KJS::JSGlobalData::sharedInstance): Added a method to access shared global data instance
+        for legacy clients.
+
+        * kjs/JSGlobalObject.cpp:
+        (KJS::JSGlobalObject::~JSGlobalObject): Changed to work with per-thread head; fixed list
+        maintenance logic.
+        (KJS::JSGlobalObject::init): Changed to work with per-thread head.
+        (KJS::JSGlobalObject::put): Assert that a cross-heap operation is not being attempted.
+        (KJS::JSGlobalObject::reset): Pass ExecState* where now required.
+        (KJS::JSGlobalObject::mark): Pass the current heap to RegisterFileStack::mark.
+        (KJS::JSGlobalObject::operator new): Overload operator new to use per-thread or shared heap.
+        * kjs/JSGlobalObject.h: Removed static s_head member.
+
+        * kjs/PropertyMap.h: (KJS::PropertyMap::PropertyMap): Removed unused SavedProperty.
+
+        * kjs/collector.h: Turned Collector into an actual object with its own data, renamed to Heap.
+        (KJS::Heap::initializeHeapIntrospector): Added.
+        (KJS::Heap::heap): Added a method to determine which heap a JSValue is in, if any.
+        (KJS::Heap::allocate): Made non-static.
+        (KJS::Heap::inlineAllocateNumber): Ditto.
+        (KJS::Heap::markListSet): Ditto.
+        (KJS::Heap::cellBlock): Ditto.
+        (KJS::Heap::cellOffset): Ditto.
+        (KJS::Heap::isCellMarked): Ditto.
+        (KJS::Heap::markCell): Ditto.
+        (KJS::Heap::reportExtraMemoryCost): Ditto.
+        (KJS::CollectorBlock): Added a back-reference to Heap for Heap::heap() method.
+        (KJS::SmallCellCollectorBlock): Ditto.
+
+        * kjs/collector.cpp: Changed MIN_ARRAY_SIZE to a #define to avoid a PIC branch. Removed
+        main thread related machinery.
+        (KJS::Heap::Heap): Initialize the newly added data members.
+        (KJS::allocateBlock): Marked NEVER_INLINE, as this is a rare case that uses a PIC branch.
+        Moved static pagesize to the class to make it safely initialized.
+        (KJS::Heap::heapAllocate): Initialize heap back reference after a new block is allocated.
+        (KJS::Heap::registerThread): Removed introspector initialization, as it is now performed
+        in InitializeThreading.cpp.
+        (KJS::Heap::markOtherThreadConservatively): Assert that the "other thread" case only occurs
+        for legacy clients using a shared heap.
+        (KJS::Heap::markStackObjectsConservatively): Moved fastMallocForbid/Allow down here, since
+        it doesn't need to be forbidden during other GC phases.
+
+        * kjs/JSImmediate.h:
+        (KJS::jsUndefined):
+        (KJS::jsNull):
+        (KJS::jsBoolean):
+        Moved from JSvalue.h, to make these usable in files that cannot include JSValue.h (such
+        as list.h).
+
+        * API/JSCallbackObjectFunctions.h:
+        (KJS::::staticFunctionGetter):
+        * API/JSClassRef.cpp:
+        (OpaqueJSClass::prototype):
+        * API/JSObjectRef.cpp:
+        (JSObjectMake):
+        (JSObjectMakeFunctionWithCallback):
+        (JSObjectMakeConstructor):
+        (JSObjectMakeFunction):
+        * API/JSValueRef.cpp:
+        (JSValueMakeNumber):
+        (JSValueMakeString):
+        * JavaScriptCore.exp:
+        * VM/CodeGenerator.cpp:
+        (KJS::CodeGenerator::emitLoad):
+        * VM/JSPropertyNameIterator.cpp:
+        (KJS::JSPropertyNameIterator::create):
+        (KJS::JSPropertyNameIterator::next):
+        * VM/Machine.cpp:
+        (KJS::jsAddSlowCase):
+        (KJS::jsAdd):
+        (KJS::jsTypeStringForValue):
+        (KJS::scopeChainForCall):
+        (KJS::Machine::throwException):
+        (KJS::Machine::execute):
+        (KJS::Machine::privateExecute):
+        (KJS::Machine::retrieveArguments):
+        * kjs/ArrayPrototype.cpp:
+        (KJS::arrayProtoFuncToString):
+        (KJS::arrayProtoFuncToLocaleString):
+        (KJS::arrayProtoFuncJoin):
+        (KJS::arrayProtoFuncConcat):
+        (KJS::arrayProtoFuncPop):
+        (KJS::arrayProtoFuncPush):
+        (KJS::arrayProtoFuncShift):
+        (KJS::arrayProtoFuncSlice):
+        (KJS::arrayProtoFuncSplice):
+        (KJS::arrayProtoFuncUnShift):
+        (KJS::arrayProtoFuncFilter):
+        (KJS::arrayProtoFuncMap):
+        (KJS::arrayProtoFuncEvery):
+        (KJS::arrayProtoFuncForEach):
+        (KJS::arrayProtoFuncSome):
+        (KJS::arrayProtoFuncIndexOf):
+        (KJS::arrayProtoFuncLastIndexOf):
+        (KJS::ArrayConstructor::ArrayConstructor):
+        (KJS::ArrayConstructor::construct):
+        (KJS::ArrayConstructor::callAsFunction):
+        * kjs/BooleanObject.cpp:
+        (KJS::BooleanPrototype::BooleanPrototype):
+        (KJS::booleanProtoFuncToString):
+        (KJS::BooleanConstructor::BooleanConstructor):
+        (KJS::BooleanConstructor::construct):
+        * kjs/FunctionPrototype.cpp:
+        (KJS::FunctionPrototype::FunctionPrototype):
+        (KJS::functionProtoFuncToString):
+        (KJS::FunctionConstructor::FunctionConstructor):
+        (KJS::FunctionConstructor::construct):
+        * kjs/JSActivation.cpp:
+        (KJS::JSActivation::createArgumentsObject):
+        * kjs/JSArray.cpp:
+        (KJS::JSArray::JSArray):
+        (KJS::JSArray::lengthGetter):
+        * kjs/JSFunction.cpp:
+        (KJS::JSFunction::lengthGetter):
+        (KJS::JSFunction::construct):
+        (KJS::Arguments::Arguments):
+        (KJS::encode):
+        (KJS::decode):
+        (KJS::globalFuncParseInt):
+        (KJS::globalFuncParseFloat):
+        (KJS::globalFuncEscape):
+        (KJS::globalFuncUnescape):
+        (KJS::PrototypeFunction::PrototypeFunction):
+        (KJS::PrototypeReflexiveFunction::PrototypeReflexiveFunction):
+        * kjs/JSImmediate.cpp:
+        (KJS::JSImmediate::toObject):
+        * kjs/JSLock.cpp:
+        (KJS::JSLock::registerThread):
+        * kjs/JSObject.cpp:
+        (KJS::JSObject::put):
+        (KJS::JSObject::defineGetter):
+        (KJS::JSObject::defineSetter):
+        (KJS::Error::create):
+        * kjs/JSObject.h:
+        (KJS::JSObject::putDirect):
+        * kjs/JSString.h:
+        (KJS::JSString::JSString):
+        * kjs/JSValue.cpp:
+        (KJS::JSCell::operator new):
+        (KJS::jsString):
+        (KJS::jsOwnedString):
+        * kjs/JSValue.h:
+        (KJS::JSNumberCell::operator new):
+        (KJS::jsNumberCell):
+        (KJS::jsNaN):
+        (KJS::jsNumber):
+        (KJS::JSCell::marked):
+        (KJS::JSCell::mark):
+        (KJS::JSValue::toJSNumber):
+        * kjs/MathObject.cpp:
+        (KJS::MathObject::getValueProperty):
+        (KJS::mathProtoFuncAbs):
+        (KJS::mathProtoFuncACos):
+        (KJS::mathProtoFuncASin):
+        (KJS::mathProtoFuncATan):
+        (KJS::mathProtoFuncATan2):
+        (KJS::mathProtoFuncCeil):
+        (KJS::mathProtoFuncCos):
+        (KJS::mathProtoFuncExp):
+        (KJS::mathProtoFuncFloor):
+        (KJS::mathProtoFuncLog):
+        (KJS::mathProtoFuncMax):
+        (KJS::mathProtoFuncMin):
+        (KJS::mathProtoFuncPow):
+        (KJS::mathProtoFuncRandom):
+        (KJS::mathProtoFuncRound):
+        (KJS::mathProtoFuncSin):
+        (KJS::mathProtoFuncSqrt):
+        (KJS::mathProtoFuncTan):
+        * kjs/NumberObject.cpp:
+        (KJS::NumberPrototype::NumberPrototype):
+        (KJS::numberProtoFuncToString):
+        (KJS::numberProtoFuncToLocaleString):
+        (KJS::numberProtoFuncToFixed):
+        (KJS::numberProtoFuncToExponential):
+        (KJS::numberProtoFuncToPrecision):
+        (KJS::NumberConstructor::NumberConstructor):
+        (KJS::NumberConstructor::getValueProperty):
+        (KJS::NumberConstructor::construct):
+        (KJS::NumberConstructor::callAsFunction):
+        * kjs/RegExpObject.cpp:
+        (KJS::RegExpPrototype::RegExpPrototype):
+        (KJS::regExpProtoFuncToString):
+        (KJS::RegExpObject::getValueProperty):
+        (KJS::RegExpConstructor::RegExpConstructor):
+        (KJS::RegExpMatchesArray::fillArrayInstance):
+        (KJS::RegExpConstructor::arrayOfMatches):
+        (KJS::RegExpConstructor::getBackref):
+        (KJS::RegExpConstructor::getLastParen):
+        (KJS::RegExpConstructor::getLeftContext):
+        (KJS::RegExpConstructor::getRightContext):
+        (KJS::RegExpConstructor::getValueProperty):
+        (KJS::RegExpConstructor::construct):
+        * kjs/RegExpObject.h:
+        * kjs/Shell.cpp:
+        (GlobalObject::GlobalObject):
+        (functionGC):
+        (functionRun):
+        (functionReadline):
+        (jscmain):
+        * kjs/date_object.cpp:
+        (KJS::formatLocaleDate):
+        (KJS::DatePrototype::DatePrototype):
+        (KJS::DateConstructor::DateConstructor):
+        (KJS::DateConstructor::construct):
+        (KJS::DateConstructor::callAsFunction):
+        (KJS::DateFunction::DateFunction):
+        (KJS::DateFunction::callAsFunction):
+        (KJS::dateProtoFuncToString):
+        (KJS::dateProtoFuncToUTCString):
+        (KJS::dateProtoFuncToDateString):
+        (KJS::dateProtoFuncToTimeString):
+        (KJS::dateProtoFuncToLocaleString):
+        (KJS::dateProtoFuncToLocaleDateString):
+        (KJS::dateProtoFuncToLocaleTimeString):
+        (KJS::dateProtoFuncValueOf):
+        (KJS::dateProtoFuncGetTime):
+        (KJS::dateProtoFuncGetFullYear):
+        (KJS::dateProtoFuncGetUTCFullYear):
+        (KJS::dateProtoFuncToGMTString):
+        (KJS::dateProtoFuncGetMonth):
+        (KJS::dateProtoFuncGetUTCMonth):
+        (KJS::dateProtoFuncGetDate):
+        (KJS::dateProtoFuncGetUTCDate):
+        (KJS::dateProtoFuncGetDay):
+        (KJS::dateProtoFuncGetUTCDay):
+        (KJS::dateProtoFuncGetHours):
+        (KJS::dateProtoFuncGetUTCHours):
+        (KJS::dateProtoFuncGetMinutes):
+        (KJS::dateProtoFuncGetUTCMinutes):
+        (KJS::dateProtoFuncGetSeconds):
+        (KJS::dateProtoFuncGetUTCSeconds):
+        (KJS::dateProtoFuncGetMilliSeconds):
+        (KJS::dateProtoFuncGetUTCMilliseconds):
+        (KJS::dateProtoFuncGetTimezoneOffset):
+        (KJS::dateProtoFuncSetTime):
+        (KJS::setNewValueFromTimeArgs):
+        (KJS::setNewValueFromDateArgs):
+        (KJS::dateProtoFuncSetYear):
+        (KJS::dateProtoFuncGetYear):
+        * kjs/error_object.cpp:
+        (KJS::ErrorPrototype::ErrorPrototype):
+        (KJS::errorProtoFuncToString):
+        (KJS::ErrorConstructor::ErrorConstructor):
+        (KJS::ErrorConstructor::construct):
+        (KJS::NativeErrorPrototype::NativeErrorPrototype):
+        (KJS::NativeErrorConstructor::NativeErrorConstructor):
+        (KJS::NativeErrorConstructor::construct):
+        * kjs/identifier.h:
+        * kjs/internal.cpp:
+        (KJS::StringObject::create):
+        (KJS::JSString::lengthGetter):
+        (KJS::JSString::indexGetter):
+        (KJS::JSString::indexNumericPropertyGetter):
+        * kjs/interpreter.cpp:
+        * kjs/list.cpp:
+        (KJS::ArgList::slowAppend):
+        * kjs/list.h:
+        * kjs/lookup.h:
+        (KJS::staticFunctionGetter):
+        (KJS::cacheGlobalObject):
+        * kjs/nodes.cpp:
+        (KJS::Node::emitThrowError):
+        (KJS::StringNode::emitCode):
+        (KJS::ArrayNode::emitCode):
+        (KJS::FuncDeclNode::makeFunction):
+        (KJS::FuncExprNode::makeFunction):
+        * kjs/nodes.h:
+        * kjs/object_object.cpp:
+        (KJS::ObjectPrototype::ObjectPrototype):
+        (KJS::objectProtoFuncToLocaleString):
+        (KJS::objectProtoFuncToString):
+        (KJS::ObjectConstructor::ObjectConstructor):
+        (KJS::ObjectConstructor::construct):
+        * kjs/protect.h:
+        (KJS::gcProtect):
+        (KJS::gcUnprotect):
+        * kjs/string_object.cpp:
+        (KJS::StringObject::StringObject):
+        (KJS::StringPrototype::StringPrototype):
+        (KJS::replace):
+        (KJS::stringProtoFuncCharAt):
+        (KJS::stringProtoFuncCharCodeAt):
+        (KJS::stringProtoFuncConcat):
+        (KJS::stringProtoFuncIndexOf):
+        (KJS::stringProtoFuncLastIndexOf):
+        (KJS::stringProtoFuncMatch):
+        (KJS::stringProtoFuncSearch):
+        (KJS::stringProtoFuncReplace):
+        (KJS::stringProtoFuncSlice):
+        (KJS::stringProtoFuncSplit):
+        (KJS::stringProtoFuncSubstr):
+        (KJS::stringProtoFuncSubstring):
+        (KJS::stringProtoFuncToLowerCase):
+        (KJS::stringProtoFuncToUpperCase):
+        (KJS::stringProtoFuncToLocaleLowerCase):
+        (KJS::stringProtoFuncToLocaleUpperCase):
+        (KJS::stringProtoFuncLocaleCompare):
+        (KJS::stringProtoFuncBig):
+        (KJS::stringProtoFuncSmall):
+        (KJS::stringProtoFuncBlink):
+        (KJS::stringProtoFuncBold):
+        (KJS::stringProtoFuncFixed):
+        (KJS::stringProtoFuncItalics):
+        (KJS::stringProtoFuncStrike):
+        (KJS::stringProtoFuncSub):
+        (KJS::stringProtoFuncSup):
+        (KJS::stringProtoFuncFontcolor):
+        (KJS::stringProtoFuncFontsize):
+        (KJS::stringProtoFuncAnchor):
+        (KJS::stringProtoFuncLink):
+        (KJS::StringConstructor::StringConstructor):
+        (KJS::StringConstructor::construct):
+        (KJS::StringConstructor::callAsFunction):
+        (KJS::StringConstructorFunction::StringConstructorFunction):
+        (KJS::StringConstructorFunction::callAsFunction):
+        * kjs/string_object.h:
+        (KJS::StringObjectThatMasqueradesAsUndefined::StringObjectThatMasqueradesAsUndefined):
+        * kjs/ustring.h:
+        Updated for the above changes.
+
 2008-06-17  Timothy Hatcher  <timothy@apple.com>
 
         Added a type to DebuggerCallFrame so the under interface can
index 120c0c8..503b7e5 100644 (file)
@@ -97,6 +97,7 @@ __ZN3KJS11PropertyMap11getLocationERKNS_10IdentifierERb
 __ZN3KJS11PropertyMap3putERKNS_10IdentifierEPNS_7JSValueEjb
 __ZN3KJS11PropertyMapD1Ev
 __ZN3KJS12DateInstance4infoE
+__ZN3KJS12JSGlobalData14sharedInstanceEv
 __ZN3KJS12JSGlobalData14threadInstanceEv
 __ZN3KJS12PropertySlot15undefinedGetterEPNS_9ExecStateERKNS_10IdentifierERKS0_
 __ZN3KJS12RegisterFile14addGlobalSlotsEm
@@ -106,10 +107,10 @@ __ZN3KJS12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_
 __ZN3KJS12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3KJS12StringObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
 __ZN3KJS12StringObject4infoE
-__ZN3KJS12StringObjectC2EPNS_8JSObjectERKNS_7UStringE
+__ZN3KJS12StringObjectC2EPNS_9ExecStateEPNS_8JSObjectERKNS_7UStringE
 __ZN3KJS13CodeGenerator21setDumpsGeneratedCodeEb
 __ZN3KJS13StatementNode6setLocEii
-__ZN3KJS13jsOwnedStringERKNS_7UStringE
+__ZN3KJS13jsOwnedStringEPNS_9ExecStateERKNS_7UStringE
 __ZN3KJS14JSGlobalObject10globalExecEv
 __ZN3KJS14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
 __ZN3KJS14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
@@ -120,6 +121,8 @@ __ZN3KJS14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
 __ZN3KJS14JSGlobalObject4initEPNS_8JSObjectE
 __ZN3KJS14JSGlobalObject4markEv
 __ZN3KJS14JSGlobalObjectD2Ev
+__ZN3KJS14JSGlobalObjectnwEm
+__ZN3KJS14JSGlobalObjectnwEmNS0_9SharedTagE
 __ZN3KJS15JSWrapperObject4markEv
 __ZN3KJS16InternalFunction11getCallDataERNS_8CallDataE
 __ZN3KJS16InternalFunction4infoE
@@ -134,6 +137,19 @@ __ZN3KJS17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFPNS_7JSValueES
 __ZN3KJS17RegisterFileStack20allocateRegisterFileEmPS0_
 __ZN3KJS19initializeThreadingEv
 __ZN3KJS23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3KJS4Heap14allocateNumberEm
+__ZN3KJS4Heap15recordExtraCostEm
+__ZN3KJS4Heap17globalObjectCountEv
+__ZN3KJS4Heap20protectedObjectCountEv
+__ZN3KJS4Heap23collectOnMainThreadOnlyEPNS_7JSValueE
+__ZN3KJS4Heap25protectedObjectTypeCountsEv
+__ZN3KJS4Heap26protectedGlobalObjectCountEv
+__ZN3KJS4Heap4heapEPKNS_7JSValueE
+__ZN3KJS4Heap4sizeEv
+__ZN3KJS4Heap7collectEv
+__ZN3KJS4Heap7protectEPNS_7JSValueE
+__ZN3KJS4Heap8allocateEm
+__ZN3KJS4Heap9unprotectEPNS_7JSValueE
 __ZN3KJS5equalEPKNS_7UString3RepES3_
 __ZN3KJS6JSCell11getCallDataERNS_8CallDataE
 __ZN3KJS6JSCell16getConstructDataERNS_13ConstructDataE
@@ -142,7 +158,7 @@ __ZN3KJS6JSCell18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3KJS6JSCell3putEPNS_9ExecStateERKNS_10IdentifierEPNS_7JSValueE
 __ZN3KJS6JSCell3putEPNS_9ExecStateEjPNS_7JSValueE
 __ZN3KJS6JSCell9getObjectEv
-__ZN3KJS6JSCellnwEm
+__ZN3KJS6JSCellnwEmPNS_9ExecStateE
 __ZN3KJS6JSLock12DropAllLocksC1Ev
 __ZN3KJS6JSLock12DropAllLocksD1Ev
 __ZN3KJS6JSLock14registerThreadEv
@@ -196,19 +212,8 @@ __ZN3KJS8JSObject9constructEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_
 __ZN3KJS8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3KJS8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3KJS8Profiler8profilerEv
-__ZN3KJS8jsStringEPKc
-__ZN3KJS8jsStringERKNS_7UStringE
-__ZN3KJS9Collector14allocateNumberEm
-__ZN3KJS9Collector15recordExtraCostEm
-__ZN3KJS9Collector17globalObjectCountEv
-__ZN3KJS9Collector20protectedObjectCountEv
-__ZN3KJS9Collector23collectOnMainThreadOnlyEPNS_7JSValueE
-__ZN3KJS9Collector25protectedObjectTypeCountsEv
-__ZN3KJS9Collector26protectedGlobalObjectCountEv
-__ZN3KJS9Collector4sizeEv
-__ZN3KJS9Collector7collectEv
-__ZN3KJS9Collector7protectEPNS_7JSValueE
-__ZN3KJS9Collector9unprotectEPNS_7JSValueE
+__ZN3KJS8jsStringEPNS_9ExecStateEPKc
+__ZN3KJS8jsStringEPNS_9ExecStateERKNS_7UStringE
 __ZN3KJSeqERKNS_7UStringEPKc
 __ZN3KJSgtERKNS_7UStringES2_
 __ZN3KJSltERKNS_7UStringES2_
@@ -246,9 +251,9 @@ __ZNK3KJS14JSGlobalObject14toGlobalObjectEPNS_9ExecStateE
 __ZNK3KJS16InternalFunction21implementsHasInstanceEv
 __ZNK3KJS16JSVariableObject16isVariableObjectEv
 __ZNK3KJS16JSVariableObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
-__ZNK3KJS17DebuggerCallFrame4typeEv
 __ZNK3KJS17DebuggerCallFrame10thisObjectEv
 __ZNK3KJS17DebuggerCallFrame12functionNameEv
+__ZNK3KJS17DebuggerCallFrame4typeEv
 __ZNK3KJS17DebuggerCallFrame8evaluateERKNS_7UStringERPNS_7JSValueE
 __ZNK3KJS4Node8toStringEv
 __ZNK3KJS6JSCell12toThisObjectEPNS_9ExecStateE
index e3e5767..9e2ba74 100644 (file)
                14D797800DAC3307001A9F05 /* RegisterFileStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D7977E0DAC3307001A9F05 /* RegisterFileStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14D797810DAC3307001A9F05 /* RegisterFileStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14D7977F0DAC3307001A9F05 /* RegisterFileStack.cpp */; };
                14DA81900D99FD2000B0A4FB /* JSActivation.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DA818E0D99FD2000B0A4FB /* JSActivation.h */; };
-               14DE0D690D02431400AACCA2 /* JSGlobalObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */; };
                14E0FF120DBAAED00007C0AB /* Machine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 149B15E70D81F986009CB8C7 /* Machine.cpp */; settings = {COMPILER_FLAGS = "-fno-tree-pre"; }; };
                14F252570D08DD8D004ECFFF /* JSVariableObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F252560D08DD8D004ECFFF /* JSVariableObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
                14F252610D08DF2F004ECFFF /* JSVariableObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14F252600D08DF2F004ECFFF /* JSVariableObject.cpp */; };
                                140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */,
                                1440FCE40A51E46B0005F061 /* JSClassRef.cpp in Sources */,
                                14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */,
-                               14DE0D690D02431400AACCA2 /* JSGlobalObject.cpp in Sources */,
                                1482B7E40A43076000517CFC /* JSObjectRef.cpp in Sources */,
                                1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
                                146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
index 5e5e951..5602886 100644 (file)
@@ -568,7 +568,7 @@ RegisterID* CodeGenerator::emitLoad(RegisterID* dst, double d)
 {
     emitOpcode(op_load);
     instructions().append(dst->index());
-    instructions().append(addConstant(jsNumber(d)));
+    instructions().append(addConstant(jsNumber(globalExec(), d)));
     return dst;
 }
 
index 568e071..5ec4e35 100644 (file)
@@ -278,6 +278,8 @@ namespace KJS {
 
         CodeType codeType() const { return m_codeType; }
 
+        ExecState* globalExec() { return m_scopeChain->globalObject()->globalExec(); }
+
     private:
         void emitOpcode(OpcodeID);
         void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
index 07757e2..ab46ee3 100644 (file)
@@ -40,13 +40,13 @@ COMPILE_ASSERT(sizeof(JSPropertyNameIterator) <= CellSize<sizeof(void*)>::m_valu
 JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue* v)
 {
     if (v->isUndefinedOrNull())
-        return new JSPropertyNameIterator(0, 0, 0);
+        return new (exec) JSPropertyNameIterator(0, 0, 0);
 
     JSObject* o = v->toObject(exec);
     PropertyNameArray propertyNames(exec);
     o->getPropertyNames(exec, propertyNames);
     size_t numProperties = propertyNames.size();
-    return new JSPropertyNameIterator(o, propertyNames.releaseIdentifiers(), numProperties);
+    return new (exec) JSPropertyNameIterator(o, propertyNames.releaseIdentifiers(), numProperties);
 }
 
 JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, Identifier* propertyNames, size_t numProperties)
@@ -114,7 +114,7 @@ JSValue* JSPropertyNameIterator::next(ExecState* exec)
 {
     while (m_position != m_end) {
         if (m_object->hasProperty(exec, *m_position))
-            return jsOwnedString((*m_position++).ustring());;
+            return jsOwnedString(exec, (*m_position++).ustring());;
         m_position++;
     }
     invalidate();
index 617afef..62408ed 100644 (file)
@@ -131,10 +131,10 @@ static JSValue* jsAddSlowCase(ExecState* exec, JSValue* v1, JSValue* v2)
         UString value = p1->toString(exec) + p2->toString(exec);
         if (value.isNull())
             return throwOutOfMemoryError(exec);
-        return jsString(value);
+        return jsString(exec, value);
     }
 
-    return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
+    return jsNumber(exec, p1->toNumber(exec) + p2->toNumber(exec));
 }
 
 // Fast-path choices here are based on frequency data from SunSpider:
@@ -153,42 +153,42 @@ static inline JSValue* jsAdd(ExecState* exec, JSValue* v1, JSValue* v2)
     const unsigned bothTypes = (t1 << 3) | t2;
 
     if (bothTypes == ((NumberType << 3) | NumberType))
-        return jsNumber(v1->uncheckedGetNumber() + v2->uncheckedGetNumber());
+        return jsNumber(exec, v1->uncheckedGetNumber() + v2->uncheckedGetNumber());
     if (bothTypes == ((StringType << 3) | StringType)) {
         UString value = static_cast<JSString*>(v1)->value() + static_cast<JSString*>(v2)->value();
         if (value.isNull())
             return throwOutOfMemoryError(exec);
-        return jsString(value);
+        return jsString(exec, value);
     }
 
     // All other cases are pretty uncommon
     return jsAddSlowCase(exec, v1, v2);
 }
 
-static JSValue* jsTypeStringForValue(JSValue* v)
+static JSValue* jsTypeStringForValue(ExecState* exec, JSValue* v)
 {
     switch (v->type()) {
         case UndefinedType:
-            return jsString("undefined");
+            return jsString(exec, "undefined");
         case NullType:
-            return jsString("object");
+            return jsString(exec, "object");
         case BooleanType:
-            return jsString("boolean");
+            return jsString(exec, "boolean");
         case NumberType:
-            return jsString("number");
+            return jsString(exec, "number");
         case StringType:
-            return jsString("string");
+            return jsString(exec, "string");
         default:
             if (v->isObject()) {
                 // Return "undefined" for objects that should be treated
                 // as null when doing comparisons.
                 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
-                    return jsString("undefined");
+                    return jsString(exec, "undefined");
                 else if (static_cast<JSObject*>(v)->implementsCall())
-                    return jsString("function");
+                    return jsString(exec, "function");
             }
 
-            return jsString("object");
+            return jsString(exec, "object");
     }
 }
 
@@ -412,10 +412,10 @@ ALWAYS_INLINE Register* slideRegisterWindowForCall(ExecState* exec, CodeBlock* n
     return r;
 }
 
-ALWAYS_INLINE ScopeChainNode* scopeChainForCall(FunctionBodyNode* functionBodyNode, CodeBlock* newCodeBlock, ScopeChainNode* callDataScopeChain, Register** registerBase, Register* r)
+ALWAYS_INLINE ScopeChainNode* scopeChainForCall(ExecState* exec, FunctionBodyNode* functionBodyNode, CodeBlock* newCodeBlock, ScopeChainNode* callDataScopeChain, Register** registerBase, Register* r)
 {
     if (newCodeBlock->needsFullScopeChain) {
-        JSActivation* activation = new JSActivation(functionBodyNode, registerBase, r - (*registerBase));
+        JSActivation* activation = new (exec) JSActivation(functionBodyNode, registerBase, r - (*registerBase));
         r[Machine::OptionalCalleeActivation - Machine::CallFrameHeaderSize - newCodeBlock->numLocals].u.jsValue = activation;
 
         return callDataScopeChain->copy()->push(activation);
@@ -610,8 +610,8 @@ NEVER_INLINE Instruction* Machine::throwException(ExecState* exec, JSValue* exce
     if (exceptionValue->isObject()) {
         JSObject* exception = static_cast<JSObject*>(exceptionValue);
         if (!exception->hasProperty(exec, Identifier(exec, "line")) && !exception->hasProperty(exec, Identifier(exec, "sourceURL"))) {
-            exception->put(exec, Identifier(exec, "line"), jsNumber(codeBlock->lineNumberForVPC(vPC)));
-            exception->put(exec, Identifier(exec, "sourceURL"), jsOwnedString(codeBlock->ownerNode->sourceURL()));
+            exception->put(exec, Identifier(exec, "line"), jsNumber(exec, codeBlock->lineNumberForVPC(vPC)));
+            exception->put(exec, Identifier(exec, "sourceURL"), jsOwnedString(exec, codeBlock->ownerNode->sourceURL()));
         }
     }
 
@@ -725,7 +725,7 @@ JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, ExecState* exec, J
         return 0;
     }
 
-    scopeChain = scopeChainForCall(functionBodyNode, newCodeBlock, scopeChain, registerBase, r);
+    scopeChain = scopeChainForCall(exec, functionBodyNode, newCodeBlock, scopeChain, registerBase, r);
 
     ExecState newExec(exec, this, registerFile, scopeChain, callFrameOffset);
 
@@ -970,7 +970,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         */
         int dst = (++vPC)->u.operand;
         int regExp = (++vPC)->u.operand;
-        r[dst].u.jsValue = new RegExpObject(scopeChain->globalObject()->regExpPrototype(), codeBlock->regexps[regExp]);
+        r[dst].u.jsValue = new (exec) RegExpObject(scopeChain->globalObject()->regExpPrototype(), codeBlock->regexps[regExp]);
 
         ++vPC;
         NEXT_OPCODE;
@@ -1113,7 +1113,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         if (JSImmediate::canDoFastAdditiveOperations(v))
             result = JSImmediate::incImmediateNumber(v);
         else
-            result = jsNumber(v->toNumber(exec) + 1);
+            result = jsNumber(exec, v->toNumber(exec) + 1);
         VM_CHECK_EXCEPTION();
         r[srcDst].u.jsValue = result;
 
@@ -1132,7 +1132,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         if (JSImmediate::canDoFastAdditiveOperations(v))
             result = JSImmediate::decImmediateNumber(v);
         else
-            result = jsNumber(v->toNumber(exec) - 1);
+            result = jsNumber(exec, v->toNumber(exec) - 1);
         VM_CHECK_EXCEPTION();
         r[srcDst].u.jsValue = result;
 
@@ -1156,7 +1156,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
             result = JSImmediate::incImmediateNumber(v);
         } else {
             number = r[srcDst].u.jsValue->toJSNumber(exec);
-            result = jsNumber(number->uncheckedGetNumber() + 1);
+            result = jsNumber(exec, number->uncheckedGetNumber() + 1);
         }
         VM_CHECK_EXCEPTION();
 
@@ -1183,7 +1183,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
             result = JSImmediate::decImmediateNumber(v);
         } else {
             number = r[srcDst].u.jsValue->toJSNumber(exec);
-            result = jsNumber(number->uncheckedGetNumber() - 1);
+            result = jsNumber(exec, number->uncheckedGetNumber() - 1);
         }
         VM_CHECK_EXCEPTION();
 
@@ -1217,7 +1217,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        JSValue* result = jsNumber(-r[src].u.jsValue->toNumber(exec));
+        JSValue* result = jsNumber(exec, -r[src].u.jsValue->toNumber(exec));
         VM_CHECK_EXCEPTION();
         r[dst].u.jsValue = result;
 
@@ -1254,7 +1254,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         JSValue*& dst = r[(++vPC)->u.operand].u.jsValue;
         JSValue* src1 = r[(++vPC)->u.operand].u.jsValue;
         JSValue* src2 = r[(++vPC)->u.operand].u.jsValue;
-        JSValue* result = jsNumber(src1->toNumber(exec) * src2->toNumber(exec));
+        JSValue* result = jsNumber(exec, src1->toNumber(exec) * src2->toNumber(exec));
         VM_CHECK_EXCEPTION();
         dst = result;
 
@@ -1271,7 +1271,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         int dst = (++vPC)->u.operand;
         int dividend = (++vPC)->u.operand;
         int divisor = (++vPC)->u.operand;
-        JSValue* result = jsNumber(r[dividend].u.jsValue->toNumber(exec) / r[divisor].u.jsValue->toNumber(exec));
+        JSValue* result = jsNumber(exec, r[dividend].u.jsValue->toNumber(exec) / r[divisor].u.jsValue->toNumber(exec));
         VM_CHECK_EXCEPTION();
         r[dst].u.jsValue = result;
         ++vPC;
@@ -1288,7 +1288,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         int dividend = (++vPC)->u.operand;
         int divisor = (++vPC)->u.operand;
         double d = r[dividend].u.jsValue->toNumber(exec);
-        JSValue* result = jsNumber(fmod(d, r[divisor].u.jsValue->toNumber(exec)));
+        JSValue* result = jsNumber(exec, fmod(d, r[divisor].u.jsValue->toNumber(exec)));
         VM_CHECK_EXCEPTION();
         r[dst].u.jsValue = result;
         ++vPC;
@@ -1308,7 +1308,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
             result = JSImmediate::subImmediateNumbers(src1, src2);
         else {
-            result = jsNumber(src1->toNumber(exec) - src2->toNumber(exec));
+            result = jsNumber(exec, src1->toNumber(exec) - src2->toNumber(exec));
             VM_CHECK_EXCEPTION();
         }
         dst = result;
@@ -1327,9 +1327,9 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         JSValue* shift = r[(++vPC)->u.operand].u.jsValue;
         JSValue* result;
         if (JSImmediate::areBothImmediateNumbers(val, shift))
-            result = jsNumber(JSImmediate::getTruncatedInt32(val) << (JSImmediate::toTruncatedUInt32(shift) & 0x1f));
+            result = jsNumber(exec, JSImmediate::getTruncatedInt32(val) << (JSImmediate::toTruncatedUInt32(shift) & 0x1f));
         else {
-            result = jsNumber((val->toInt32(exec)) << (shift->toUInt32(exec) & 0x1f));
+            result = jsNumber(exec, (val->toInt32(exec)) << (shift->toUInt32(exec) & 0x1f));
             VM_CHECK_EXCEPTION();
         }
         dst = result;
@@ -1351,7 +1351,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         if (JSImmediate::areBothImmediateNumbers(val, shift))
             result = JSImmediate::rightShiftImmediateNumbers(val, shift);
         else {
-            result = jsNumber((val->toInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
+            result = jsNumber(exec, (val->toInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
             VM_CHECK_EXCEPTION();
         }
         dst = result;
@@ -1373,7 +1373,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         if (JSImmediate::areBothImmediateNumbers(val, shift) && !JSImmediate::isNegative(val))
             result = JSImmediate::rightShiftImmediateNumbers(val, shift);
         else {
-            result = jsNumber((val->toUInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
+            result = jsNumber(exec, (val->toUInt32(exec)) >> (shift->toUInt32(exec) & 0x1f));
             VM_CHECK_EXCEPTION();
         }
         dst = result;
@@ -1395,7 +1395,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         if (JSImmediate::areBothImmediateNumbers(src1, src2))
             result = JSImmediate::andImmediateNumbers(src1, src2);
         else {
-            result = jsNumber(src1->toInt32(exec) & src2->toInt32(exec));
+            result = jsNumber(exec, src1->toInt32(exec) & src2->toInt32(exec));
             VM_CHECK_EXCEPTION();
         }
         dst = result;
@@ -1417,7 +1417,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         if (JSImmediate::areBothImmediateNumbers(src1, src2))
             result = JSImmediate::xorImmediateNumbers(src1, src2);
         else {
-            result = jsNumber(src1->toInt32(exec) ^ src2->toInt32(exec));
+            result = jsNumber(exec, src1->toInt32(exec) ^ src2->toInt32(exec));
             VM_CHECK_EXCEPTION();
         }
         dst = result;
@@ -1439,7 +1439,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         if (JSImmediate::areBothImmediateNumbers(src1, src2))
             result = JSImmediate::orImmediateNumbers(src1, src2);
         else {
-            result = jsNumber(src1->toInt32(exec) | src2->toInt32(exec));
+            result = jsNumber(exec, src1->toInt32(exec) | src2->toInt32(exec));
             VM_CHECK_EXCEPTION();
         }
         dst = result;
@@ -1455,7 +1455,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        JSValue* result = jsNumber(~r[src].u.jsValue->toInt32(exec));
+        JSValue* result = jsNumber(exec, ~r[src].u.jsValue->toInt32(exec));
         VM_CHECK_EXCEPTION();
         r[dst].u.jsValue = result;
 
@@ -1509,7 +1509,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        r[dst].u.jsValue = jsTypeStringForValue(r[src].u.jsValue);
+        r[dst].u.jsValue = jsTypeStringForValue(exec, r[src].u.jsValue);
 
         ++vPC;
         NEXT_OPCODE;
@@ -2095,7 +2095,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
 
             codeBlock = newCodeBlock;
             exec->m_callFrameOffset = callFrameOffset;
-            setScopeChain(exec, scopeChain, scopeChainForCall(functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
+            setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
             k = codeBlock->jsValues.data();
             vPC = codeBlock->instructions.begin();
 
@@ -2223,7 +2223,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
                 prototype = static_cast<JSObject*>(p);
             else
                 prototype = scopeChain->globalObject()->objectPrototype();
-            JSObject* newObject = new JSObject(prototype);
+            JSObject* newObject = new (exec) JSObject(prototype);
             r[firstArg].u.jsValue = newObject; // "this" value
 
             initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, dst, firstArg, argCount, 1, constructor);
@@ -2238,7 +2238,7 @@ JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFi
 
             codeBlock = newCodeBlock;
             exec->m_callFrameOffset = callFrameOffset;
-            setScopeChain(exec, scopeChain, scopeChainForCall(functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
+            setScopeChain(exec, scopeChain, scopeChainForCall(exec, functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
             k = codeBlock->jsValues.data();
             vPC = codeBlock->instructions.begin();
 
@@ -2550,7 +2550,7 @@ JSValue* Machine::retrieveArguments(ExecState* exec, JSFunction* function) const
     JSActivation* activation = static_cast<JSActivation*>(callFrame[OptionalCalleeActivation].u.jsValue);
     if (!activation) {
         CodeBlock* codeBlock = &function->body->generatedCode();
-        activation = new JSActivation(function->body, registerBase, callFrameOffset + CallFrameHeaderSize + codeBlock->numLocals);
+        activation = new (exec) JSActivation(function->body, registerBase, callFrameOffset + CallFrameHeaderSize + codeBlock->numLocals);
         callFrame[OptionalCalleeActivation].u.jsValue = activation;
     }
 
index 9821c07..ef6e8d5 100644 (file)
@@ -136,9 +136,9 @@ namespace KJS {
 
         void copyGlobals(RegisterFile* src);
 
-        void mark()
+        void mark(Heap* heap)
         {
-            Collector::markStackObjectsConservatively(m_buffer, m_base + m_size);
+            heap->markStackObjectsConservatively(m_buffer, m_base + m_size);
         }
 
         bool isGlobal() { return !!m_baseObserver; }
index 5e5298a..efc94a4 100644 (file)
@@ -51,11 +51,11 @@ namespace KJS {
 
         RegisterFile* current() { return m_stack.last(); }
 
-        void mark()
+        void mark(Heap* heap)
         {
             Stack::iterator end = m_stack.end();
             for (Stack::iterator it = m_stack.begin(); it != end; ++it)
-                (*it)->mark();
+                (*it)->mark(heap);
         }
 
         // Pointer to a value that holds the base of the top-most global register file.
index 5fdf0ed..28c3aec 100644 (file)
@@ -56,6 +56,7 @@
 #include "nodes2string.cpp"
 #include "NumberObject.cpp"
 #include "JSObject.cpp"
+#include "JSGlobalObject.cpp"
 #include "object_object.cpp"
 #include "operations.cpp"
 #include "Parser.cpp"
index 3f1ad2a..1a4039c 100644 (file)
@@ -100,7 +100,7 @@ JSValue* arrayProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLis
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     Vector<UChar, 256> strBuffer;
     if (alreadyVisited)
-        return jsString(UString(0, 0)); // return an empty string, avoding infinite recursion.
+        return jsString(exec, UString(0, 0)); // return an empty string, avoding infinite recursion.
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     for (unsigned k = 0; k < length; k++) {
@@ -128,7 +128,7 @@ JSValue* arrayProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLis
             break;
     }
     exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
-    return jsString(UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+    return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
 JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -143,7 +143,7 @@ JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     Vector<UChar, 256> strBuffer;
     if (alreadyVisited)
-        return jsString(UString(0, 0)); // return an empty string, avoding infinite recursion.
+        return jsString(exec, UString(0, 0)); // return an empty string, avoding infinite recursion.
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     for (unsigned k = 0; k < length; k++) {
@@ -177,7 +177,7 @@ JSValue* arrayProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const
             break;
     }
     exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
-    return jsString(UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+    return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
 JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -189,7 +189,7 @@ JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject* thisObj, const ArgList& a
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     Vector<UChar, 256> strBuffer;
     if (alreadyVisited)
-        return jsString(UString(0, 0)); // return an empty string, avoding infinite recursion.
+        return jsString(exec, UString(0, 0)); // return an empty string, avoding infinite recursion.
 
     UChar comma = ',';
     UString separator = args[0]->isUndefined() ? UString(&comma, 1) : args[0]->toString(exec);
@@ -220,7 +220,7 @@ JSValue* arrayProtoFuncJoin(ExecState* exec, JSObject* thisObj, const ArgList& a
             break;
     }
     exec->dynamicGlobalObject()->arrayVisitedElements().remove(thisObj);
-    return jsString(UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+    return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
 JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -253,7 +253,7 @@ JSValue* arrayProtoFuncConcat(ExecState* exec, JSObject* thisObj, const ArgList&
         curObj = static_cast<JSObject*>(curArg); // may be 0
         ++it;
     }
-    arr->put(exec, exec->propertyNames().length, jsNumber(n));
+    arr->put(exec, exec->propertyNames().length, jsNumber(exec, n));
     return arr;
 }
 
@@ -262,12 +262,12 @@ JSValue* arrayProtoFuncPop(ExecState* exec, JSObject* thisObj, const ArgList&)
     JSValue* result = 0;
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     if (length == 0) {
-        thisObj->put(exec, exec->propertyNames().length, jsNumber(length));
+        thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
         result = jsUndefined();
     } else {
         result = thisObj->get(exec, length - 1);
         thisObj->deleteProperty(exec, length - 1);
-        thisObj->put(exec, exec->propertyNames().length, jsNumber(length - 1));
+        thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));
     }
     return result;
 }
@@ -278,8 +278,8 @@ JSValue* arrayProtoFuncPush(ExecState* exec, JSObject* thisObj, const ArgList& a
     for (unsigned n = 0; n < args.size(); n++)
         thisObj->put(exec, length + n, args[n]);
     length += args.size();
-    thisObj->put(exec, exec->propertyNames().length, jsNumber(length));
-    return jsNumber(length);
+    thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
+    return jsNumber(exec, length);
 }
 
 JSValue* arrayProtoFuncReverse(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -311,7 +311,7 @@ JSValue* arrayProtoFuncShift(ExecState* exec, JSObject* thisObj, const ArgList&)
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
     if (length == 0) {
-        thisObj->put(exec, exec->propertyNames().length, jsNumber(length));
+        thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length));
         result = jsUndefined();
     } else {
         result = thisObj->get(exec, 0);
@@ -322,7 +322,7 @@ JSValue* arrayProtoFuncShift(ExecState* exec, JSObject* thisObj, const ArgList&)
                 thisObj->deleteProperty(exec, k - 1);
         }
         thisObj->deleteProperty(exec, length - 1);
-        thisObj->put(exec, exec->propertyNames().length, jsNumber(length - 1));
+        thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - 1));
     }
     return result;
 }
@@ -366,7 +366,7 @@ JSValue* arrayProtoFuncSlice(ExecState* exec, JSObject* thisObj, const ArgList&
         if (JSValue* v = getProperty(exec, thisObj, k))
             resObj->put(exec, n, v);
     }
-    resObj->put(exec, exec->propertyNames().length, jsNumber(n));
+    resObj->put(exec, exec->propertyNames().length, jsNumber(exec, n));
     return result;
 }
 
@@ -451,7 +451,7 @@ JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject* thisObj, const ArgList&
         if (JSValue* v = getProperty(exec, thisObj, k + begin))
             resObj->put(exec, k, v);
     }
-    resObj->put(exec, exec->propertyNames().length, jsNumber(deleteCount));
+    resObj->put(exec, exec->propertyNames().length, jsNumber(exec, deleteCount));
 
     unsigned additionalArgs = std::max<int>(args.size() - 2, 0);
     if (additionalArgs != deleteCount) {
@@ -476,7 +476,7 @@ JSValue* arrayProtoFuncSplice(ExecState* exec, JSObject* thisObj, const ArgList&
     for (unsigned k = 0; k < additionalArgs; ++k)
         thisObj->put(exec, k + begin, args[k + 2]);
 
-    thisObj->put(exec, exec->propertyNames().length, jsNumber(length - deleteCount + additionalArgs));
+    thisObj->put(exec, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));
     return result;
 }
 
@@ -495,7 +495,7 @@ JSValue* arrayProtoFuncUnShift(ExecState* exec, JSObject* thisObj, const ArgList
     }
     for (unsigned k = 0; k < nrArgs; ++k)
         thisObj->put(exec, k, args[k]);
-    JSValue* result = jsNumber(length + nrArgs);
+    JSValue* result = jsNumber(exec, length + nrArgs);
     thisObj->put(exec, exec->propertyNames().length, result);
     return result;
 }
@@ -523,7 +523,7 @@ JSValue* arrayProtoFuncFilter(ExecState* exec, JSObject* thisObj, const ArgList&
         ArgList eachArguments;
 
         eachArguments.append(v);
-        eachArguments.append(jsNumber(k));
+        eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
         JSValue* result = eachFunction->callAsFunction(exec, applyThis, eachArguments);
@@ -545,7 +545,7 @@ JSValue* arrayProtoFuncMap(ExecState* exec, JSObject* thisObj, const ArgList& ar
     unsigned length = thisObj->get(exec, exec->propertyNames().length)->toUInt32(exec);
 
     ArgList mapArgs;
-    mapArgs.append(jsNumber(length));
+    mapArgs.append(jsNumber(exec, length));
     JSObject* resultArray = static_cast<JSObject*>(exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, mapArgs));
 
     for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
@@ -558,7 +558,7 @@ JSValue* arrayProtoFuncMap(ExecState* exec, JSObject* thisObj, const ArgList& ar
         ArgList eachArguments;
 
         eachArguments.append(v);
-        eachArguments.append(jsNumber(k));
+        eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
         JSValue* result = eachFunction->callAsFunction(exec, applyThis, eachArguments);
@@ -594,7 +594,7 @@ JSValue* arrayProtoFuncEvery(ExecState* exec, JSObject* thisObj, const ArgList&
         ArgList eachArguments;
 
         eachArguments.append(slot.getValue(exec, k));
-        eachArguments.append(jsNumber(k));
+        eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
         bool predicateResult = eachFunction->callAsFunction(exec, applyThis, eachArguments)->toBoolean(exec);
@@ -625,7 +625,7 @@ JSValue* arrayProtoFuncForEach(ExecState* exec, JSObject* thisObj, const ArgList
 
         ArgList eachArguments;
         eachArguments.append(slot.getValue(exec, k));
-        eachArguments.append(jsNumber(k));
+        eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
         eachFunction->callAsFunction(exec, applyThis, eachArguments);
@@ -652,7 +652,7 @@ JSValue* arrayProtoFuncSome(ExecState* exec, JSObject* thisObj, const ArgList& a
 
         ArgList eachArguments;
         eachArguments.append(slot.getValue(exec, k));
-        eachArguments.append(jsNumber(k));
+        eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
         bool predicateResult = eachFunction->callAsFunction(exec, applyThis, eachArguments)->toBoolean(exec);
@@ -688,10 +688,10 @@ JSValue* arrayProtoFuncIndexOf(ExecState* exec, JSObject* thisObj, const ArgList
         if (!e)
             continue;
         if (strictEqual(searchElement, e))
-            return jsNumber(index);
+            return jsNumber(exec, index);
     }
 
-    return jsNumber(-1);
+    return jsNumber(exec, -1);
 }
 
 JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -706,7 +706,7 @@ JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const Arg
     if (d < 0) {
         d += length;
         if (d < 0)
-            return jsNumber(-1);
+            return jsNumber(exec, -1);
     }
     if (d < length)
         index = static_cast<int>(d);
@@ -717,10 +717,10 @@ JSValue* arrayProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const Arg
         if (!e)
             continue;
         if (strictEqual(searchElement, e))
-            return jsNumber(index);
+            return jsNumber(exec, index);
     }
 
-    return jsNumber(-1);
+    return jsNumber(exec, -1);
 }
 
 // ------------------------------ ArrayConstructor -------------------------------
@@ -732,7 +732,7 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, FunctionPrototype* funcProto
     putDirect(exec->propertyNames().prototype, arrayProto, DontEnum|DontDelete|ReadOnly);
 
     // no. of arguments for constructor
-    putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
 }
 
 ConstructType ArrayConstructor::getConstructData(ConstructData&)
@@ -748,18 +748,18 @@ JSObject* ArrayConstructor::construct(ExecState* exec, const ArgList& args)
         uint32_t n = args[0]->toUInt32(exec);
         if (n != args[0]->toNumber(exec))
             return throwError(exec, RangeError, "Array size is not a small enough positive integer.");
-        return new JSArray(exec->lexicalGlobalObject()->arrayPrototype(), n);
+        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayPrototype(), n);
     }
 
     // otherwise the array is constructed with the arguments in it
-    return new JSArray(exec->lexicalGlobalObject()->arrayPrototype(), args);
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayPrototype(), args);
 }
 
 // ECMA 15.6.1
 JSValue* ArrayConstructor::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
 {
     // equivalent to 'new Array(....)'
-    return construct(exec,args);
+    return construct(exec, args);
 }
 
 }
index 2b58f22..b6b3481 100644 (file)
@@ -50,8 +50,8 @@ BooleanPrototype::BooleanPrototype(ExecState* exec, ObjectPrototype* objectProto
 {
     setInternalValue(jsBoolean(false));
 
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
 }
 
 
@@ -67,7 +67,7 @@ JSValue* booleanProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgL
     JSValue* v = static_cast<BooleanObject*>(thisObj)->internalValue();
     ASSERT(v);
 
-    return jsString(v->toString(exec));
+    return jsString(exec, v->toString(exec));
 }
 JSValue* booleanProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
@@ -90,7 +90,7 @@ BooleanConstructor::BooleanConstructor(ExecState* exec, FunctionPrototype* funct
     putDirect(exec->propertyNames().prototype, booleanPrototype, DontEnum | DontDelete | ReadOnly);
 
     // no. of arguments for constructor
-    putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
 }
 
 ConstructType BooleanConstructor::getConstructData(ConstructData&)
@@ -101,7 +101,7 @@ ConstructType BooleanConstructor::getConstructData(ConstructData&)
 // ECMA 15.6.2
 JSObject* BooleanConstructor::construct(ExecState* exec, const ArgList& args)
 {
-    BooleanObject* obj(new BooleanObject(exec->lexicalGlobalObject()->booleanPrototype()));
+    BooleanObject* obj(new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanPrototype()));
     obj->setInternalValue(jsBoolean(args[0]->toBoolean(exec)));
     return obj;
 }
index dea49e9..13c0876 100644 (file)
@@ -25,9 +25,6 @@
 #define ExecState_h
 
 #include "JSGlobalData.h"
-#include "LabelStack.h"
-#include "completion.h"
-#include "list.h"
 #include "ScopeChain.h"
 
 namespace KJS  {
@@ -91,6 +88,8 @@ namespace KJS  {
         static const HashTable* regExpConstructorTable(ExecState* exec) { return exec->m_globalData->regExpConstructorTable; }
         static const HashTable* stringTable(ExecState* exec) { return exec->m_globalData->stringTable; }
 
+        Heap* heap() const { return m_globalData->heap; }
+
     private:
         // Default constructor required for gcc 3.
         ExecState() { }
index 955e123..ab9a5c7 100644 (file)
@@ -44,11 +44,11 @@ static JSValue* functionProtoFuncCall(ExecState*, JSObject*, const ArgList&);
 
 FunctionPrototype::FunctionPrototype(ExecState* exec)
 {
-    putDirect(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
 
-    putDirectFunction(new PrototypeFunction(exec, this, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, this, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, this, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, this, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, this, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, this, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
 }
 
 // ECMA 15.3.4
@@ -70,10 +70,10 @@ JSValue* functionProtoFuncToString(ExecState* exec, JSObject* thisObj, const Arg
 
     if (thisObj->inherits(&JSFunction::info)) {
         JSFunction* fi = static_cast<JSFunction*>(thisObj);
-        return jsString("function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toSourceString());
+        return jsString(exec, "function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toSourceString());
     }
 
-    return jsString("function " + static_cast<InternalFunction*>(thisObj)->functionName().ustring() + "() {\n    [native code]\n}");
+    return jsString(exec, "function " + static_cast<InternalFunction*>(thisObj)->functionName().ustring() + "() {\n    [native code]\n}");
 }
 
 JSValue* functionProtoFuncApply(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -133,7 +133,7 @@ FunctionConstructor::FunctionConstructor(ExecState* exec, FunctionPrototype* fun
     putDirect(exec->propertyNames().prototype, functionPrototype, DontEnum | DontDelete | ReadOnly);
 
     // Number of arguments for constructor
-    putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontDelete | DontEnum);
 }
 
 ConstructType FunctionConstructor::getConstructData(ConstructData&)
@@ -174,7 +174,7 @@ JSObject* FunctionConstructor::construct(ExecState* exec, const ArgList& args, c
     functionBody->setSource(SourceRange(source, 0, source->length()));
     ScopeChain scopeChain(exec->lexicalGlobalObject(), exec->globalThisValue());
 
-    JSFunction* fimp = new JSFunction(exec, functionName, functionBody.get(), scopeChain.node());
+    JSFunction* fimp = new (exec) JSFunction(exec, functionName, functionBody.get(), scopeChain.node());
 
     // parse parameter list. throw syntax error on illegal identifiers
     int len = p.size();
index 40b5423..2d34c5e 100644 (file)
@@ -49,7 +49,7 @@ static void initializeThreadingOnce()
 #if USE(MULTIPLE_THREADS)
     s_dtoaP5Mutex = new Mutex;
 #if !PLATFORM(DARWIN) // Darwin has pthread_main_np(), and doesn't need registerAsMainThread() called.
-    Collector::registerAsMainThread();
+    Heap::registerAsMainThread();
 #endif
     JSGlobalData::threadInstance();
     UString::null();
@@ -61,6 +61,10 @@ void initializeThreading()
 {
 #if PLATFORM(DARWIN)
     pthread_once(&initializeThreadingKeyOnce, initializeThreadingOnce);
+
+    // FIXME: do we want heap introspector to work on other threads?
+    if (pthread_main_np())
+       JSGlobalData::threadInstance().heap->initializeHeapIntrospector();
 #else
     static bool initializedThreading = false;
     if (!initializedThreading) {
index 325266c..a0a3453 100644 (file)
@@ -186,7 +186,7 @@ JSObject* JSActivation::createArgumentsObject(ExecState* exec)
     int argc;
     exec->machine()->getFunctionAndArguments(registerBase(), callFrame, function, argv, argc);
     ArgList args(reinterpret_cast<JSValue***>(registerBase()), argv - *registerBase(), argc);
-    return new Arguments(exec, function, args, this);
+    return new (exec) Arguments(exec, function, args, this);
 }
 
 } // namespace KJS
index 69547b6..8f9e5c3 100644 (file)
@@ -88,7 +88,7 @@ JSArray::JSArray(JSObject* prototype, unsigned initialLength)
     m_vectorLength = initialCapacity;
     m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
 
-    Collector::reportExtraMemoryCost(initialCapacity * sizeof(JSValue*));
+    Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue*));
 
     checkConsistency();
 }
@@ -146,9 +146,9 @@ JSValue* JSArray::getItem(unsigned i) const
     return value ? value : jsUndefined();
 }
 
-JSValue* JSArray::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue* JSArray::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return jsNumber(static_cast<JSArray*>(slot.slotBase())->m_length);
+    return jsNumber(exec, static_cast<JSArray*>(slot.slotBase())->m_length);
 }
 
 ALWAYS_INLINE bool JSArray::inlineGetOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
index 6db1459..342ad6b 100644 (file)
@@ -113,10 +113,10 @@ JSValue* JSFunction::callerGetter(ExecState* exec, const Identifier&, const Prop
     return exec->machine()->retrieveCaller(exec, thisObj);
 }
 
-JSValue* JSFunction::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue* JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     JSFunction* thisObj = static_cast<JSFunction*>(slot.slotBase());
-    return jsNumber(thisObj->body->parameters().size());
+    return jsNumber(exec, thisObj->body->parameters().size());
 }
 
 bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -195,7 +195,7 @@ JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
     else
         proto = exec->lexicalGlobalObject()->objectPrototype();
 
-    JSObject* thisObj = new JSObject(proto);
+    JSObject* thisObj = new (exec) JSObject(proto);
 
     JSValue* exception = 0;
     JSValue* result = machine().execute(body.get(), exec, this, thisObj, args, &exec->dynamicGlobalObject()->registerFileStack(), _scope.node(), &exception);
@@ -284,7 +284,7 @@ Arguments::Arguments(ExecState* exec, JSFunction* func, const ArgList& args, JSA
     , indexToNameMap(func, args)
 {
     putDirect(exec->propertyNames().callee, func, DontEnum);
-    putDirect(exec->propertyNames().length, args.size(), DontEnum);
+    putDirect(exec, exec->propertyNames().length, args.size(), DontEnum);
   
     int i = 0;
     ArgList::const_iterator end = args.end();
@@ -355,7 +355,7 @@ static JSValue* encode(ExecState* exec, const ArgList& args, const char* do_not_
       r += tmp;
     }
   }
-  return jsString(r);
+  return jsString(exec, r);
 }
 
 static JSValue* decode(ExecState* exec, const ArgList& args, const char* do_not_unescape, bool strict)
@@ -420,7 +420,7 @@ static JSValue* decode(ExecState* exec, const ArgList& args, const char* do_not_
     k++;
     s.append(c);
   }
-  return jsString(s);
+  return jsString(exec, s);
 }
 
 static bool isStrWhiteSpace(unsigned short c)
@@ -592,12 +592,12 @@ JSValue* globalFuncEval(ExecState* exec, PrototypeReflexiveFunction* function, J
 
 JSValue* globalFuncParseInt(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
+    return jsNumber(exec, parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
 }
 
 JSValue* globalFuncParseFloat(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(parseFloat(args[0]->toString(exec)));
+    return jsNumber(exec, parseFloat(args[0]->toString(exec)));
 }
 
 JSValue* globalFuncIsNaN(ExecState* exec, JSObject*, const ArgList& args)
@@ -672,7 +672,7 @@ JSValue* globalFuncEscape(ExecState* exec, JSObject*, const ArgList& args)
         r += s;
     }
 
-    return jsString(r);
+    return jsString(exec, r);
 }
 
 JSValue* globalFuncUnescape(ExecState* exec, JSObject*, const ArgList& args)
@@ -697,7 +697,7 @@ JSValue* globalFuncUnescape(ExecState* exec, JSObject*, const ArgList& args)
         s += UString(c, 1);
     }
 
-    return jsString(s);
+    return jsString(exec, s);
 }
 
 #ifndef NDEBUG
@@ -717,7 +717,7 @@ PrototypeFunction::PrototypeFunction(ExecState* exec, int len, const Identifier&
     , m_function(function)
 {
     ASSERT_ARG(function, function);
-    putDirect(exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
 }
 
 PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functionPrototype, int len, const Identifier& name, JSMemberFunction function)
@@ -725,7 +725,7 @@ PrototypeFunction::PrototypeFunction(ExecState* exec, FunctionPrototype* functio
     , m_function(function)
 {
     ASSERT_ARG(function, function);
-    putDirect(exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
 }
 
 JSValue* PrototypeFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -742,7 +742,7 @@ PrototypeReflexiveFunction::PrototypeReflexiveFunction(ExecState* exec, Function
 {
     ASSERT_ARG(function, function);
     ASSERT_ARG(cachedGlobalObject, cachedGlobalObject);
-    putDirect(exec->propertyNames().length, jsNumber(len), DontDelete | ReadOnly | DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, len), DontDelete | ReadOnly | DontEnum);
 }
 
 JSValue* PrototypeReflexiveFunction::callAsFunction(ExecState* exec, JSObject* thisObj, const ArgList& args)
index 7a32c5d..5ce6641 100644 (file)
@@ -38,6 +38,7 @@
 #include "Parser.h"
 
 #if USE(MULTIPLE_THREADS)
+#include <wtf/Threading.h>
 #include <wtf/ThreadSpecific.h>
 #endif
 
@@ -55,9 +56,9 @@ extern const HashTable stringTable;
 
 
 JSGlobalData::JSGlobalData()
-//    : heap(new Heap)
+    : heap(new Heap)
 #if USE(MULTIPLE_THREADS)
-    : arrayTable(new HashTable(KJS::arrayTable))
+    , arrayTable(new HashTable(KJS::arrayTable))
     , dateTable(new HashTable(KJS::dateTable))
     , mathTable(new HashTable(KJS::mathTable))
     , numberTable(new HashTable(KJS::numberTable))
@@ -65,7 +66,7 @@ JSGlobalData::JSGlobalData()
     , regExpConstructorTable(new HashTable(KJS::regExpConstructorTable))
     , stringTable(new HashTable(KJS::stringTable))
 #else
-    : arrayTable(&KJS::arrayTable)
+    , arrayTable(&KJS::arrayTable)
     , dateTable(&KJS::dateTable)
     , mathTable(&KJS::mathTable)
     , numberTable(&KJS::numberTable)
@@ -118,4 +119,17 @@ JSGlobalData& JSGlobalData::threadInstance()
 #endif
 }
 
+JSGlobalData& JSGlobalData::sharedInstance()
+{
+    return threadInstance();
+/*
+#if USE(MULTIPLE_THREADS)
+    AtomicallyInitializedStatic(JSGlobalData, sharedInstance);
+#else
+    static JSGlobalData sharedInstance;
+#endif
+    return sharedInstance;
+*/
+}
+
 }
index d35d99f..af3b8de 100644 (file)
@@ -30,7 +30,6 @@
 #define JSGlobalData_h
 
 #include "list.h"
-#include "ustring.h"
 #include <wtf/HashCountedSet.h>
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
@@ -42,7 +41,7 @@ namespace WTF {
 namespace KJS {
 
     class CommonIdentifiers;
-//    class Heap;
+    class Heap;
     class IdentifierTable;
     class JSGlobalObject;
     class Lexer;
@@ -56,8 +55,9 @@ namespace KJS {
     // JavaScriptCore clients, which all share a single JSGlobalData, and thus cannot run concurrently.
     struct JSGlobalData : Noncopyable {
         static JSGlobalData& threadInstance();
+        static JSGlobalData& sharedInstance();
 
-//        Heap* heap;
+        Heap* heap;
 
         const HashTable* arrayTable;
         const HashTable* dateTable;
index f03fbb4..b61ad4e 100644 (file)
@@ -89,20 +89,18 @@ static inline unsigned getCurrentTime()
 #endif
 }
 
-JSGlobalObject* JSGlobalObject::s_head = 0;
-
 JSGlobalObject::~JSGlobalObject()
 {
-    ASSERT(JSLock::currentThreadIsHoldingLock());
-
     if (d()->debugger)
         d()->debugger->detach(this);
 
     d()->next->d()->prev = d()->prev;
     d()->prev->d()->next = d()->next;
-    s_head = d()->next;
-    if (s_head == this)
-        s_head = 0;
+    JSGlobalObject*& headObject = head();
+    if (headObject == this)
+        headObject = d()->next;
+    if (headObject == this)
+        headObject = 0;
 
     HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
     for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
@@ -115,13 +113,13 @@ void JSGlobalObject::init(JSObject* thisValue)
 {
     ASSERT(JSLock::currentThreadIsHoldingLock());
 
-    if (s_head) {
-        d()->prev = s_head;
-        d()->next = s_head->d()->next;
-        s_head->d()->next->d()->prev = this;
-        s_head->d()->next = this;
+    if (JSGlobalObject*& headObject = head()) {
+        d()->prev = headObject;
+        d()->next = headObject->d()->next;
+        headObject->d()->next->d()->prev = this;
+        headObject->d()->next = this;
     } else
-        s_head = d()->next = d()->prev = this;
+        headObject = d()->next = d()->prev = this;
 
     resetTimeoutCheck();
     d()->timeoutTime = 0;
@@ -141,6 +139,8 @@ void JSGlobalObject::init(JSObject* thisValue)
 
 void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
 {
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
     if (symbolTablePut(propertyName, value))
         return;
     return JSVariableObject::put(exec, propertyName, value);
@@ -234,42 +234,42 @@ void JSGlobalObject::reset(JSValue* prototype)
     ExecState* exec = d()->globalExec.get();
 
     // Prototypes
-    d()->functionPrototype = new FunctionPrototype(exec);
-    d()->objectPrototype = new ObjectPrototype(exec, d()->functionPrototype);
+    d()->functionPrototype = new (exec) FunctionPrototype(exec);
+    d()->objectPrototype = new (exec) ObjectPrototype(exec, d()->functionPrototype);
     d()->functionPrototype->setPrototype(d()->objectPrototype);
 
-    d()->arrayPrototype = new ArrayPrototype(exec, d()->objectPrototype);
-    d()->stringPrototype = new StringPrototype(exec, d()->objectPrototype);
-    d()->booleanPrototype = new BooleanPrototype(exec, d()->objectPrototype, d()->functionPrototype);
-    d()->numberPrototype = new NumberPrototype(exec, d()->objectPrototype, d()->functionPrototype);
-    d()->datePrototype = new DatePrototype(exec, d()->objectPrototype);
-    d()->regExpPrototype = new RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype);
-    d()->errorPrototype = new ErrorPrototype(exec, d()->objectPrototype, d()->functionPrototype);
+    d()->arrayPrototype = new (exec) ArrayPrototype(exec, d()->objectPrototype);
+    d()->stringPrototype = new (exec) StringPrototype(exec, d()->objectPrototype);
+    d()->booleanPrototype = new (exec) BooleanPrototype(exec, d()->objectPrototype, d()->functionPrototype);
+    d()->numberPrototype = new (exec) NumberPrototype(exec, d()->objectPrototype, d()->functionPrototype);
+    d()->datePrototype = new (exec) DatePrototype(exec, d()->objectPrototype);
+    d()->regExpPrototype = new (exec) RegExpPrototype(exec, d()->objectPrototype, d()->functionPrototype);
+    d()->errorPrototype = new (exec) ErrorPrototype(exec, d()->objectPrototype, d()->functionPrototype);
     
-    d()->evalErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "EvalError", "EvalError");
-    d()->rangeErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "RangeError", "RangeError");
-    d()->referenceErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "ReferenceError", "ReferenceError");
-    d()->syntaxErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "SyntaxError", "SyntaxError");
-    d()->typeErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "TypeError", "TypeError");
-    d()->URIErrorPrototype = new NativeErrorPrototype(exec, d()->errorPrototype, "URIError", "URIError");
+    d()->evalErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "EvalError", "EvalError");
+    d()->rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "RangeError", "RangeError");
+    d()->referenceErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "ReferenceError", "ReferenceError");
+    d()->syntaxErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "SyntaxError", "SyntaxError");
+    d()->typeErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "TypeError", "TypeError");
+    d()->URIErrorPrototype = new (exec) NativeErrorPrototype(exec, d()->errorPrototype, "URIError", "URIError");
 
     // Constructors
-    d()->objectConstructor = new ObjectConstructor(exec, d()->objectPrototype, d()->functionPrototype);
-    d()->functionConstructor = new FunctionConstructor(exec, d()->functionPrototype);
-    d()->arrayConstructor = new ArrayConstructor(exec, d()->functionPrototype, d()->arrayPrototype);
-    d()->stringConstructor = new StringConstructor(exec, d()->functionPrototype, d()->stringPrototype);
-    d()->booleanConstructor = new BooleanConstructor(exec, d()->functionPrototype, d()->booleanPrototype);
-    d()->numberConstructor = new NumberConstructor(exec, d()->functionPrototype, d()->numberPrototype);
-    d()->dateConstructor = new DateConstructor(exec, d()->functionPrototype, d()->datePrototype);
-    d()->regExpConstructor = new RegExpConstructor(exec, d()->functionPrototype, d()->regExpPrototype);
-    d()->errorConstructor = new ErrorConstructor(exec, d()->functionPrototype, d()->errorPrototype);
+    d()->objectConstructor = new (exec) ObjectConstructor(exec, d()->objectPrototype, d()->functionPrototype);
+    d()->functionConstructor = new (exec) FunctionConstructor(exec, d()->functionPrototype);
+    d()->arrayConstructor = new (exec) ArrayConstructor(exec, d()->functionPrototype, d()->arrayPrototype);
+    d()->stringConstructor = new (exec) StringConstructor(exec, d()->functionPrototype, d()->stringPrototype);
+    d()->booleanConstructor = new (exec) BooleanConstructor(exec, d()->functionPrototype, d()->booleanPrototype);
+    d()->numberConstructor = new (exec) NumberConstructor(exec, d()->functionPrototype, d()->numberPrototype);
+    d()->dateConstructor = new (exec) DateConstructor(exec, d()->functionPrototype, d()->datePrototype);
+    d()->regExpConstructor = new (exec) RegExpConstructor(exec, d()->functionPrototype, d()->regExpPrototype);
+    d()->errorConstructor = new (exec) ErrorConstructor(exec, d()->functionPrototype, d()->errorPrototype);
     
-    d()->evalErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->evalErrorPrototype);
-    d()->rangeErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->rangeErrorPrototype);
-    d()->referenceErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->referenceErrorPrototype);
-    d()->syntaxErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->syntaxErrorPrototype);
-    d()->typeErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->typeErrorPrototype);
-    d()->URIErrorConstructor = new NativeErrorConstructor(exec, d()->functionPrototype, d()->URIErrorPrototype);
+    d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->evalErrorPrototype);
+    d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->rangeErrorPrototype);
+    d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->referenceErrorPrototype);
+    d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->syntaxErrorPrototype);
+    d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->typeErrorPrototype);
+    d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, d()->functionPrototype, d()->URIErrorPrototype);
     
     d()->functionPrototype->putDirect(exec->propertyNames().constructor, d()->functionConstructor, DontEnum);
 
@@ -311,9 +311,9 @@ void JSGlobalObject::reset(JSValue* prototype)
 
     // Set global values.
     GlobalPropertyInfo staticGlobals[] = {
-        GlobalPropertyInfo(Identifier(exec, "Math"), new MathObject(exec, d()->objectPrototype), DontEnum | DontDelete),
-        GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(), DontEnum | DontDelete),
-        GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(Inf), DontEnum | DontDelete),
+        GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, d()->objectPrototype), DontEnum | DontDelete),
+        GlobalPropertyInfo(Identifier(exec, "NaN"), jsNaN(exec), DontEnum | DontDelete),
+        GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(exec, Inf), DontEnum | DontDelete),
         GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete)
     };
 
@@ -321,20 +321,20 @@ void JSGlobalObject::reset(JSValue* prototype)
 
     // Set global functions.
 
-    d()->evalFunction = new PrototypeReflexiveFunction(exec, d()->functionPrototype, 1, exec->propertyNames().eval, globalFuncEval, this);
+    d()->evalFunction = new (exec) PrototypeReflexiveFunction(exec, d()->functionPrototype, 1, exec->propertyNames().eval, globalFuncEval, this);
     putDirectFunction(d()->evalFunction, DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
 #ifndef NDEBUG
-    putDirectFunction(new PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "kjsprint"), globalFuncKJSPrint), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, d()->functionPrototype, 1, Identifier(exec, "kjsprint"), globalFuncKJSPrint), DontEnum);
 #endif
 
     // Set prototype, and also insert the object prototype at the end of the chain.
@@ -411,7 +411,7 @@ void JSGlobalObject::mark()
     for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
         (*it)->mark();
 
-    registerFileStack().mark();
+    registerFileStack().mark(globalData()->heap);
 
     markIfNeeded(d()->globalExec->exception());
 
@@ -465,5 +465,22 @@ bool JSGlobalObject::isDynamicScope() const
     return true;
 }
 
+void* JSGlobalObject::operator new(size_t size)
+{
+#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+    return JSGlobalData::threadInstance().heap->inlineAllocate(size);
+#else
+    return JSGlobalData::threadInstance().heap->allocate(size);
+#endif
+}
+
+void* JSGlobalObject::operator new(size_t size, SharedTag)
+{
+#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+    return JSGlobalData::sharedInstance().heap->inlineAllocate(size);
+#else
+    return JSGlobalData::sharedInstance().heap->allocate(size);
+#endif
+}
 
 } // namespace KJS
index 4f7ec6a..3dbca28 100644 (file)
@@ -170,7 +170,6 @@ namespace KJS {
         virtual void put(ExecState*, const Identifier&, JSValue*);
         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);
 
@@ -260,6 +259,10 @@ namespace KJS {
         // Per-thread hash tables, cached on the global object for faster access.
         JSGlobalData* globalData() { return d()->globalData; }
 
+        enum SharedTag { Shared };
+        void* operator new(size_t);
+        void* operator new(size_t, SharedTag);
+
         void init(JSObject* thisValue);
         
         JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
@@ -282,8 +285,6 @@ namespace KJS {
     private:
         bool checkTimeout();
         void resetTimeoutCheck();
-
-        static JSGlobalObject* s_head;
     };
 
     inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
index b1483e4..abc579d 100644 (file)
@@ -33,9 +33,9 @@ JSObject *JSImmediate::toObject(const JSValue *v, ExecState *exec)
 {
     ASSERT(isImmediate(v));
     if (v == jsNull())
-        return new JSNotAnObject(throwError(exec, TypeError, "Null value"));
+        return new (exec) JSNotAnObject(throwError(exec, TypeError, "Null value"));
     else if (v == jsUndefined())
-        return new JSNotAnObject(throwError(exec, TypeError, "Undefined value"));
+        return new (exec) JSNotAnObject(throwError(exec, TypeError, "Undefined value"));
     else if (isBoolean(v)) {
         ArgList args;
         args.append(const_cast<JSValue *>(v));
index e6c5fbe..266f6b7 100644 (file)
@@ -352,6 +352,21 @@ ALWAYS_INLINE JSType JSImmediate::type(const JSValue* v)
     return static_cast<JSType>(tag);
 }
 
+ALWAYS_INLINE JSValue* jsUndefined()
+{
+    return JSImmediate::undefinedImmediate();
+}
+
+inline JSValue* jsNull()
+{
+    return JSImmediate::nullImmediate();
+}
+
+inline JSValue* jsBoolean(bool b)
+{
+    return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
+}
+
 } // namespace KJS
 
 #endif
index 9d51ca9..dbddb73 100644 (file)
@@ -82,7 +82,7 @@ bool JSLock::currentThreadIsHoldingLock()
 
 void JSLock::registerThread()
 {
-    Collector::registerThread();
+    Heap::registerThread();
 }
 
 JSLock::DropAllLocks::DropAllLocks()
index ce28a5b..c55873a 100644 (file)
@@ -96,6 +96,7 @@ static void throwSetterError(ExecState *exec)
 void JSObject::put(ExecState* exec, const Identifier &propertyName, JSValue *value)
 {
   ASSERT(value);
+  ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
   if (propertyName == exec->propertyNames().underscoreProto) {
     JSObject* proto = value->getObject();
@@ -293,7 +294,7 @@ const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifi
     return 0;
 }
 
-void JSObject::defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc)
+void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunc)
 {
     JSValue *o = getDirect(propertyName);
     GetterSetter *gs;
@@ -301,7 +302,7 @@ void JSObject::defineGetter(ExecState*, const Identifier& propertyName, JSObject
     if (o && o->type() == GetterSetterType) {
         gs = static_cast<GetterSetter *>(o);
     } else {
-        gs = new GetterSetter;
+        gs = new (exec) GetterSetter;
         putDirect(propertyName, gs, IsGetterSetter);
     }
     
@@ -309,7 +310,7 @@ void JSObject::defineGetter(ExecState*, const Identifier& propertyName, JSObject
     gs->setGetter(getterFunc);
 }
 
-void JSObject::defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc)
+void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunc)
 {
     JSValue *o = getDirect(propertyName);
     GetterSetter *gs;
@@ -317,7 +318,7 @@ void JSObject::defineSetter(ExecState*, const Identifier& propertyName, JSObject
     if (o && o->type() == GetterSetterType) {
         gs = static_cast<GetterSetter *>(o);
     } else {
-        gs = new GetterSetter;
+        gs = new (exec) GetterSetter;
         putDirect(propertyName, gs, IsGetterSetter);
     }
     
@@ -556,18 +557,18 @@ JSObject* Error::create(ExecState* exec, ErrorType errtype, const UString& messa
 
   ArgList args;
   if (message.isEmpty())
-    args.append(jsString(name));
+    args.append(jsString(exec, name));
   else
-    args.append(jsString(message));
+    args.append(jsString(exec, message));
   JSObject *err = static_cast<JSObject *>(cons->construct(exec,args));
 
   if (lineno != -1)
-    err->put(exec, Identifier(exec, "line"), jsNumber(lineno));
+    err->put(exec, Identifier(exec, "line"), jsNumber(exec, lineno));
   if (sourceId != -1)
-    err->put(exec, Identifier(exec, "sourceId"), jsNumber(sourceId));
+    err->put(exec, Identifier(exec, "sourceId"), jsNumber(exec, sourceId));
 
   if(!sourceURL.isNull())
-    err->put(exec, Identifier(exec, "sourceURL"), jsString(sourceURL));
+    err->put(exec, Identifier(exec, "sourceURL"), jsString(exec, sourceURL));
  
   return err;
 }
index 4fc0064..5053150 100644 (file)
@@ -420,7 +420,7 @@ namespace KJS {
    JSValue **getDirectLocation(const Identifier& propertyName, bool& isWriteable)
         { return _prop.getLocation(propertyName, isWriteable); }
     void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0);
-    void putDirect(const Identifier &propertyName, int value, int attr = 0);
+    void putDirect(ExecState*, const Identifier& propertyName, int value, int attr = 0);
     void removeDirect(const Identifier &propertyName);
     
     // convenience to add a function property under the function's own built-in name
@@ -486,6 +486,7 @@ inline JSObject::JSObject(JSValue* proto)
     : _proto(proto)
 {
     ASSERT(proto);
+    ASSERT(Heap::heap(this) == Heap::heap(proto));
 }
 
 inline JSObject::JSObject()
@@ -629,9 +630,9 @@ inline void JSObject::putDirect(const Identifier &propertyName, JSValue *value,
     _prop.put(propertyName, value, attr);
 }
 
-inline void JSObject::putDirect(const Identifier &propertyName, int value, int attr)
+inline void JSObject::putDirect(ExecState* exec, const Identifier &propertyName, int value, int attr)
 {
-    _prop.put(propertyName, jsNumber(value), attr);
+    _prop.put(propertyName, jsNumber(exec, value), attr);
 }
 
 inline JSValue* JSObject::toPrimitive(ExecState* exec, JSType preferredType) const
index 9214385..f6de21e 100644 (file)
@@ -31,7 +31,7 @@ namespace KJS {
 
   class JSString : public JSCell {
   public:
-    JSString(const UString& value) : m_value(value) { Collector::reportExtraMemoryCost(value.cost()); }
+    JSString(const UString& value) : m_value(value) { Heap::heap(this)->reportExtraMemoryCost(value.cost()); }
     enum HasOtherOwnerType { HasOtherOwner };
     JSString(const UString& value, HasOtherOwnerType) : m_value(value) { }
 
index 1c8dc01..6fa618d 100644 (file)
@@ -80,9 +80,13 @@ extern const double Inf = NaNInf.doubles.Inf_Double;
 static const double D16 = 65536.0;
 static const double D32 = 4294967296.0;
 
-void* JSCell::operator new(size_t size)
+void* JSCell::operator new(size_t size, ExecState* exec)
 {
-    return Collector::allocate(size);
+#ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
+    return exec->heap()->inlineAllocate(size);
+#else
+    return exec->heap()->allocate(size);
+#endif
 }
 
 bool JSCell::getUInt32(uint32_t&) const
@@ -256,19 +260,19 @@ JSObject* JSCell::toThisObject(ExecState* exec) const
     return toObject(exec);
 }
 
-JSCell* jsString(const char* s)
+JSCell* jsString(ExecState* exec, const char* s)
 {
-    return new JSString(s ? s : "");
+    return new (exec) JSString(s ? s : "");
 }
 
-JSCell* jsString(const UString& s)
+JSCell* jsString(ExecState* exec, const UString& s)
 {
-    return s.isNull() ? new JSString("") : new JSString(s);
+    return s.isNull() ? new (exec) JSString("") : new (exec) JSString(s);
 }
 
-JSCell* jsOwnedString(const UString& s)
+JSCell* jsOwnedString(ExecState* exec, const UString& s)
 {
-    return s.isNull() ? new JSString("", JSString::HasOtherOwner) : new JSString(s, JSString::HasOtherOwner);
+    return s.isNull() ? new (exec) JSString("", JSString::HasOtherOwner) : new (exec) JSString(s, JSString::HasOtherOwner);
 }
 
 } // namespace KJS
index 1c8f8ba..7d4c5a7 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "CallData.h"
 #include "ConstructData.h"
+#include "ExecState.h"
 #include "JSImmediate.h"
 #include "collector.h"
 #include "ustring.h"
@@ -51,7 +52,7 @@ struct Instruction;
  */
 class JSValue : Noncopyable {
     friend class JSCell; // so it can derive from this class
-    friend class Collector; // so it can call asCell()
+    friend class Heap; // so it can call asCell()
 private:
     JSValue();
     virtual ~JSValue();
@@ -141,7 +142,7 @@ private:
 };
 
 class JSCell : public JSValue {
-    friend class Collector;
+    friend class Heap;
     friend class GetterSetter;
     friend class JSObject;
     friend class JSPropertyNameIterator;
@@ -185,7 +186,7 @@ public:
     virtual JSObject* toObject(ExecState*) const = 0;
 
     // Garbage collection.
-    void* operator new(size_t);
+    void* operator new(size_t, ExecState*);
     virtual void mark();
     bool marked() const;
 
@@ -201,7 +202,7 @@ private:
 };
 
 class JSNumberCell : public JSCell {
-    friend JSValue* jsNumberCell(double);
+    friend JSValue* jsNumberCell(ExecState*, double);
 public:
     double value() const { return val; }
 
@@ -215,12 +216,12 @@ public:
     virtual JSObject* toObject(ExecState*) const;
     virtual JSObject* toThisObject(ExecState*) const;
 
-    void* operator new(size_t size)
+    void* operator new(size_t size, ExecState* exec)
     {
 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
-        return Collector::inlineAllocateNumber(size);
+        return exec->heap()->inlineAllocateNumber(size);
 #else
-        return Collector::allocateNumber(size);
+        return exec->heap()->allocateNumber(size);
 #endif
     }
 
@@ -237,91 +238,69 @@ private:
     double val;
 };
 
-JSCell* jsString(const UString&); // returns empty string if passed null string
-JSCell* jsString(const char* = ""); // returns empty string if passed 0
+JSCell* jsString(ExecState*, const UString&); // returns empty string if passed null string
+JSCell* jsString(ExecState*, const char* = ""); // returns empty string if passed 0
 
 // should be used for strings that are owned by an object that will
 // likely outlive the JSValue this makes, such as the parse tree or a
 // DOM object that contains a UString
-JSCell* jsOwnedString(const UString&); 
+JSCell* jsOwnedString(ExecState*, const UString&); 
 
 extern const double NaN;
 extern const double Inf;
 
 // Beware marking this function ALWAYS_INLINE: It takes a PIC branch, so
 // inlining it may not always be a win.
-inline JSValue* jsNumberCell(double d)
+inline JSValue* jsNumberCell(ExecState* exec, double d)
 {
-    return new JSNumberCell(d);
+    return new (exec) JSNumberCell(d);
 }
 
-ALWAYS_INLINE JSValue* jsUndefined()
+inline JSValue* jsNaN(ExecState* exec)
 {
-    return JSImmediate::undefinedImmediate();
+    return jsNumberCell(exec, NaN);
 }
 
-inline JSValue* jsNull()
-{
-    return JSImmediate::nullImmediate();
-}
-
-inline JSValue* jsNaN()
-{
-    return jsNumberCell(NaN);
-}
-
-inline JSValue* jsBoolean(bool b)
-{
-    return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
-}
-
-ALWAYS_INLINE JSValue* jsNumber(double d)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, double d)
 {
     JSValue* v = JSImmediate::from(d);
-    return v ? v : jsNumberCell(d);
+    return v ? v : jsNumberCell(exec, d);
 }
 
-ALWAYS_INLINE JSValue* jsNumber(int i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, int i)
 {
     JSValue* v = JSImmediate::from(i);
-    return v ? v : jsNumberCell(i);
+    return v ? v : jsNumberCell(exec, i);
 }
 
-ALWAYS_INLINE JSValue* jsNumber(unsigned i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned i)
 {
     JSValue* v = JSImmediate::from(i);
-    return v ? v : jsNumberCell(i);
+    return v ? v : jsNumberCell(exec, i);
 }
 
-ALWAYS_INLINE JSValue* jsNumber(long i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long i)
 {
     JSValue* v = JSImmediate::from(i);
-    return v ? v : jsNumberCell(i);
+    return v ? v : jsNumberCell(exec, i);
 }
 
-ALWAYS_INLINE JSValue* jsNumber(unsigned long i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long i)
 {
     JSValue* v = JSImmediate::from(i);
-    return v ? v : jsNumberCell(i);
+    return v ? v : jsNumberCell(exec, i);
 }
 
-ALWAYS_INLINE JSValue* jsNumber(long long i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, long long i)
 {
     JSValue* v = JSImmediate::from(i);
-    return v ? v : jsNumberCell(static_cast<double>(i));
+    return v ? v : jsNumberCell(exec, static_cast<double>(i));
 }
 
-ALWAYS_INLINE JSValue* jsNumber(unsigned long long i)
+ALWAYS_INLINE JSValue* jsNumber(ExecState* exec, unsigned long long i)
 {
     JSValue* v = JSImmediate::from(i);
-    return v ? v : jsNumberCell(static_cast<double>(i));
-}
-
-ALWAYS_INLINE JSValue* jsNumberFromAnd(ExecState *exec, JSValue* v1, JSValue* v2)
-{
-    if (JSImmediate::areBothImmediateNumbers(v1, v2))
-        return JSImmediate::andImmediateNumbers(v1, v2);
-    return jsNumber(v1->toInt32(exec) & v2->toInt32(exec));
+    return v ? v : jsNumberCell(exec, static_cast<double>(i));
 }
 
 inline JSValue::JSValue()
@@ -357,12 +336,12 @@ inline bool JSCell::isObject() const
 
 inline bool JSCell::marked() const
 {
-    return Collector::isCellMarked(this);
+    return Heap::isCellMarked(this);
 }
 
 inline void JSCell::mark()
 {
-    return Collector::markCell(this);
+    return Heap::markCell(this);
 }
 
 ALWAYS_INLINE JSCell* JSValue::asCell()
@@ -535,7 +514,7 @@ ALWAYS_INLINE double JSValue::toNumber(ExecState *exec) const
 
 ALWAYS_INLINE JSValue* JSValue::toJSNumber(ExecState* exec) const
 {
-    return JSImmediate::isNumber(this) ? const_cast<JSValue*>(this) : jsNumber(this->toNumber(exec));
+    return JSImmediate::isNumber(this) ? const_cast<JSValue*>(this) : jsNumber(exec, this->toNumber(exec));
 }
 
 inline UString JSValue::toString(ExecState *exec) const
index d198899..870c58d 100644 (file)
@@ -76,25 +76,25 @@ bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
     return getStaticPropertySlot<MathObject, JSObject>(exec, ExecState::mathTable(exec), this, propertyName, slot);
 }
 
-JSValue* MathObject::getValueProperty(ExecState*, int token) const
+JSValue* MathObject::getValueProperty(ExecState* exec, int token) const
 {
     switch (token) {
     case Euler:
-        return jsNumber(exp(1.0));
+        return jsNumber(exec, exp(1.0));
     case Ln2:
-        return jsNumber(log(2.0));
+        return jsNumber(exec, log(2.0));
     case Ln10:
-        return jsNumber(log(10.0));
+        return jsNumber(exec, log(10.0));
     case Log2E:
-        return jsNumber(1.0 / log(2.0));
+        return jsNumber(exec, 1.0 / log(2.0));
     case Log10E:
-        return jsNumber(1.0 / log(10.0));
+        return jsNumber(exec, 1.0 / log(10.0));
     case Pi:
-        return jsNumber(piDouble);
+        return jsNumber(exec, piDouble);
     case Sqrt1_2:
-        return jsNumber(sqrt(0.5));
+        return jsNumber(exec, sqrt(0.5));
     case Sqrt2:
-        return jsNumber(sqrt(2.0));
+        return jsNumber(exec, sqrt(2.0));
     }
 
     ASSERT_NOT_REACHED();
@@ -106,58 +106,58 @@ JSValue* MathObject::getValueProperty(ExecState*, int token) const
 JSValue* mathProtoFuncAbs(ExecState* exec, JSObject*, const ArgList& args)
 {
     double arg = args[0]->toNumber(exec);
-    return signbit(arg) ? jsNumber(-arg) : jsNumber(arg);
+    return signbit(arg) ? jsNumber(exec, -arg) : jsNumber(exec, arg);
 }
 
 JSValue* mathProtoFuncACos(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(acos(args[0]->toNumber(exec)));
+    return jsNumber(exec, acos(args[0]->toNumber(exec)));
 }
 
 JSValue* mathProtoFuncASin(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(asin(args[0]->toNumber(exec)));
+    return jsNumber(exec, asin(args[0]->toNumber(exec)));
 }
 
 JSValue* mathProtoFuncATan(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(atan(args[0]->toNumber(exec)));
+    return jsNumber(exec, atan(args[0]->toNumber(exec)));
 }
 
 JSValue* mathProtoFuncATan2(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(atan2(args[0]->toNumber(exec), args[1]->toNumber(exec)));
+    return jsNumber(exec, atan2(args[0]->toNumber(exec), args[1]->toNumber(exec)));
 }
 
 JSValue* mathProtoFuncCeil(ExecState* exec, JSObject*, const ArgList& args)
 {
     double arg = args[0]->toNumber(exec);
     if (signbit(arg) && arg > -1.0)
-        return jsNumber(-0.0);
-    return jsNumber(ceil(arg));
+        return jsNumber(exec, -0.0);
+    return jsNumber(exec, ceil(arg));
 }
 
 JSValue* mathProtoFuncCos(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(cos(args[0]->toNumber(exec)));
+    return jsNumber(exec, cos(args[0]->toNumber(exec)));
 }
 
 JSValue* mathProtoFuncExp(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(exp(args[0]->toNumber(exec)));
+    return jsNumber(exec, exp(args[0]->toNumber(exec)));
 }
 
 JSValue* mathProtoFuncFloor(ExecState* exec, JSObject*, const ArgList& args)
 {
     double arg = args[0]->toNumber(exec);
     if (signbit(arg) && arg == 0.0)
-        return jsNumber(-0.0);
-    return jsNumber(floor(arg));
+        return jsNumber(exec, -0.0);
+    return jsNumber(exec, floor(arg));
 }
 
 JSValue* mathProtoFuncLog(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(log(args[0]->toNumber(exec)));
+    return jsNumber(exec, log(args[0]->toNumber(exec)));
 }
 
 JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, const ArgList& args)
@@ -173,7 +173,7 @@ JSValue* mathProtoFuncMax(ExecState* exec, JSObject*, const ArgList& args)
         if (val > result || (val == 0 && result == 0 && !signbit(val)))
             result = val;
     }
-    return jsNumber(result);
+    return jsNumber(exec, result);
 }
 
 JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, const ArgList& args)
@@ -189,7 +189,7 @@ JSValue* mathProtoFuncMin(ExecState* exec, JSObject*, const ArgList& args)
         if (val < result || (val == 0 && result == 0 && signbit(val)))
             result = val;
     }
-    return jsNumber(result);
+    return jsNumber(exec, result);
 }
 
 JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, const ArgList& args)
@@ -200,13 +200,13 @@ JSValue* mathProtoFuncPow(ExecState* exec, JSObject*, const ArgList& args)
     double arg2 = args[1]->toNumber(exec);
 
     if (isnan(arg2))
-        return jsNaN();
+        return jsNaN(exec);
     if (isinf(arg2) && fabs(arg) == 1)
-        return jsNaN();
-    return jsNumber(pow(arg, arg2));
+        return jsNaN(exec);
+    return jsNumber(exec, pow(arg, arg2));
 }
 
-JSValue* mathProtoFuncRandom(ExecState*, JSObject*, const ArgList&)
+JSValue* mathProtoFuncRandom(ExecState* exec, JSObject*, const ArgList&)
 {
 #if !USE(MULTIPLE_THREADS)
     static bool didInitRandom;
@@ -216,30 +216,30 @@ JSValue* mathProtoFuncRandom(ExecState*, JSObject*, const ArgList&)
     }
 #endif
 
-    return jsNumber(wtf_random());
+    return jsNumber(exec, wtf_random());
 }
 
 JSValue* mathProtoFuncRound(ExecState* exec, JSObject*, const ArgList& args)
 {
     double arg = args[0]->toNumber(exec);
     if (signbit(arg) && arg >= -0.5)
-         return jsNumber(-0.0);
-    return jsNumber(floor(arg + 0.5));
+         return jsNumber(exec, -0.0);
+    return jsNumber(exec, floor(arg + 0.5));
 }
 
 JSValue* mathProtoFuncSin(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(sin(args[0]->toNumber(exec)));
+    return jsNumber(exec, sin(args[0]->toNumber(exec)));
 }
 
 JSValue* mathProtoFuncSqrt(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(sqrt(args[0]->toNumber(exec)));
+    return jsNumber(exec, sqrt(args[0]->toNumber(exec)));
 }
 
 JSValue* mathProtoFuncTan(ExecState* exec, JSObject*, const ArgList& args)
 {
-    return jsNumber(tan(args[0]->toNumber(exec)));
+    return jsNumber(exec, tan(args[0]->toNumber(exec)));
 }
 
 } // namespace KJS
index 954fcef..707fe4a 100644 (file)
@@ -55,16 +55,16 @@ static JSValue* numberProtoFuncToPrecision(ExecState*, JSObject*, const ArgList&
 NumberPrototype::NumberPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype)
     : NumberObject(objectPrototype)
 {
-    setInternalValue(jsNumber(0));
+    setInternalValue(jsNumber(exec, 0));
 
     // The constructor will be added later, after NumberConstructor has been constructed
 
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
 }
 
 // ------------------------------ Functions ---------------------------
@@ -151,7 +151,7 @@ JSValue* numberProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLi
 
     double radixAsDouble = args[0]->toInteger(exec); // nan -> 0
     if (radixAsDouble == 10 || args[0]->isUndefined())
-        return jsString(v->toString(exec));
+        return jsString(exec, v->toString(exec));
 
     if (radixAsDouble < 2 || radixAsDouble > 36)
         return throwError(exec, RangeError, "toString() radix argument must be between 2 and 36");
@@ -165,7 +165,7 @@ JSValue* numberProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLi
     const char* lastCharInString = s + sizeof(s) - 1;
     double x = v->toNumber(exec);
     if (isnan(x) || isinf(x))
-        return jsString(UString::from(x));
+        return jsString(exec, UString::from(x));
 
     bool isNegative = x < 0.0;
     if (isNegative)
@@ -204,7 +204,7 @@ JSValue* numberProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLi
     *p = '\0';
     ASSERT(p < s + sizeof(s));
 
-    return jsString(startOfResultString);
+    return jsString(exec, startOfResultString);
 }
 
 JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -213,7 +213,7 @@ JSValue* numberProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const
         return throwError(exec, TypeError);
 
     // TODO
-    return jsString(static_cast<NumberObject*>(thisObj)->internalValue()->toString(exec));
+    return jsString(exec, static_cast<NumberObject*>(thisObj)->internalValue()->toString(exec));
 }
 
 JSValue* numberProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -239,7 +239,7 @@ JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject* thisObj, const ArgLis
 
     double x = v->toNumber(exec);
     if (isnan(x))
-        return jsString("NaN");
+        return jsString(exec, "NaN");
 
     UString s;
     if (x < 0) {
@@ -249,7 +249,7 @@ JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject* thisObj, const ArgLis
         x = 0;
 
     if (x >= pow(10.0, 21.0))
-        return jsString(s + UString::from(x));
+        return jsString(exec, s + UString::from(x));
 
     const double tenToTheF = pow(10.0, f);
     double n = floor(x * tenToTheF);
@@ -269,8 +269,8 @@ JSValue* numberProtoFuncToFixed(ExecState* exec, JSObject* thisObj, const ArgLis
     }
     int kMinusf = k - f;
     if (kMinusf < m.size())
-        return jsString(s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
-    return jsString(s + m.substr(0, kMinusf));
+        return jsString(exec, s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
+    return jsString(exec, s + m.substr(0, kMinusf));
 }
 
 static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits)
@@ -320,7 +320,7 @@ JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject* thisObj, const
     double x = v->toNumber(exec);
 
     if (isnan(x) || isinf(x))
-        return jsString(UString::from(x));
+        return jsString(exec, UString::from(x));
 
     JSValue* fractionalDigitsValue = args[0];
     double df = fractionalDigitsValue->toInteger(exec);
@@ -346,7 +346,7 @@ JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject* thisObj, const
     }
 
     if (isnan(x))
-        return jsString("NaN");
+        return jsString(exec, "NaN");
 
     if (x == -0.0) // (-0.0).toExponential() should print as 0 instead of -0
         x = 0;
@@ -378,7 +378,7 @@ JSValue* numberProtoFuncToExponential(ExecState* exec, JSObject* thisObj, const
 
     freedtoa(result);
 
-    return jsString(buf);
+    return jsString(exec, buf);
 }
 
 JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -391,7 +391,7 @@ JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject* thisObj, const Ar
     double doublePrecision = args[0]->toIntegerPreserveNaN(exec);
     double x = v->toNumber(exec);
     if (args[0]->isUndefined() || isnan(x) || isinf(x))
-        return jsString(v->toString(exec));
+        return jsString(exec, v->toString(exec));
 
     UString s;
     if (x < 0) {
@@ -430,8 +430,8 @@ JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject* thisObj, const Ar
             if (m.size() > 1)
                 m = m.substr(0, 1) + "." + m.substr(1);
             if (e >= 0)
-                return jsString(s + m + "e+" + UString::from(e));
-            return jsString(s + m + "e-" + UString::from(-e));
+                return jsString(exec, s + m + "e+" + UString::from(e));
+            return jsString(exec, s + m + "e-" + UString::from(-e));
         }
     } else {
         m = char_sequence('0', precision);
@@ -439,13 +439,13 @@ JSValue* numberProtoFuncToPrecision(ExecState* exec, JSObject* thisObj, const Ar
     }
 
     if (e == precision - 1)
-        return jsString(s + m);
+        return jsString(exec, s + m);
     if (e >= 0) {
         if (e + 1 < m.size())
-            return jsString(s + m.substr(0, e + 1) + "." + m.substr(e + 1));
-        return jsString(s + m);
+            return jsString(exec, s + m.substr(0, e + 1) + "." + m.substr(e + 1));
+        return jsString(exec, s + m);
     }
-    return jsString(s + "0." + char_sequence('0', -(e + 1)) + m);
+    return jsString(exec, s + "0." + char_sequence('0', -(e + 1)) + m);
 }
 
 // ------------------------------ NumberConstructor ------------------------------
@@ -468,7 +468,7 @@ NumberConstructor::NumberConstructor(ExecState* exec, FunctionPrototype* funcPro
     putDirect(exec->propertyNames().prototype, numberProto, DontEnum|DontDelete|ReadOnly);
 
     // no. of arguments for constructor
-    putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
 }
 
 bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -476,20 +476,20 @@ bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr
     return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot);
 }
 
-JSValue* NumberConstructor::getValueProperty(ExecState*, int token) const
+JSValue* NumberConstructor::getValueProperty(ExecState* exec, int token) const
 {
     // ECMA 15.7.3
     switch (token) {
         case NaNValue:
-            return jsNaN();
+            return jsNaN(exec);
         case NegInfinity:
-            return jsNumberCell(-Inf);
+            return jsNumberCell(exec, -Inf);
         case PosInfinity:
-            return jsNumberCell(Inf);
+            return jsNumberCell(exec, Inf);
         case MaxValue:
-            return jsNumberCell(1.7976931348623157E+308);
+            return jsNumberCell(exec, 1.7976931348623157E+308);
         case MinValue:
-            return jsNumberCell(5E-324);
+            return jsNumberCell(exec, 5E-324);
     }
     ASSERT_NOT_REACHED();
     return jsNull();
@@ -504,11 +504,11 @@ ConstructType NumberConstructor::getConstructData(ConstructData&)
 JSObject* NumberConstructor::construct(ExecState* exec, const ArgList& args)
 {
     JSObject* proto = exec->lexicalGlobalObject()->numberPrototype();
-    NumberObject* obj = new NumberObject(proto);
+    NumberObject* obj = new (exec) NumberObject(proto);
 
     // FIXME: Check args[0]->isUndefined() instead of args.isEmpty()?
     double n = args.isEmpty() ? 0 : args[0]->toNumber(exec);
-    obj->setInternalValue(jsNumber(n));
+    obj->setInternalValue(jsNumber(exec, n));
     return obj;
 }
 
@@ -516,7 +516,7 @@ JSObject* NumberConstructor::construct(ExecState* exec, const ArgList& args)
 JSValue* NumberConstructor::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
 {
     // FIXME: Check args[0]->isUndefined() instead of args.isEmpty()?
-    return jsNumber(args.isEmpty() ? 0 : args[0]->toNumber(exec));
+    return jsNumber(exec, args.isEmpty() ? 0 : args[0]->toNumber(exec));
 }
 
 } // namespace KJS
index 28b5575..0cd50a6 100644 (file)
@@ -35,27 +35,6 @@ namespace KJS {
     struct PropertyMapEntry;
     struct PropertyMapHashTable;
 
-    class SavedProperty : Noncopyable {
-    public:
-        // Since we use this in arrays, we allocate it uninitialized
-        // and then explicitly initialize. This means we can allocate
-        // the array without initializing every saved property in the
-        // array twice. To accomplish this, the class uses data members
-        // with types that don't have constructors.
-        SavedProperty();
-        void init(UString::Rep* name, JSValue*, unsigned attributes);
-        ~SavedProperty();
-
-        UString::Rep* name() const;
-        JSValue* value() const;
-        unsigned attributes() const;
-
-    private:
-        UString::Rep* m_name;
-        JSValue* m_value;
-        unsigned m_attributes;
-    };
-
     class PropertyMap : Noncopyable {
     public:
         PropertyMap();
@@ -110,65 +89,6 @@ namespace KJS {
 
     {
     }
-
-    inline SavedProperty::SavedProperty()
-#ifndef NDEBUG
-        : m_name(0)
-        , m_value(0)
-        , m_attributes(0)
-#endif
-    {
-    }
-
-    inline void SavedProperty::init(UString::Rep* name, JSValue* value, unsigned attributes)
-    {
-        ASSERT(name);
-        ASSERT(value);
-
-        ASSERT(!m_name);
-        ASSERT(!m_value);
-        ASSERT(!m_attributes);
-
-        m_name = name;
-        m_value = value;
-        m_attributes = attributes;
-        name->ref();
-        gcProtect(value);
-    }
-
-    inline SavedProperty::~SavedProperty()
-    {
-        ASSERT(m_name);
-        ASSERT(m_value);
-
-        m_name->deref();
-        gcUnprotect(m_value);
-    }
-
-    inline UString::Rep* SavedProperty::name() const
-    {
-        ASSERT(m_name);
-        ASSERT(m_value);
-
-        return m_name;
-    }
-
-    inline JSValue* SavedProperty::value() const
-    {
-        ASSERT(m_name);
-        ASSERT(m_value);
-
-        return m_value;
-    }
-
-    inline unsigned SavedProperty::attributes() const
-    {
-        ASSERT(m_name);
-        ASSERT(m_value);
-
-        return m_attributes;
-    }
-
 } // namespace
 
 #endif // _KJS_PROPERTY_MAP_H_
index bbc7ec5..e2265ed 100644 (file)
@@ -50,10 +50,10 @@ const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0, 0 };
 RegExpPrototype::RegExpPrototype(ExecState* exec, ObjectPrototype* objectPrototype, FunctionPrototype* functionPrototype)
     : JSObject(objectPrototype)
 {
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
 }
 
 // ------------------------------ Functions ---------------------------
@@ -105,7 +105,7 @@ JSValue* regExpProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLi
 {
     if (!thisObj->inherits(&RegExpObject::info)) {
         if (thisObj->inherits(&RegExpPrototype::info))
-            return jsString("//");
+            return jsString(exec, "//");
         return throwError(exec, TypeError);
     }
 
@@ -116,7 +116,7 @@ JSValue* regExpProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLi
         result += "i";
     if (thisObj->get(exec, exec->propertyNames().multiline)->toBoolean(exec))
         result += "m";
-    return jsString(result);
+    return jsString(exec, result);
 }
 
 // ------------------------------ RegExpObject ------------------------------------
@@ -149,7 +149,7 @@ bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propert
   return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
 }
 
-JSValue* RegExpObject::getValueProperty(ExecState*, int token) const
+JSValue* RegExpObject::getValueProperty(ExecState* exec, int token) const
 {
     switch (token) {
         case Global:
@@ -159,9 +159,9 @@ JSValue* RegExpObject::getValueProperty(ExecState*, int token) const
         case Multiline:
             return jsBoolean(m_regExp->multiline());
         case Source:
-            return jsString(m_regExp->pattern());
+            return jsString(exec, m_regExp->pattern());
         case LastIndex:
-            return jsNumber(m_lastIndex);
+            return jsNumber(exec, m_lastIndex);
     }
     
     ASSERT_NOT_REACHED();
@@ -286,7 +286,7 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, FunctionPrototype* funcPro
   putDirect(exec->propertyNames().prototype, regProto, DontEnum | DontDelete | ReadOnly);
 
   // no. of arguments for constructor
-  putDirect(exec->propertyNames().length, jsNumber(2), ReadOnly | DontDelete | DontEnum);
+  putDirect(exec->propertyNames().length, jsNumber(exec, 2), ReadOnly | DontDelete | DontEnum);
 }
 
 /* 
@@ -360,10 +360,10 @@ void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
     for (unsigned i = 0; i <= lastNumSubpatterns; ++i) {
         int start = d->lastOvector[2 * i];
         if (start >= 0)
-            JSArray::put(exec, i, jsString(d->lastInput.substr(start, d->lastOvector[2 * i + 1] - start)));
+            JSArray::put(exec, i, jsString(exec, d->lastInput.substr(start, d->lastOvector[2 * i + 1] - start)));
     }
-    JSArray::put(exec, exec->propertyNames().index, jsNumber(d->lastOvector[0]));
-    JSArray::put(exec, exec->propertyNames().input, jsString(d->lastInput));
+    JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector[0]));
+    JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->lastInput));
 
     delete d;
     setLazyCreationData(0);
@@ -371,40 +371,40 @@ void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
 
 JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
 {
-    return new RegExpMatchesArray(exec, d.get());
+    return new (exec) RegExpMatchesArray(exec, d.get());
 }
 
-JSValue* RegExpConstructor::getBackref(unsigned i) const
+JSValue* RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
 {
   if (d->lastOvector && i <= d->lastNumSubPatterns)
-    return jsString(d->lastInput.substr(d->lastOvector[2 * i], d->lastOvector[2 * i + 1] - d->lastOvector[2 * i]));
-  return jsString("");
+    return jsString(exec, d->lastInput.substr(d->lastOvector[2 * i], d->lastOvector[2 * i + 1] - d->lastOvector[2 * i]));
+  return jsString(exec, "");
 }
 
-JSValue* RegExpConstructor::getLastParen() const
+JSValue* RegExpConstructor::getLastParen(ExecState* exec) const
 {
   unsigned i = d->lastNumSubPatterns;
   if (i > 0) {
     ASSERT(d->lastOvector);
-    return jsString(d->lastInput.substr(d->lastOvector[2 * i], d->lastOvector[2 * i + 1] - d->lastOvector[2 * i]));
+    return jsString(exec, d->lastInput.substr(d->lastOvector[2 * i], d->lastOvector[2 * i + 1] - d->lastOvector[2 * i]));
   }
-  return jsString("");
+  return jsString(exec, "");
 }
 
-JSValue *RegExpConstructor::getLeftContext() const
+JSValue* RegExpConstructor::getLeftContext(ExecState* exec) const
 {
   if (d->lastOvector)
-    return jsString(d->lastInput.substr(0, d->lastOvector[0]));
-  return jsString("");
+    return jsString(exec, d->lastInput.substr(0, d->lastOvector[0]));
+  return jsString(exec, "");
 }
 
-JSValue *RegExpConstructor::getRightContext() const
+JSValue* RegExpConstructor::getRightContext(ExecState* exec) const
 {
   if (d->lastOvector) {
     UString s = d->lastInput;
-    return jsString(s.substr(d->lastOvector[1], s.size() - d->lastOvector[1]));
+    return jsString(exec, s.substr(d->lastOvector[1], s.size() - d->lastOvector[1]));
   }
-  return jsString("");
+  return jsString(exec, "");
 }
 
 bool RegExpConstructor::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
@@ -412,44 +412,44 @@ bool RegExpConstructor::getOwnPropertySlot(ExecState *exec, const Identifier& pr
   return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, slot);
 }
 
-JSValue *RegExpConstructor::getValueProperty(ExecState*, int token) const
+JSValue *RegExpConstructor::getValueProperty(ExecState* exec, int token) const
 {
   switch (token) {
     case Dollar1:
-      return getBackref(1);
+      return getBackref(exec, 1);
     case Dollar2:
-      return getBackref(2);
+      return getBackref(exec, 2);
     case Dollar3:
-      return getBackref(3);
+      return getBackref(exec, 3);
     case Dollar4:
-      return getBackref(4);
+      return getBackref(exec, 4);
     case Dollar5:
-      return getBackref(5);
+      return getBackref(exec, 5);
     case Dollar6:
-      return getBackref(6);
+      return getBackref(exec, 6);
     case Dollar7:
-      return getBackref(7);
+      return getBackref(exec, 7);
     case Dollar8:
-      return getBackref(8);
+      return getBackref(exec, 8);
     case Dollar9:
-      return getBackref(9);
+      return getBackref(exec, 9);
     case Input:
-      return jsString(d->lastInput);
+      return jsString(exec, d->lastInput);
     case Multiline:
       return jsBoolean(d->multiline);
     case LastMatch:
-      return getBackref(0);
+      return getBackref(exec, 0);
     case LastParen:
-      return getLastParen();
+      return getLastParen(exec);
     case LeftContext:
-      return getLeftContext();
+      return getLeftContext(exec);
     case RightContext:
-      return getRightContext();
+      return getRightContext(exec);
     default:
-      ASSERT(0);
+      ASSERT_NOT_REACHED();
   }
 
-  return jsString("");
+  return jsString(exec, "");
 }
 
 void RegExpConstructor::put(ExecState *exec, const Identifier &propertyName, JSValue *value)
@@ -493,7 +493,7 @@ JSObject *RegExpConstructor::construct(ExecState *exec, const ArgList &args)
   
   RefPtr<RegExp> regExp = RegExp::create(pattern, flags);
   return regExp->isValid()
-    ? new RegExpObject(exec->lexicalGlobalObject()->regExpPrototype(), regExp.release())
+    ? new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpPrototype(), regExp.release())
     : throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
 }
 
index 77d3605..a5f424d 100644 (file)
@@ -94,10 +94,10 @@ namespace KJS {
         const UString& input() const;
 
     private:
-        JSValue* getBackref(unsigned) const;
-        JSValue* getLastParen() const;
-        JSValue* getLeftContext() const;
-        JSValue* getRightContext() const;
+        JSValue* getBackref(ExecState*, unsigned) const;
+        JSValue* getLastParen(ExecState*) const;
+        JSValue* getLeftContext(ExecState*) const;
+        JSValue* getRightContext(ExecState*) const;
 
         OwnPtr<RegExpConstructorPrivate> d;
     };
index 654b187..7ed6863 100644 (file)
@@ -28,6 +28,7 @@
 #include "Parser.h"
 #include "ArrayPrototype.h"
 #include "collector.h"
+#include "completion.h"
 #include "JSFunction.h"
 #include "InitializeThreading.h"
 #include "interpreter.h"
@@ -163,18 +164,18 @@ COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false
 
 GlobalObject::GlobalObject(Vector<UString>& arguments)
 {
-    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "debug"), functionDebug));
-    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "print"), functionPrint));
-    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "quit"), functionQuit));
-    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "gc"), functionGC));
-    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "version"), functionVersion));
-    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "run"), functionRun));
-    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "load"), functionLoad));
-    putDirectFunction(new PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "readline"), functionReadline));
+    putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "debug"), functionDebug));
+    putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "print"), functionPrint));
+    putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "quit"), functionQuit));
+    putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "gc"), functionGC));
+    putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "version"), functionVersion));
+    putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "run"), functionRun));
+    putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 1, Identifier(globalExec(), "load"), functionLoad));
+    putDirectFunction(new (globalExec()) PrototypeFunction(globalExec(), functionPrototype(), 0, Identifier(globalExec(), "readline"), functionReadline));
 
     JSObject* array = arrayConstructor()->construct(globalExec(), globalExec()->emptyList());
     for (size_t i = 0; i < arguments.size(); ++i)
-        array->put(globalExec(), i, jsString(arguments[i]));
+        array->put(globalExec(), i, jsString(globalExec(), arguments[i]));
     putDirect(Identifier(globalExec(), "arguments"), array);
 
     Interpreter::setShouldPrintExceptions(true);
@@ -200,10 +201,10 @@ JSValue* functionDebug(ExecState* exec, JSObject*, const ArgList& args)
     return jsUndefined();
 }
 
-JSValue* functionGC(ExecState*, JSObject*, const ArgList&)
+JSValue* functionGC(ExecState* exec, JSObject*, const ArgList&)
 {
     JSLock lock;
-    Collector::collect();
+    exec->heap()->collect();
     return jsUndefined();
 }
 
@@ -228,7 +229,7 @@ JSValue* functionRun(ExecState* exec, JSObject*, const ArgList& args)
     Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 1, script.data());
     stopWatch.stop();
 
-    return jsNumber(stopWatch.getElapsedMS());
+    return jsNumber(globalObject->globalExec(), stopWatch.getElapsedMS());
 }
 
 JSValue* functionLoad(ExecState* exec, JSObject*, const ArgList& args)
@@ -244,7 +245,7 @@ JSValue* functionLoad(ExecState* exec, JSObject*, const ArgList& args)
     return jsUndefined();
 }
 
-JSValue* functionReadline(ExecState*, JSObject*, const ArgList&)
+JSValue* functionReadline(ExecState* exec, JSObject*, const ArgList&)
 {
     Vector<char, 256> line;
     int c;
@@ -255,7 +256,7 @@ JSValue* functionReadline(ExecState*, JSObject*, const ArgList&)
         line.append(c);
     }
     line.append('\0');
-    return jsString(line.data());
+    return jsString(exec, line.data());
 }
 
 JSValue* functionQuit(ExecState*, JSObject*, const ArgList&)
@@ -451,7 +452,7 @@ int jscmain(int argc, char** argv)
         runInteractive(globalObject);
 
 #ifndef NDEBUG
-    Collector::collect();
+    JSGlobalData::threadInstance().heap->collect();
 #endif
 
     return success ? 0 : 3;
index 0df3413..d6fcda3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
  *
  *  This library is free software; you can redistribute it and/or
@@ -35,6 +35,7 @@
 
 #if USE(MULTIPLE_THREADS)
 #include <pthread.h>
+#include <wtf/Threading.h>
 #endif
 
 #if PLATFORM(DARWIN)
@@ -79,18 +80,23 @@ namespace KJS {
 // tunable parameters
 
 const size_t SPARE_EMPTY_BLOCKS = 2;
-const size_t MIN_ARRAY_SIZE = 14;
 const size_t GROWTH_FACTOR = 2;
 const size_t LOW_WATER_FACTOR = 4;
 const size_t ALLOCATIONS_PER_COLLECTION = 4000;
+// This value has to be a macro to be used in max() without introducing
+// a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
+#define MIN_ARRAY_SIZE 14UL
+
+Heap::Heap()
+    : m_pagesize(getpagesize())
+    , mainThreadOnlyObjectCount(0)
+    , m_markListSet(0)
+{
+    memset(&primaryHeap, 0, sizeof(CollectorHeap));
+    memset(&numberHeap, 0, sizeof(CollectorHeap));
+}
 
-static CollectorHeap primaryHeap = { 0, 0, 0, 0, 0, 0, 0, NoOperation };
-static CollectorHeap numberHeap = { 0, 0, 0, 0, 0, 0, 0, NoOperation };
-
-size_t Collector::mainThreadOnlyObjectCount = 0;
-HashSet<ArgList*>* Collector::m_markListSet;
-
-static CollectorBlock* allocateBlock()
+static NEVER_INLINE CollectorBlock* allocateBlock()
 {
 #if PLATFORM(DARWIN)    
     vm_address_t address = 0;
@@ -103,11 +109,10 @@ static CollectorBlock* allocateBlock()
     posix_memalign(&address, BLOCK_SIZE, BLOCK_SIZE);
     memset(address, 0, BLOCK_SIZE);
 #else
-    static size_t pagesize = getpagesize();
     
     size_t extra = 0;
-    if (BLOCK_SIZE > pagesize)
-        extra = BLOCK_SIZE - pagesize;
+    if (BLOCK_SIZE > m_pagesize)
+        extra = BLOCK_SIZE - m_pagesize;
 
     void* mmapResult = mmap(NULL, BLOCK_SIZE + extra, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
     uintptr_t address = reinterpret_cast<uintptr_t>(mmapResult);
@@ -138,11 +143,11 @@ static void freeBlock(CollectorBlock* block)
 #elif HAVE(POSIX_MEMALIGN)
     free(block);
 #else
-    munmap(reinterpret_cast<char *>(block), BLOCK_SIZE);
+    munmap(reinterpret_cast<char*>(block), BLOCK_SIZE);
 #endif
 }
 
-void Collector::recordExtraCost(size_t cost)
+void Heap::recordExtraCost(size_t cost)
 {
     // Our frequency of garbage collection tries to balance memory use against speed
     // by collecting based on the number of newly created values. However, for values
@@ -159,9 +164,9 @@ void Collector::recordExtraCost(size_t cost)
     primaryHeap.extraCost += cost;
 }
 
-template <Collector::HeapType heapType> struct HeapConstants;
+template <Heap::HeapType heapType> struct HeapConstants;
 
-template <> struct HeapConstants<Collector::PrimaryHeap> {
+template <> struct HeapConstants<Heap::PrimaryHeap> {
     static const size_t cellSize = CELL_SIZE;
     static const size_t cellsPerBlock = CELLS_PER_BLOCK;
     static const size_t bitmapShift = 0;
@@ -169,7 +174,7 @@ template <> struct HeapConstants<Collector::PrimaryHeap> {
     typedef CollectorBlock Block;
 };
 
-template <> struct HeapConstants<Collector::NumberHeap> {
+template <> struct HeapConstants<Heap::NumberHeap> {
     static const size_t cellSize = SMALL_CELL_SIZE;
     static const size_t cellsPerBlock = SMALL_CELLS_PER_BLOCK;
     static const size_t bitmapShift = 1;
@@ -177,7 +182,7 @@ template <> struct HeapConstants<Collector::NumberHeap> {
     typedef SmallCellCollectorBlock Block;
 };
 
-template <Collector::HeapType heapType> ALWAYS_INLINE void* Collector::heapAllocate(size_t s)
+template <Heap::HeapType heapType> ALWAYS_INLINE void* Heap::heapAllocate(size_t s)
 {
     typedef typename HeapConstants<heapType>::Block Block;
     typedef typename HeapConstants<heapType>::Cell Cell;
@@ -267,6 +272,7 @@ collect:
 
         targetBlock = (Block*)allocateBlock();
         targetBlock->freeList = targetBlock->cells;
+        targetBlock->heap = this;
         targetBlockUsedCells = 0;
         heap.blocks[usedBlocks] = (CollectorBlock*)targetBlock;
         heap.usedBlocks = usedBlocks + 1;
@@ -290,14 +296,12 @@ collect:
     return newCell;
 }
 
-#ifndef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
-void* Collector::allocate(size_t s)
+void* Heap::allocate(size_t s)
 {
     return heapAllocate<PrimaryHeap>(s);
 }
-#endif
 
-void* Collector::allocateNumber(size_t s)
+void* Heap::allocateNumber(size_t s)
 {
     return heapAllocate<NumberHeap>(s);
 }
@@ -362,7 +366,7 @@ static inline void* currentThreadStackBase()
 static pthread_t mainThread;
 #endif
 
-void Collector::registerAsMainThread()
+void Heap::registerAsMainThread()
 {
 #if USE(MULTIPLE_THREADS)
     mainThread = pthread_self();
@@ -404,7 +408,7 @@ static inline PlatformThread getCurrentPlatformThread()
 #endif
 }
 
-class Collector::Thread {
+class Heap::Thread {
 public:
     Thread(pthread_t pthread, const PlatformThread& platThread, void* base) 
         : posixThread(pthread)
@@ -421,11 +425,11 @@ public:
 
 pthread_key_t registeredThreadKey;
 pthread_once_t registeredThreadKeyOnce = PTHREAD_ONCE_INIT;
-Collector::Thread* registeredThreads;
+Heap::Thread* registeredThreads;
 
 static void destroyRegisteredThread(void* data) 
 {
-    Collector::Thread* thread = (Collector::Thread*)data;
+    Heap::Thread* thread = (Heap::Thread*)data;
 
     // Can't use JSLock convenience object here because we don't want to re-register
     // an exiting thread.
@@ -434,8 +438,8 @@ static void destroyRegisteredThread(void* data)
     if (registeredThreads == thread) {
         registeredThreads = registeredThreads->next;
     } else {
-        Collector::Thread* last = registeredThreads;
-        Collector::Thread* t;
+        Heap::Thread* last = registeredThreads;
+        Heap::Thread* t;
         for (t = registeredThreads->next; t != NULL; t = t->next) {
             if (t == thread) {          
                 last->next = t->next;
@@ -456,7 +460,7 @@ static void initializeRegisteredThreadKey()
     pthread_key_create(&registeredThreadKey, destroyRegisteredThread);
 }
 
-void Collector::registerThread()
+void Heap::registerThread()
 {
     ASSERT(JSLock::lockCount() > 0);
     ASSERT(JSLock::currentThreadIsHoldingLock());
@@ -464,12 +468,7 @@ void Collector::registerThread()
     pthread_once(&registeredThreadKeyOnce, initializeRegisteredThreadKey);
 
     if (!pthread_getspecific(registeredThreadKey)) {
-#if PLATFORM(DARWIN)
-        if (onMainThread())
-            CollectorHeapIntrospector::init(&primaryHeap, &numberHeap);
-#endif
-
-        Collector::Thread* thread = new Collector::Thread(pthread_self(), getCurrentPlatformThread(), currentThreadStackBase());
+        Heap::Thread* thread = new Heap::Thread(pthread_self(), getCurrentPlatformThread(), currentThreadStackBase());
 
         thread->next = registeredThreads;
         registeredThreads = thread;
@@ -477,6 +476,12 @@ void Collector::registerThread()
     }
 }
 
+void Heap::initializeHeapIntrospector()
+{
+    ASSERT(pthread_main_np());
+    CollectorHeapIntrospector::init(&primaryHeap, &numberHeap);
+}
+
 #endif
 
 #define IS_POINTER_ALIGNED(p) (((intptr_t)(p) & (sizeof(char*) - 1)) == 0)
@@ -484,7 +489,7 @@ void Collector::registerThread()
 // cell size needs to be a power of two for this to be valid
 #define IS_HALF_CELL_ALIGNED(p) (((intptr_t)(p) & (CELL_MASK >> 1)) == 0)
 
-void Collector::markStackObjectsConservatively(void* start, void* end)
+void Heap::markStackObjectsConservatively(void* start, void* end)
 {
     if (start > end) {
         void* tmp = start;
@@ -516,7 +521,7 @@ void Collector::markStackObjectsConservatively(void* start, void* end)
             // Mark the the number heap, we can mark these Cells directly to avoid the virtual call cost
             for (size_t block = 0; block < usedNumberBlocks; block++) {
                 if ((numberBlocks[block] == blockAddr) & (offset <= lastCellOffset)) {
-                    Collector::markCell(reinterpret_cast<JSCell*>(xAsBits));
+                    Heap::markCell(reinterpret_cast<JSCell*>(xAsBits));
                     goto endMarkLoop;
                 }
             }
@@ -538,7 +543,7 @@ void Collector::markStackObjectsConservatively(void* start, void* end)
     }
 }
 
-void NEVER_INLINE Collector::markCurrentThreadConservativelyInternal()
+void NEVER_INLINE Heap::markCurrentThreadConservativelyInternal()
 {
     void* dummy;
     void* stackPointer = &dummy;
@@ -546,7 +551,7 @@ void NEVER_INLINE Collector::markCurrentThreadConservativelyInternal()
     markStackObjectsConservatively(stackPointer, stackBase);
 }
 
-void Collector::markCurrentThreadConservatively()
+void Heap::markCurrentThreadConservatively()
 {
     // setjmp forces volatile registers onto the stack
     jmp_buf registers;
@@ -691,8 +696,10 @@ static inline void* otherThreadStackPointer(const PlatformThreadRegisters& regs)
 #endif
 }
 
-void Collector::markOtherThreadConservatively(Thread* thread)
+void Heap::markOtherThreadConservatively(Thread* thread)
 {
+    ASSERT(this == JSGlobalData::sharedInstance().heap);
+
     suspendThread(thread->platformThread);
 
     PlatformThreadRegisters regs;
@@ -709,28 +716,32 @@ void Collector::markOtherThreadConservatively(Thread* thread)
 
 #endif
 
-void Collector::markStackObjectsConservatively()
+void Heap::markStackObjectsConservatively()
 {
     markCurrentThreadConservatively();
 
 #if USE(MULTIPLE_THREADS)
-    for (Thread* thread = registeredThreads; thread != NULL; thread = thread->next) {
-        if (!pthread_equal(thread->posixThread, pthread_self())) {
-            markOtherThreadConservatively(thread);
+
+    if (this == JSGlobalData::sharedInstance().heap) {
+
+#ifndef NDEBUG
+        // Forbid malloc during the mark phase. Marking a thread suspends it, so 
+        // a malloc inside mark() would risk a deadlock with a thread that had been 
+        // suspended while holding the malloc lock.
+        fastMallocForbid();
+#endif
+        for (Thread* thread = registeredThreads; thread != NULL; thread = thread->next) {
+            if (!pthread_equal(thread->posixThread, pthread_self()))
+                markOtherThreadConservatively(thread);
         }
+#ifndef NDEBUG
+        fastMallocAllow();
+#endif
     }
 #endif
 }
 
-typedef HashCountedSet<JSCell*> ProtectCountSet;
-
-static ProtectCountSet& protectedValues()
-{
-    static ProtectCountSet staticProtectCountSet;
-    return staticProtectCountSet;
-}
-
-void Collector::protect(JSValue* k)
+void Heap::protect(JSValue* k)
 {
     ASSERT(k);
     ASSERT(JSLock::lockCount() > 0);
@@ -739,10 +750,10 @@ void Collector::protect(JSValue* k)
     if (JSImmediate::isImmediate(k))
         return;
 
-    protectedValues().add(k->asCell());
+    protectedValues.add(k->asCell());
 }
 
-void Collector::unprotect(JSValue* k)
+void Heap::unprotect(JSValue* k)
 {
     ASSERT(k);
     ASSERT(JSLock::lockCount() > 0);
@@ -751,10 +762,10 @@ void Collector::unprotect(JSValue* k)
     if (JSImmediate::isImmediate(k))
         return;
 
-    protectedValues().remove(k->asCell());
+    protectedValues.remove(k->asCell());
 }
 
-void Collector::collectOnMainThreadOnly(JSValue* value)
+void Heap::collectOnMainThreadOnly(JSValue* value)
 {
     ASSERT(value);
     ASSERT(JSLock::lockCount() > 0);
@@ -768,9 +779,15 @@ void Collector::collectOnMainThreadOnly(JSValue* value)
     ++mainThreadOnlyObjectCount;
 }
 
-void Collector::markProtectedObjects()
+Heap* Heap::heap(const JSValue* v)
+{
+    if (JSImmediate::isImmediate(v))
+        return 0;
+    return Heap::cellBlock(v->asCell())->heap;
+}
+
+void Heap::markProtectedObjects()
 {
-    ProtectCountSet& protectedValues = KJS::protectedValues();
     ProtectCountSet::iterator end = protectedValues.end();
     for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it) {
         JSCell* val = it->first;
@@ -779,7 +796,7 @@ void Collector::markProtectedObjects()
     }
 }
 
-void Collector::markMainThreadOnlyObjects()
+void Heap::markMainThreadOnlyObjects()
 {
 #if USE(MULTIPLE_THREADS)
     ASSERT(!onMainThread());
@@ -821,14 +838,14 @@ void Collector::markMainThreadOnlyObjects()
     }
 }
 
-template <Collector::HeapType heapType> size_t Collector::sweep(bool currentThreadIsMainThread)
+template <Heap::HeapType heapType> size_t Heap::sweep(bool currentThreadIsMainThread)
 {
     typedef typename HeapConstants<heapType>::Block Block;
     typedef typename HeapConstants<heapType>::Cell Cell;
 
     UNUSED_PARAM(currentThreadIsMainThread); // currentThreadIsMainThread is only used in ASSERTs
     // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else
-    CollectorHeap& heap = heapType == Collector::PrimaryHeap ? primaryHeap : numberHeap;
+    CollectorHeap& heap = heapType == Heap::PrimaryHeap ? primaryHeap : numberHeap;
     
     size_t emptyBlocks = 0;
     size_t numLiveObjects = heap.numLiveObjects;
@@ -845,7 +862,7 @@ template <Collector::HeapType heapType> size_t Collector::sweep(bool currentThre
                 if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
                     Cell* cell = curBlock->cells + i;
                     
-                    if (heapType != Collector::NumberHeap) {
+                    if (heapType != Heap::NumberHeap) {
                         JSCell* imp = reinterpret_cast<JSCell*>(cell);
                         // special case for allocated but uninitialized object
                         // (We don't need this check earlier because nothing prior this point 
@@ -856,7 +873,7 @@ template <Collector::HeapType heapType> size_t Collector::sweep(bool currentThre
                         ASSERT(currentThreadIsMainThread || !curBlock->collectOnMainThreadOnly.get(i));
                         if (curBlock->collectOnMainThreadOnly.get(i)) {
                             curBlock->collectOnMainThreadOnly.clear(i);
-                            --Collector::mainThreadOnlyObjectCount;
+                            --mainThreadOnlyObjectCount;
                         }
                         imp->~JSCell();
                     }
@@ -878,12 +895,12 @@ template <Collector::HeapType heapType> size_t Collector::sweep(bool currentThre
                     ++minimumCellsToProcess;
                 } else {
                     if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
-                        if (heapType != Collector::NumberHeap) {
+                        if (heapType != Heap::NumberHeap) {
                             JSCell* imp = reinterpret_cast<JSCell*>(cell);
                             ASSERT(currentThreadIsMainThread || !curBlock->collectOnMainThreadOnly.get(i));
                             if (curBlock->collectOnMainThreadOnly.get(i)) {
                                 curBlock->collectOnMainThreadOnly.clear(i);
-                                --Collector::mainThreadOnlyObjectCount;
+                                --mainThreadOnlyObjectCount;
                             }
                             imp->~JSCell();
                         }
@@ -931,10 +948,14 @@ template <Collector::HeapType heapType> size_t Collector::sweep(bool currentThre
     return numLiveObjects;
 }
     
-bool Collector::collect()
+bool Heap::collect()
 {
-    ASSERT(JSLock::lockCount() > 0);
-    ASSERT(JSLock::currentThreadIsHoldingLock());
+#ifndef NDEBUG
+    if (JSGlobalData::sharedInstance().heap == this) {
+        ASSERT(JSLock::lockCount() > 0);
+        ASSERT(JSLock::currentThreadIsHoldingLock());
+    }
+#endif
 
     ASSERT((primaryHeap.operationInProgress == NoOperation) | (numberHeap.operationInProgress == NoOperation));
     if ((primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation))
@@ -947,13 +968,6 @@ bool Collector::collect()
 
     // MARK: first mark all referenced objects recursively starting out from the set of root objects
 
-#ifndef NDEBUG
-    // Forbid malloc during the mark phase. Marking a thread suspends it, so 
-    // a malloc inside mark() would risk a deadlock with a thread that had been 
-    // suspended while holding the malloc lock.
-    fastMallocForbid();
-#endif
-
     markStackObjectsConservatively();
     markProtectedObjects();
     if (m_markListSet && m_markListSet->size())
@@ -963,10 +977,6 @@ bool Collector::collect()
         markMainThreadOnlyObjects();
 #endif
 
-#ifndef NDEBUG
-    fastMallocAllow();
-#endif
-
     size_t originalLiveObjects = primaryHeap.numLiveObjects + numberHeap.numLiveObjects;
     size_t numLiveObjects = sweep<PrimaryHeap>(currentThreadIsMainThread);
     numLiveObjects += sweep<NumberHeap>(currentThreadIsMainThread);
@@ -977,12 +987,12 @@ bool Collector::collect()
     return numLiveObjects < originalLiveObjects;
 }
 
-size_t Collector::size() 
+size_t Heap::size() 
 {
     return primaryHeap.numLiveObjects + numberHeap.numLiveObjects; 
 }
 
-size_t Collector::globalObjectCount()
+size_t Heap::globalObjectCount()
 {
     size_t count = 0;
     if (JSGlobalObject::head()) {
@@ -995,13 +1005,13 @@ size_t Collector::globalObjectCount()
     return count;
 }
 
-size_t Collector::protectedGlobalObjectCount()
+size_t Heap::protectedGlobalObjectCount()
 {
     size_t count = 0;
     if (JSGlobalObject::head()) {
         JSGlobalObject* o = JSGlobalObject::head();
         do {
-            if (protectedValues().contains(o))
+            if (protectedValues.contains(o))
                 ++count;
             o = o->next();
         } while (o != JSGlobalObject::head());
@@ -1009,9 +1019,9 @@ size_t Collector::protectedGlobalObjectCount()
     return count;
 }
 
-size_t Collector::protectedObjectCount()
+size_t Heap::protectedObjectCount()
 {
-    return protectedValues().size();
+    return protectedValues.size();
 }
 
 static const char* typeName(JSCell* val)
@@ -1047,11 +1057,10 @@ static const char* typeName(JSCell* val)
     return name;
 }
 
-HashCountedSet<const char*>* Collector::protectedObjectTypeCounts()
+HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
 {
     HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
 
-    ProtectCountSet& protectedValues = KJS::protectedValues();
     ProtectCountSet::iterator end = protectedValues.end();
     for (ProtectCountSet::iterator it = protectedValues.begin(); it != end; ++it)
         counts->add(typeName(it->first));
@@ -1059,7 +1068,7 @@ HashCountedSet<const char*>* Collector::protectedObjectTypeCounts()
     return counts;
 }
 
-bool Collector::isBusy()
+bool Heap::isBusy()
 {
     return (primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation);
 }
index 6370493..d8a77e0 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <wtf/HashCountedSet.h>
 #include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
 
 namespace KJS {
 
@@ -33,7 +34,22 @@ namespace KJS {
     class JSValue;
     class ArgList;
 
-    class Collector {
+    enum OperationInProgress { NoOperation, Allocation, Collection };
+
+    struct CollectorHeap {
+        CollectorBlock** blocks;
+        size_t numBlocks;
+        size_t usedBlocks;
+        size_t firstBlockWithPossibleSpace;
+
+        size_t numLiveObjects;
+        size_t numLiveObjectsAtLastCollect;
+        size_t extraCost;
+
+        OperationInProgress operationInProgress;
+    };
+
+    class Heap : Noncopyable {
     public:
         class Thread;
         enum HeapType { PrimaryHeap, NumberHeap };
@@ -43,64 +59,74 @@ namespace KJS {
         // one file, so the heapAllocate template definitions are available.
         // However, allocateNumber is used via jsNumberCell outside JavaScriptCore.
         // Thus allocateNumber needs to provide a non-inline version too.
-        static void* allocate(size_t s) { return heapAllocate<PrimaryHeap>(s); }
-        static void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); }
-#else
-        static void* allocate(size_t);
+        void* inlineAllocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); }
+        void* inlineAllocate(size_t s) { return heapAllocate<PrimaryHeap>(s); }
 #endif
-        static void* allocateNumber(size_t s);
+        void* allocateNumber(size_t);
+        void* allocate(size_t);
 
-        static bool collect();
-        static bool isBusy(); // true if an allocation or collection is in progress
+        bool collect();
+        bool isBusy(); // true if an allocation or collection is in progress
 
         static const size_t minExtraCostSize = 256;
 
-        static void reportExtraMemoryCost(size_t cost);
+        void reportExtraMemoryCost(size_t cost);
+
+        size_t size();
 
-        static size_t size();
+        void protect(JSValue*);
+        void unprotect(JSValue*);
 
-        static void protect(JSValue*);
-        static void unprotect(JSValue*);
-        
-        static void collectOnMainThreadOnly(JSValue*);
+        void collectOnMainThreadOnly(JSValue*);
 
-        static size_t globalObjectCount();
-        static size_t protectedObjectCount();
-        static size_t protectedGlobalObjectCount();
-        static HashCountedSet<const char*>* protectedObjectTypeCounts();
+        static Heap* heap(const JSValue*); // 0 for immediate values
+
+        size_t globalObjectCount();
+        size_t protectedObjectCount();
+        size_t protectedGlobalObjectCount();
+        HashCountedSet<const char*>* protectedObjectTypeCounts();
 
-        static void registerThread();
-        
         static void registerAsMainThread();
+        static void registerThread(); // Should only be called by clients that can use the same heap from multiple threads.
+
+#if PLATFORM(DARWIN)
+        void initializeHeapIntrospector();
+#endif
 
         static bool isCellMarked(const JSCell*);
         static void markCell(JSCell*);
 
-        static void markStackObjectsConservatively(void* start, void* end);
+        void markStackObjectsConservatively(void* start, void* end);
 
-        static HashSet<ArgList*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<ArgList*>; return *m_markListSet; }
+        HashSet<ArgList*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<ArgList*>; return *m_markListSet; }
 
     private:
-        template <Collector::HeapType heapType> static void* heapAllocate(size_t s);
-        template <Collector::HeapType heapType> static size_t sweep(bool);
+        template <Heap::HeapType heapType> void* heapAllocate(size_t);
+        template <Heap::HeapType heapType> size_t sweep(bool);
         static const CollectorBlock* cellBlock(const JSCell*);
         static CollectorBlock* cellBlock(JSCell*);
         static size_t cellOffset(const JSCell*);
 
-        Collector();
+        Heap();
+        friend class JSGlobalData;
+
+        void recordExtraCost(size_t);
+        void markProtectedObjects();
+        void markMainThreadOnlyObjects();
+        void markCurrentThreadConservatively();
+        void markCurrentThreadConservativelyInternal();
+        void markOtherThreadConservatively(Thread*);
+        void markStackObjectsConservatively();
 
-        static void recordExtraCost(size_t);
-        static void markProtectedObjects();
-        static void markMainThreadOnlyObjects();
-        static void markCurrentThreadConservatively();
-        static void markCurrentThreadConservativelyInternal();
-        static void markOtherThreadConservatively(Thread*);
-        static void markStackObjectsConservatively();
+        typedef HashCountedSet<JSCell*> ProtectCountSet;
 
-        static size_t mainThreadOnlyObjectCount;
-        static bool memoryFull;
+        const size_t m_pagesize;
 
-        static HashSet<ArgList*>* m_markListSet;
+        size_t mainThreadOnlyObjectCount;
+        CollectorHeap primaryHeap;
+        CollectorHeap numberHeap;
+        ProtectCountSet protectedValues;
+        HashSet<ArgList*>* m_markListSet;
     };
 
     // tunable parameters
@@ -160,6 +186,7 @@ namespace KJS {
         CollectorCell* freeList;
         CollectorBitmap marked;
         CollectorBitmap collectOnMainThreadOnly;
+        Heap* heap;
     };
 
     class SmallCellCollectorBlock {
@@ -169,49 +196,35 @@ namespace KJS {
         SmallCollectorCell* freeList;
         CollectorBitmap marked;
         CollectorBitmap collectOnMainThreadOnly;
+        Heap* heap;
     };
 
-    enum OperationInProgress { NoOperation, Allocation, Collection };
-
-    struct CollectorHeap {
-        CollectorBlock** blocks;
-        size_t numBlocks;
-        size_t usedBlocks;
-        size_t firstBlockWithPossibleSpace;
-
-        size_t numLiveObjects;
-        size_t numLiveObjectsAtLastCollect;
-        size_t extraCost;
-
-        OperationInProgress operationInProgress;
-    };
-
-    inline const CollectorBlock* Collector::cellBlock(const JSCell* cell)
+    inline const CollectorBlock* Heap::cellBlock(const JSCell* cell)
     {
         return reinterpret_cast<const CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
     }
 
-    inline CollectorBlock* Collector::cellBlock(JSCell* cell)
+    inline CollectorBlock* Heap::cellBlock(JSCell* cell)
     {
         return const_cast<CollectorBlock*>(cellBlock(const_cast<const JSCell*>(cell)));
     }
 
-    inline size_t Collector::cellOffset(const JSCell* cell)
+    inline size_t Heap::cellOffset(const JSCell* cell)
     {
         return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
     }
 
-    inline bool Collector::isCellMarked(const JSCell* cell)
+    inline bool Heap::isCellMarked(const JSCell* cell)
     {
         return cellBlock(cell)->marked.get(cellOffset(cell));
     }
 
-    inline void Collector::markCell(JSCell* cell)
+    inline void Heap::markCell(JSCell* cell)
     {
         cellBlock(cell)->marked.set(cellOffset(cell));
     }
 
-    inline void Collector::reportExtraMemoryCost(size_t cost)
+    inline void Heap::reportExtraMemoryCost(size_t cost)
     {
         if (cost > minExtraCostSize) 
             recordExtraCost(cost / (CELL_SIZE * 2)); 
index e18efb6..5057267 100644 (file)
@@ -170,7 +170,7 @@ static UString formatLocaleDate(ExecState *exec, double time, bool includeDate,
 
 enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime };
  
-static JSCell* formatLocaleDate(const GregorianDateTime& gdt, const LocaleDateTimeFormat format)
+static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, const LocaleDateTimeFormat format)
 {
     static const char* formatStrings[] = {"%#c", "%#x", "%X"};
  
@@ -188,7 +188,7 @@ static JSCell* formatLocaleDate(const GregorianDateTime& gdt, const LocaleDateTi
     size_t ret = strftime(timebuffer, bufsize, formatStrings[format], &localTM);
  
     if ( ret == 0 )
-        return jsString("");
+        return jsString(exec, "");
  
     // Copy original into the buffer
     if (yearNeedsOffset && format != LocaleTime) {
@@ -202,7 +202,7 @@ static JSCell* formatLocaleDate(const GregorianDateTime& gdt, const LocaleDateTi
         strncpy(yearLocation, yearString, yearLen - 1);
     }
  
-    return jsString(timebuffer);
+    return jsString(exec, timebuffer);
 }
 
 #endif // PLATFORM(WIN_OS)
@@ -469,10 +469,10 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState
 */
 // ECMA 15.9.4
 
-DatePrototype::DatePrototype(ExecState *, ObjectPrototype *objectProto)
-  : DateInstance(objectProto)
+DatePrototype::DatePrototype(ExecState* exec, ObjectPrototype* objectProto)
+    : DateInstance(objectProto)
 {
-    setInternalValue(jsNaN());
+    setInternalValue(jsNaN(exec));
     // The constructor will be added later, after DateConstructor has been built.
 }
 
@@ -489,10 +489,10 @@ DateConstructor::DateConstructor(ExecState* exec, FunctionPrototype* funcProto,
   : InternalFunction(funcProto, Identifier(exec, dateProto->classInfo()->className))
 {
   putDirect(exec->propertyNames().prototype, dateProto, DontEnum|DontDelete|ReadOnly);
-  putDirectFunction(new DateFunction(exec, funcProto, DateFunction::Parse, 1, exec->propertyNames().parse), DontEnum);
-  putDirectFunction(new DateFunction(exec, funcProto, DateFunction::UTC, 7, exec->propertyNames().UTC), DontEnum);
-  putDirectFunction(new DateFunction(exec, funcProto, DateFunction::Now, 0, exec->propertyNames().now), DontEnum);
-  putDirect(exec->propertyNames().length, 7, ReadOnly|DontDelete|DontEnum);
+  putDirectFunction(new (exec) DateFunction(exec, funcProto, DateFunction::Parse, 1, exec->propertyNames().parse), DontEnum);
+  putDirectFunction(new (exec) DateFunction(exec, funcProto, DateFunction::UTC, 7, exec->propertyNames().UTC), DontEnum);
+  putDirectFunction(new (exec) DateFunction(exec, funcProto, DateFunction::Now, 0, exec->propertyNames().now), DontEnum);
+  putDirect(exec, exec->propertyNames().length, 7, ReadOnly|DontDelete|DontEnum);
 }
 
 ConstructType DateConstructor::getConstructData(ConstructData&)
@@ -543,19 +543,19 @@ JSObject *DateConstructor::construct(ExecState *exec, const ArgList &args)
     }
   }
   
-  DateInstance *ret = new DateInstance(exec->lexicalGlobalObject()->datePrototype());
-  ret->setInternalValue(jsNumber(timeClip(value)));
+  DateInstance* ret = new (exec) DateInstance(exec->lexicalGlobalObject()->datePrototype());
+  ret->setInternalValue(jsNumber(exec, timeClip(value)));
   return ret;
 }
 
 // ECMA 15.9.2
-JSValue *DateConstructor::callAsFunction(ExecState * /*exec*/, JSObject * /*thisObj*/, const ArgList &/*args*/)
+JSValue* DateConstructor::callAsFunction(ExecState* exec, JSObject * /*thisObj*/, const ArgList &/*args*/)
 {
     time_t localTime = time(0);
     tm localTM;
     getLocalTime(&localTime, &localTM);
     GregorianDateTime ts(localTM);
-    return jsString(formatDate(ts) + " " + formatTime(ts, false));
+    return jsString(exec, formatDate(ts) + " " + formatTime(ts, false));
 }
 
 // ------------------------------ DateFunction ----------------------------
@@ -563,16 +563,16 @@ JSValue *DateConstructor::callAsFunction(ExecState * /*exec*/, JSObject * /*this
 DateFunction::DateFunction(ExecState* exec, FunctionPrototype* funcProto, int i, int len, const Identifier& name)
     : InternalFunction(funcProto, name), id(i)
 {
-    putDirect(exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum);
+    putDirect(exec, exec->propertyNames().length, len, DontDelete|ReadOnly|DontEnum);
 }
 
 // ECMA 15.9.4.2 - 3
 JSValue *DateFunction::callAsFunction(ExecState* exec, JSObject*, const ArgList& args)
 {
   if (id == Parse)
-    return jsNumber(parseDate(args[0]->toString(exec)));
+    return jsNumber(exec, parseDate(args[0]->toString(exec)));
   else if (id == Now)
-    return jsNumber(getCurrentUTCTime());
+    return jsNumber(exec, getCurrentUTCTime());
   else { // UTC
     int n = args.size();
     if (isnan(args[0]->toNumber(exec))
@@ -582,7 +582,7 @@ JSValue *DateFunction::callAsFunction(ExecState* exec, JSObject*, const ArgList&
         || (n >= 5 && isnan(args[4]->toNumber(exec)))
         || (n >= 6 && isnan(args[5]->toNumber(exec)))
         || (n >= 7 && isnan(args[6]->toNumber(exec)))) {
-      return jsNaN();
+      return jsNaN(exec);
     }
 
     GregorianDateTime t;
@@ -594,7 +594,7 @@ JSValue *DateFunction::callAsFunction(ExecState* exec, JSObject*, const ArgList&
     t.minute = args[4]->toInt32(exec);
     t.second = args[5]->toInt32(exec);
     double ms = (n >= 7) ? args[6]->toNumber(exec) : 0;
-    return jsNumber(gregorianDateTimeToMS(t, ms, true));
+    return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
   }
 }
 
@@ -989,11 +989,11 @@ JSValue* dateProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsString("Invalid Date");
+        return jsString(exec, "Invalid Date");
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsString(formatDate(t) + " " + formatTime(t, utc));
+    return jsString(exec, formatDate(t) + " " + formatTime(t, utc));
 }
 
 JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1007,11 +1007,11 @@ JSValue* dateProtoFuncToUTCString(ExecState* exec, JSObject* thisObj, const ArgL
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsString("Invalid Date");
+        return jsString(exec, "Invalid Date");
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsString(formatDateUTCVariant(t) + " " + formatTime(t, utc));
+    return jsString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
 }
 
 JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1025,11 +1025,11 @@ JSValue* dateProtoFuncToDateString(ExecState* exec, JSObject* thisObj, const Arg
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsString("Invalid Date");
+        return jsString(exec, "Invalid Date");
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsString(formatDate(t));
+    return jsString(exec, formatDate(t));
 }
 
 JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1043,11 +1043,11 @@ JSValue* dateProtoFuncToTimeString(ExecState* exec, JSObject* thisObj, const Arg
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsString("Invalid Date");
+        return jsString(exec, "Invalid Date");
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsString(formatTime(t, utc));
+    return jsString(exec, formatTime(t, utc));
 }
 
 JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -1059,11 +1059,11 @@ JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const A
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsString("Invalid Date");
+        return jsString(exec, "Invalid Date");
 
 #if PLATFORM(MAC)
     double secs = floor(milli / msPerSecond);
-    return jsString(formatLocaleDate(exec, secs, true, true, args));
+    return jsString(exec, formatLocaleDate(exec, secs, true, true, args));
 #else
     UNUSED_PARAM(args);
 
@@ -1071,7 +1071,7 @@ JSValue* dateProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const A
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return formatLocaleDate(t, LocaleDateAndTime);
+    return formatLocaleDate(exec, t, LocaleDateAndTime);
 #endif
 }
 
@@ -1084,11 +1084,11 @@ JSValue* dateProtoFuncToLocaleDateString(ExecState* exec, JSObject* thisObj, con
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsString("Invalid Date");
+        return jsString(exec, "Invalid Date");
 
 #if PLATFORM(MAC)
     double secs = floor(milli / msPerSecond);
-    return jsString(formatLocaleDate(exec, secs, true, false, args));
+    return jsString(exec, formatLocaleDate(exec, secs, true, false, args));
 #else
     UNUSED_PARAM(args);
 
@@ -1096,7 +1096,7 @@ JSValue* dateProtoFuncToLocaleDateString(ExecState* exec, JSObject* thisObj, con
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return formatLocaleDate(t, LocaleDate);
+    return formatLocaleDate(exec, t, LocaleDate);
 #endif
 }
 
@@ -1109,11 +1109,11 @@ JSValue* dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject* thisObj, con
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsString("Invalid Date");
+        return jsString(exec, "Invalid Date");
 
 #if PLATFORM(MAC)
     double secs = floor(milli / msPerSecond);
-    return jsString(formatLocaleDate(exec, secs, false, true, args));
+    return jsString(exec, formatLocaleDate(exec, secs, false, true, args));
 #else
     UNUSED_PARAM(args);
 
@@ -1121,7 +1121,7 @@ JSValue* dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject* thisObj, con
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return formatLocaleDate(t, LocaleTime);
+    return formatLocaleDate(exec, t, LocaleTime);
 #endif
 }
 
@@ -1134,9 +1134,9 @@ JSValue* dateProtoFuncValueOf(ExecState* exec, JSObject* thisObj, const ArgList&
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
-    return jsNumber(milli);
+    return jsNumber(exec, milli);
 }
 
 JSValue* dateProtoFuncGetTime(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1148,9 +1148,9 @@ JSValue* dateProtoFuncGetTime(ExecState* exec, JSObject* thisObj, const ArgList&
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
-    return jsNumber(milli);
+    return jsNumber(exec, milli);
 }
 
 JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1164,11 +1164,11 @@ JSValue* dateProtoFuncGetFullYear(ExecState* exec, JSObject* thisObj, const ArgL
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(1900 + t.year);
+    return jsNumber(exec, 1900 + t.year);
 }
 
 JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1182,11 +1182,11 @@ JSValue* dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject* thisObj, const A
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(1900 + t.year);
+    return jsNumber(exec, 1900 + t.year);
 }
 
 JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1200,11 +1200,11 @@ JSValue* dateProtoFuncToGMTString(ExecState* exec, JSObject* thisObj, const ArgL
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsString("Invalid Date");
+        return jsString(exec, "Invalid Date");
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsString(formatDateUTCVariant(t) + " " + formatTime(t, utc));
+    return jsString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
 }
 
 JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1218,11 +1218,11 @@ JSValue* dateProtoFuncGetMonth(ExecState* exec, JSObject* thisObj, const ArgList
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.month);
+    return jsNumber(exec, t.month);
 }
 
 JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1236,11 +1236,11 @@ JSValue* dateProtoFuncGetUTCMonth(ExecState* exec, JSObject* thisObj, const ArgL
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.month);
+    return jsNumber(exec, t.month);
 }
 
 JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1254,11 +1254,11 @@ JSValue* dateProtoFuncGetDate(ExecState* exec, JSObject* thisObj, const ArgList&
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.monthDay);
+    return jsNumber(exec, t.monthDay);
 }
 
 JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1272,11 +1272,11 @@ JSValue* dateProtoFuncGetUTCDate(ExecState* exec, JSObject* thisObj, const ArgLi
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.monthDay);
+    return jsNumber(exec, t.monthDay);
 }
 
 JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1290,11 +1290,11 @@ JSValue* dateProtoFuncGetDay(ExecState* exec, JSObject* thisObj, const ArgList&)
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.weekDay);
+    return jsNumber(exec, t.weekDay);
 }
 
 JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1308,11 +1308,11 @@ JSValue* dateProtoFuncGetUTCDay(ExecState* exec, JSObject* thisObj, const ArgLis
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.weekDay);
+    return jsNumber(exec, t.weekDay);
 }
 
 JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1326,11 +1326,11 @@ JSValue* dateProtoFuncGetHours(ExecState* exec, JSObject* thisObj, const ArgList
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.hour);
+    return jsNumber(exec, t.hour);
 }
 
 JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1344,11 +1344,11 @@ JSValue* dateProtoFuncGetUTCHours(ExecState* exec, JSObject* thisObj, const ArgL
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.hour);
+    return jsNumber(exec, t.hour);
 }
 
 JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1362,11 +1362,11 @@ JSValue* dateProtoFuncGetMinutes(ExecState* exec, JSObject* thisObj, const ArgLi
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.minute);
+    return jsNumber(exec, t.minute);
 }
 
 JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1380,11 +1380,11 @@ JSValue* dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject* thisObj, const Ar
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.minute);
+    return jsNumber(exec, t.minute);
 }
 
 JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1398,11 +1398,11 @@ JSValue* dateProtoFuncGetSeconds(ExecState* exec, JSObject* thisObj, const ArgLi
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.second);
+    return jsNumber(exec, t.second);
 }
 
 JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1416,11 +1416,11 @@ JSValue* dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject* thisObj, const Ar
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(t.second);
+    return jsNumber(exec, t.second);
 }
 
 JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1432,11 +1432,11 @@ JSValue* dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject* thisObj, const
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     double secs = floor(milli / msPerSecond);
     double ms = milli - secs * msPerSecond;
-    return jsNumber(ms);
+    return jsNumber(exec, ms);
 }
 
 JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1448,11 +1448,11 @@ JSValue* dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject* thisObj, con
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     double secs = floor(milli / msPerSecond);
     double ms = milli - secs * msPerSecond;
-    return jsNumber(ms);
+    return jsNumber(exec, ms);
 }
 
 JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -1466,11 +1466,11 @@ JSValue* dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject* thisObj, cons
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
-    return jsNumber(-gmtoffset(t) / minutesPerHour);
+    return jsNumber(exec, -gmtoffset(t) / minutesPerHour);
 }
 
 JSValue* dateProtoFuncSetTime(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -1481,7 +1481,7 @@ JSValue* dateProtoFuncSetTime(ExecState* exec, JSObject* thisObj, const ArgList&
     DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj); 
 
     double milli = timeClip(args[0]->toNumber(exec));
-    JSValue* result = jsNumber(milli);
+    JSValue* result = jsNumber(exec, milli);
     thisDateObj->setInternalValue(result);
     return result;
 }
@@ -1496,7 +1496,7 @@ static JSValue* setNewValueFromTimeArgs(ExecState* exec, JSObject* thisObj, cons
     double milli = v->toNumber(exec);
     
     if (args.isEmpty() || isnan(milli)) {
-        JSValue* result = jsNaN();
+        JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }
@@ -1508,12 +1508,12 @@ static JSValue* setNewValueFromTimeArgs(ExecState* exec, JSObject* thisObj, cons
     thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t);
 
     if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) {
-        JSValue* result = jsNaN();
+        JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     } 
     
-    JSValue* result = jsNumber(gregorianDateTimeToMS(t, ms, inputIsUTC));
+    JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
     thisDateObj->setInternalValue(result);
     return result;
 }
@@ -1525,7 +1525,7 @@ static JSValue* setNewValueFromDateArgs(ExecState* exec, JSObject* thisObj, cons
 
     DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);
     if (args.isEmpty()) {
-        JSValue* result = jsNaN();
+        JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }      
@@ -1546,12 +1546,12 @@ static JSValue* setNewValueFromDateArgs(ExecState* exec, JSObject* thisObj, cons
     }
     
     if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) {
-        JSValue* result = jsNaN();
+        JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     } 
            
-    JSValue* result = jsNumber(gregorianDateTimeToMS(t, ms, inputIsUTC));
+    JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
     thisDateObj->setInternalValue(result);
     return result;
 }
@@ -1649,7 +1649,7 @@ JSValue* dateProtoFuncSetYear(ExecState* exec, JSObject* thisObj, const ArgList&
 
     DateInstance* thisDateObj = static_cast<DateInstance*>(thisObj);     
     if (args.isEmpty()) { 
-        JSValue* result = jsNaN();
+        JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }
@@ -1672,13 +1672,13 @@ JSValue* dateProtoFuncSetYear(ExecState* exec, JSObject* thisObj, const ArgList&
     bool ok = true;
     int32_t year = args[0]->toInt32(exec, ok);
     if (!ok) {
-        JSValue* result = jsNaN();
+        JSValue* result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }
             
     t.year = (year > 99 || year < 0) ? year - 1900 : year;
-    JSValue* result = jsNumber(gregorianDateTimeToMS(t, ms, utc));
+    JSValue* result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
     thisDateObj->setInternalValue(result);
     return result;
 }
@@ -1694,13 +1694,13 @@ JSValue* dateProtoFuncGetYear(ExecState* exec, JSObject* thisObj, const ArgList&
     JSValue* v = thisDateObj->internalValue();
     double milli = v->toNumber(exec);
     if (isnan(milli))
-        return jsNaN();
+        return jsNaN(exec);
 
     GregorianDateTime t;
     thisDateObj->msToGregorianDateTime(milli, utc, t);
 
     // NOTE: IE returns the full year even in getYear.
-    return jsNumber(t.year);
+    return jsNumber(exec, t.year);
 }
 
 } // namespace KJS
index efe0074..5e1ce10 100644 (file)
@@ -45,10 +45,10 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, ObjectPrototype* objectPrototype
 {
     // The constructor will be added later in ErrorConstructor's constructor
 
-    putDirect(exec->propertyNames().name, jsString("Error"), DontEnum);
-    putDirect(exec->propertyNames().message, jsString("Unknown error"), DontEnum);
+    putDirect(exec->propertyNames().name, jsString(exec, "Error"), DontEnum);
+    putDirect(exec->propertyNames().message, jsString(exec, "Unknown error"), DontEnum);
 
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
 }
 
 JSValue* errorProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -64,7 +64,7 @@ JSValue* errorProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgLis
         // Mozilla compatible format
         s += ": " + v->toString(exec);
 
-    return jsString(s);
+    return jsString(exec, s);
 }
 
 // ------------------------------ ErrorConstructor -------------------------------
@@ -74,7 +74,7 @@ ErrorConstructor::ErrorConstructor(ExecState* exec, FunctionPrototype* funcProto
 {
     // ECMA 15.11.3.1 Error.prototype
     putDirect(exec->propertyNames().prototype, errorProto, DontEnum|DontDelete|ReadOnly);
-    putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete|ReadOnly|DontEnum);
 }
 
 ConstructType ErrorConstructor::getConstructData(ConstructData&)
@@ -86,11 +86,11 @@ ConstructType ErrorConstructor::getConstructData(ConstructData&)
 JSObject* ErrorConstructor::construct(ExecState* exec, const ArgList& args)
 {
     JSObject* proto = static_cast<JSObject*>(exec->lexicalGlobalObject()->errorPrototype());
-    JSObject* imp = new ErrorInstance(proto);
+    JSObject* imp = new (exec) ErrorInstance(proto);
     JSObject* obj(imp);
 
     if (!args[0]->isUndefined())
-        imp->putDirect(exec->propertyNames().message, jsString(args[0]->toString(exec)));
+        imp->putDirect(exec->propertyNames().message, jsString(exec, args[0]->toString(exec)));
 
     return obj;
 }
@@ -107,8 +107,8 @@ JSValue* ErrorConstructor::callAsFunction(ExecState* exec, JSObject* /*thisObj*/
 NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, ErrorPrototype* errorProto, const UString& name, const UString& message)
     : JSObject(errorProto)
 {
-    putDirect(exec->propertyNames().name, jsString(name), 0);
-    putDirect(exec->propertyNames().message, jsString(message), 0);
+    putDirect(exec->propertyNames().name, jsString(exec, name), 0);
+    putDirect(exec->propertyNames().message, jsString(exec, message), 0);
 }
 
 // ------------------------------ NativeErrorConstructor -------------------------------
@@ -119,7 +119,7 @@ NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, FunctionPrototyp
     : InternalFunction(funcProto, Identifier(exec, prot->getDirect(exec->propertyNames().name)->getString()))
     , proto(prot)
 {
-    putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum); // ECMA 15.11.7.5
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete|ReadOnly|DontEnum); // ECMA 15.11.7.5
     putDirect(exec->propertyNames().prototype, proto, DontDelete|ReadOnly|DontEnum);
 }
 
@@ -130,10 +130,10 @@ ConstructType NativeErrorConstructor::getConstructData(ConstructData&)
 
 JSObject* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
 {
-    JSObject* imp = new ErrorInstance(proto);
+    JSObject* imp = new (exec) ErrorInstance(proto);
     JSObject* obj(imp);
     if (!args[0]->isUndefined())
-        imp->putDirect(exec->propertyNames().message, jsString(args[0]->toString(exec)));
+        imp->putDirect(exec->propertyNames().message, jsString(exec, args[0]->toString(exec)));
     return obj;
 }
 
index 4eb03d8..35f2b91 100644 (file)
@@ -26,6 +26,8 @@
 
 namespace KJS {
 
+    class ExecState;
+
     class Identifier {
         friend class PropertyMap;
     public:
index 514dd6f..ee9482e 100644 (file)
@@ -80,7 +80,7 @@ UString JSString::toString(ExecState*) const
 
 inline StringObject* StringObject::create(ExecState* exec, JSString* string)
 {
-    return new StringObject(exec->lexicalGlobalObject()->stringPrototype(), string);
+    return new (exec) StringObject(exec->lexicalGlobalObject()->stringPrototype(), string);
 }
 
 JSObject* JSString::toObject(ExecState* exec) const
@@ -93,19 +93,19 @@ JSObject* JSString::toThisObject(ExecState* exec) const
     return StringObject::create(exec, const_cast<JSString*>(this));
 }
 
-JSValue* JSString::lengthGetter(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue* JSString::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return jsNumber(static_cast<JSString*>(slot.slotBase())->value().size());
+    return jsNumber(exec, static_cast<JSString*>(slot.slotBase())->value().size());
 }
 
-JSValue* JSString::indexGetter(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue* JSString::indexGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
-    return jsString(static_cast<JSString*>(slot.slotBase())->value().substr(slot.index(), 1));
+    return jsString(exec, static_cast<JSString*>(slot.slotBase())->value().substr(slot.index(), 1));
 }
 
-JSValue* JSString::indexNumericPropertyGetter(ExecState*, unsigned index, const PropertySlot& slot)
+JSValue* JSString::indexNumericPropertyGetter(ExecState* exec, unsigned index, const PropertySlot& slot)
 {
-    return jsString(static_cast<JSString*>(slot.slotBase())->value().substr(index, 1));
+    return jsString(exec, static_cast<JSString*>(slot.slotBase())->value().substr(index, 1));
 }
 
 bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
index df4d5e0..9d02cb8 100644 (file)
@@ -27,6 +27,7 @@
 #include "JSGlobalObject.h"
 #include "Machine.h"
 #include "Parser.h"
+#include "completion.h"
 #include "debugger.h"
 #include <profiler/Profiler.h>
 #include <stdio.h>
index c86e6d0..e795995 100644 (file)
@@ -21,6 +21,8 @@
 #include "config.h"
 #include "list.h"
 
+#include "JSValue.h"
+
 using std::min;
 
 namespace KJS {
@@ -60,8 +62,8 @@ void ArgList::slowAppend(JSValue* v)
     if (!m_markSet) {
         // We can only register for explicit marking once we know which heap
         // is the current one, i.e., when a non-immediate value is appended.
-        if (!JSImmediate::isImmediate(v)) { // Will be: if (Heap* heap = Heap::heap(v))
-            ListSet& markSet = Collector::markListSet();
+        if (Heap* heap = Heap::heap(v)) {
+            ListSet& markSet = heap->markListSet();
             markSet.add(this);
             m_markSet = &markSet;
         }
index 81f2614..3e93d66 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2007 Apple Computer, Inc.
+ *  Copyright (C) 2003, 2007, 2008 Apple Computer, Inc.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -22,7 +22,7 @@
 #ifndef KJS_LIST_H
 #define KJS_LIST_H
 
-#include <kjs/JSValue.h>
+#include "JSImmediate.h"
 #include <wtf/HashSet.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/Vector.h>
@@ -120,7 +120,7 @@ namespace KJS {
         void slowAppend(JSValue*);
         
         JSValue** buffer() const { return *m_bufferSlot + m_offset; }
-        
+
         JSValue*** m_bufferSlot;
         size_t m_offset;
         size_t m_size;
index 39a398f..cfb0e3a 100644 (file)
@@ -109,7 +109,7 @@ private:
         return cachedVal;
 
       const HashEntry* entry = slot.staticEntry();
-      JSValue* val = new PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
+      JSValue* val = new (exec) PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
       thisObj->putDirect(propertyName, val, entry->attributes);
       return val;
   }
@@ -249,7 +249,7 @@ private:
       ASSERT(obj->isObject());
       return static_cast<JSObject* >(obj);
     }
-    JSObject* newObject = new ClassCtor(exec);
+    JSObject* newObject = new (exec) ClassCtor(exec);
     globalObject->putDirect(propertyName, newObject, DontEnum);
     return newObject;
   }
index 02536b7..e1c39a3 100644 (file)
@@ -195,7 +195,7 @@ static inline const UString currentSourceURL(ExecState*)
 
 RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
 {
-    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(msg));
+    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), msg));
     generator.emitThrow(exception);
     return exception;
 }
@@ -204,7 +204,7 @@ RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const ch
 {
     UString message = msg;
     substitute(message, label.ustring());
-    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(message));
+    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(generator.globalExec(), message));
     generator.emitThrow(exception);
     return exception;
 }
@@ -272,7 +272,7 @@ RegisterID* NumberNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 RegisterID* StringNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
     // FIXME: should we try to atomize constant strings?
-    return generator.emitLoad(generator.finalDestination(dst), jsOwnedString(m_value));
+    return generator.emitLoad(generator.finalDestination(dst), jsOwnedString(generator.globalExec(), m_value));
 }
 
 // ------------------------------ RegExpNode -----------------------------------
@@ -321,7 +321,7 @@ RegisterID* ArrayNode::emitCode(CodeGenerator& generator, RegisterID* dst)
         generator.emitPutByIndex(newArray.get(), length++, value);
     }
 
-    value = generator.emitLoad(generator.newTemporary(), jsNumber(m_elision + length));
+    value = generator.emitLoad(generator.newTemporary(), jsNumber(generator.globalExec(), m_elision + length));
     generator.emitPutById(newArray.get(), generator.propertyNames().length, value);
 
     return generator.moveToDestinationIfNeeded(dst, newArray.get());
@@ -1692,12 +1692,12 @@ void FuncDeclNode::addParams()
 
 JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
 {
-    JSFunction* func = new JSFunction(exec, m_ident, m_body.get(), scopeChain);
+    JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
 
     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
-    func->putDirect(exec->propertyNames().length, jsNumber(m_body->parameters().size()), ReadOnly | DontDelete | DontEnum);
+    func->putDirect(exec->propertyNames().length, jsNumber(exec, m_body->parameters().size()), ReadOnly | DontDelete | DontEnum);
     return func;
 }
 
@@ -1715,7 +1715,7 @@ RegisterID* FuncExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 
 JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
 {
-    JSFunction* func = new JSFunction(exec, m_ident, m_body.get(), scopeChain);
+    JSFunction* func = new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
@@ -1729,7 +1729,7 @@ JSFunction* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeCha
      */
 
     if (!m_ident.isNull()) {
-        JSObject* functionScopeObject = new JSObject;
+        JSObject* functionScopeObject = new (exec) JSObject;
         functionScopeObject->putDirect(m_ident, func, ReadOnly | DontDelete);
         func->scope().push(functionScopeObject);
     }
index eddb6a6..e8537aa 100644 (file)
@@ -27,6 +27,7 @@
 #define NODES_H_
 
 #include "JSString.h"
+#include "LabelStack.h"
 #include "Opcode.h"
 #include "regexp.h"
 #include "RegisterID.h"
index a0c35ce..13abdcb 100644 (file)
@@ -43,18 +43,18 @@ static JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, const ArgLi
 ObjectPrototype::ObjectPrototype(ExecState* exec, FunctionPrototype* functionPrototype)
     : JSObject() // [[Prototype]] is null
 {
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
 
     // Mozilla extensions
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
-    putDirectFunction(new PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
+    putDirectFunction(new (exec) PrototypeFunction(exec, functionPrototype, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
 }
 
 
@@ -123,12 +123,12 @@ JSValue* objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject* thisObj,
 
 JSValue* objectProtoFuncToLocaleString(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
-    return jsString(thisObj->toString(exec));
+    return jsString(exec, thisObj->toString(exec));
 }
 
-JSValue* objectProtoFuncToString(ExecState*, JSObject* thisObj, const ArgList&)
+JSValue* objectProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
-    return jsString("[object " + thisObj->className() + "]");
+    return jsString(exec, "[object " + thisObj->className() + "]");
 }
 
 // ------------------------------ ObjectConstructor --------------------------------
@@ -140,7 +140,7 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, ObjectPrototype* objProto,
   putDirect(exec->propertyNames().prototype, objProto, DontEnum|DontDelete|ReadOnly);
 
   // no. of arguments for constructor
-  putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+  putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
 }
 
 ConstructType ObjectConstructor::getConstructData(ConstructData&)
@@ -160,7 +160,7 @@ JSObject* ObjectConstructor::construct(ExecState* exec, const ArgList& args)
       return arg->toObject(exec);
   case NullType:
   case UndefinedType:
-      return new JSObject(exec->lexicalGlobalObject()->objectPrototype());
+      return new (exec) JSObject(exec->lexicalGlobalObject()->objectPrototype());
   default:
       ASSERT_NOT_REACHED();
       return 0;
index 9092cba..3cb601b 100644 (file)
 
 namespace KJS {
 
-    inline void gcProtect(JSValue *val) 
-    { 
-        Collector::protect(val);
+    inline void gcProtect(JSValue* val) 
+    {
+        Heap* heap = Heap::heap(val);
+        if (heap)
+            heap->protect(val);
     }
 
-    inline void gcUnprotect(JSValue *val)
-    { 
-        Collector::unprotect(val);
+    inline void gcUnprotect(JSValue* val)
+    {
+        Heap* heap = Heap::heap(val);
+        if (heap)
+            heap->unprotect(val);
     }
 
     inline void gcProtectNullTolerant(JSValue *val) 
index cf293aa..d2c4853 100644 (file)
@@ -40,22 +40,22 @@ namespace KJS {
 
 const ClassInfo StringObject::info = { "String", 0, 0, 0 };
 
-StringObject::StringObject(JSObject *proto)
+StringObject::StringObject(ExecState* exec, JSObject* proto)
   : JSWrapperObject(proto)
 {
-  setInternalValue(jsString(""));
+  setInternalValue(jsString(exec, ""));
 }
 
-StringObject::StringObject(JSObject *proto, JSString* string)
+StringObject::StringObject(JSObjectproto, JSString* string)
   : JSWrapperObject(proto)
 {
   setInternalValue(string);
 }
 
-StringObject::StringObject(JSObject *proto, const UString &string)
+StringObject::StringObject(ExecState* exec, JSObject* proto, const UString& string)
   : JSWrapperObject(proto)
 {
-  setInternalValue(jsString(string));
+  setInternalValue(jsString(exec, string));
 }
 
 bool StringObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
@@ -135,10 +135,10 @@ const ClassInfo StringPrototype::info = { "String", &StringObject::info, 0, Exec
 */
 // ECMA 15.5.4
 StringPrototype::StringPrototype(ExecState* exec, ObjectPrototype* objProto)
-  : StringObject(objProto)
+  : StringObject(exec, objProto)
 {
   // The constructor will be added later, after StringConstructor has been built
-  putDirect(exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum);
+  putDirect(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
 }
 
 bool StringPrototype::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot &slot)
@@ -314,10 +314,10 @@ static JSValue *replace(ExecState *exec, JSString* sourceVal, JSValue *pattern,
               if (matchStart < 0)
                 args.append(jsUndefined());
               else
-                args.append(jsString(source.substr(matchStart, matchLen)));
+                args.append(jsString(exec, source.substr(matchStart, matchLen)));
           }
           
-          args.append(jsNumber(completeMatchStart));
+          args.append(jsNumber(exec, completeMatchStart));
           args.append(sourceVal);
 
           substitutedReplacement = replacementFunction->callAsFunction(exec, exec->globalThisValue(), args)->toString(exec);
@@ -351,7 +351,7 @@ static JSValue *replace(ExecState *exec, JSString* sourceVal, JSValue *pattern,
     if (result == source)
       return sourceVal;
 
-    return jsString(result);
+    return jsString(exec, result);
   }
   
   // First arg is a string
@@ -365,14 +365,14 @@ static JSValue *replace(ExecState *exec, JSString* sourceVal, JSValue *pattern,
   if (replacementFunction) {
       ArgList args;
       
-      args.append(jsString(source.substr(matchPos, matchLen)));
-      args.append(jsNumber(matchPos));
+      args.append(jsString(exec, source.substr(matchPos, matchLen)));
+      args.append(jsNumber(exec, matchPos));
       args.append(sourceVal);
       
       replacementString = replacementFunction->callAsFunction(exec, exec->globalThisValue(), args)->toString(exec);
   }
 
-  return jsString(source.substr(0, matchPos) + replacementString + source.substr(matchPos + matchLen));
+  return jsString(exec, source.substr(0, matchPos) + replacementString + source.substr(matchPos + matchLen));
 }
 
 JSValue* stringProtoFuncToString(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -404,7 +404,7 @@ JSValue* stringProtoFuncCharAt(ExecState* exec, JSObject* thisObj, const ArgList
       u = s.substr(static_cast<int>(dpos), 1);
     else
       u = "";
-    return jsString(u);
+    return jsString(exec, u);
 }
 
 JSValue* stringProtoFuncCharCodeAt(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -418,9 +418,9 @@ JSValue* stringProtoFuncCharCodeAt(ExecState* exec, JSObject* thisObj, const Arg
     JSValue* a0 = args[0];
     double dpos = a0->toInteger(exec);
     if (dpos >= 0 && dpos < len)
-      result = jsNumber(s[static_cast<int>(dpos)]);
+      result = jsNumber(exec, s[static_cast<int>(dpos)]);
     else
-      result = jsNaN();
+      result = jsNaN(exec);
     return result;
 }
 
@@ -433,7 +433,7 @@ JSValue* stringProtoFuncConcat(ExecState* exec, JSObject* thisObj, const ArgList
     for (ArgList::const_iterator it = args.begin(); it != end; ++it) {
         s += (*it)->toString(exec);
     }
-    return jsString(s);
+    return jsString(exec, s);
 }
 
 JSValue* stringProtoFuncIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -450,7 +450,7 @@ JSValue* stringProtoFuncIndexOf(ExecState* exec, JSObject* thisObj, const ArgLis
         dpos = 0;
     else if (dpos > len)
         dpos = len;
-    return jsNumber(s.find(u2, static_cast<int>(dpos)));
+    return jsNumber(exec, s.find(u2, static_cast<int>(dpos)));
 }
 
 JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -468,7 +468,7 @@ JSValue* stringProtoFuncLastIndexOf(ExecState* exec, JSObject* thisObj, const Ar
         dpos = 0;
     else if (!(dpos <= len)) // true for NaN
         dpos = len;
-    return jsNumber(s.rfind(u2, static_cast<int>(dpos)));
+    return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
 }
 
 JSValue* stringProtoFuncMatch(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -507,7 +507,7 @@ JSValue* stringProtoFuncMatch(ExecState* exec, JSObject* thisObj, const ArgList&
       ArgList list;
       int lastIndex = 0;
       while (pos >= 0) {
-        list.append(jsString(u.substr(pos, matchLength)));
+        list.append(jsString(exec, u.substr(pos, matchLength)));
         lastIndex = pos;
         pos += matchLength == 0 ? 1 : matchLength;
         regExpObj->performMatch(reg.get(), u, pos, pos, matchLength);
@@ -549,7 +549,7 @@ JSValue* stringProtoFuncSearch(ExecState* exec, JSObject* thisObj, const ArgList
     int pos;
     int matchLength;
     regExpObj->performMatch(reg.get(), u, 0, pos, matchLength);
-    return jsNumber(pos);
+    return jsNumber(exec, pos);
 }
 
 JSValue* stringProtoFuncReplace(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -559,7 +559,7 @@ JSValue* stringProtoFuncReplace(ExecState* exec, JSObject* thisObj, const ArgLis
 
     JSString* sVal = thisObj->inherits(&StringObject::info) ?
       static_cast<StringObject*>(thisObj)->internalValue() :
-      static_cast<JSString*>(jsString(s));
+      static_cast<JSString*>(jsString(exec, s));
 
     JSValue* a0 = args[0];
     JSValue* a1 = args[1];
@@ -586,10 +586,10 @@ JSValue* stringProtoFuncSlice(ExecState* exec, JSObject* thisObj, const ArgList&
             from = 0;
         if (to > len)
             to = len;
-        return jsString(s.substr(static_cast<int>(from), static_cast<int>(to - from)));
+        return jsString(exec, s.substr(static_cast<int>(from), static_cast<int>(to - from)));
     }
 
-    return jsString("");
+    return jsString(exec, "");
 }
 
 JSValue* stringProtoFuncSplit(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -612,7 +612,7 @@ JSValue* stringProtoFuncSplit(ExecState* exec, JSObject* thisObj, const ArgList&
       RegExp *reg = static_cast<RegExpObject *>(a0)->regExp();
       if (u.isEmpty() && reg->match(u, 0) >= 0) {
         // empty string matched by regexp -> empty array
-        res->put(exec, exec->propertyNames().length, jsNumber(0));
+        res->put(exec, exec->propertyNames().length, jsNumber(exec, 0));
         return result;
       }
       pos = 0;
@@ -624,7 +624,7 @@ JSValue* stringProtoFuncSplit(ExecState* exec, JSObject* thisObj, const ArgList&
         int mlen = ovector[1] - ovector[0];
         pos = mpos + (mlen == 0 ? 1 : mlen);
         if (mpos != p0 || mlen) {
-          res->put(exec,i, jsString(u.substr(p0, mpos-p0)));
+          res->put(exec,i, jsString(exec, u.substr(p0, mpos-p0)));
           p0 = mpos + mlen;
           i++;
         }
@@ -633,7 +633,7 @@ JSValue* stringProtoFuncSplit(ExecState* exec, JSObject* thisObj, const ArgList&
           if (spos < 0)
             res->put(exec, i++, jsUndefined());
           else
-            res->put(exec, i++, jsString(u.substr(spos, ovector[si * 2 + 1] - spos)));
+            res->put(exec, i++, jsString(exec, u.substr(spos, ovector[si * 2 + 1] - spos)));
         }
       }
     } else {
@@ -641,15 +641,15 @@ JSValue* stringProtoFuncSplit(ExecState* exec, JSObject* thisObj, const ArgList&
       if (u2.isEmpty()) {
         if (u.isEmpty()) {
           // empty separator matches empty string -> empty array
-          res->put(exec, exec->propertyNames().length, jsNumber(0));
+          res->put(exec, exec->propertyNames().length, jsNumber(exec, 0));
           return result;
         } else {
           while (static_cast<uint32_t>(i) != limit && i < u.size()-1)
-            res->put(exec, i++, jsString(u.substr(p0++, 1)));
+            res->put(exec, i++, jsString(exec, u.substr(p0++, 1)));
         }
       } else {
         while (static_cast<uint32_t>(i) != limit && (pos = u.find(u2, p0)) >= 0) {
-          res->put(exec, i, jsString(u.substr(p0, pos-p0)));
+          res->put(exec, i, jsString(exec, u.substr(p0, pos - p0)));
           p0 = pos + u2.size();
           i++;
         }
@@ -657,8 +657,8 @@ JSValue* stringProtoFuncSplit(ExecState* exec, JSObject* thisObj, const ArgList&
     }
     // add remaining string, if any
     if (static_cast<uint32_t>(i) != limit)
-      res->put(exec, i++, jsString(u.substr(p0)));
-    res->put(exec, exec->propertyNames().length, jsNumber(i));
+      res->put(exec, i++, jsString(exec, u.substr(p0)));
+    res->put(exec, exec->propertyNames().length, jsNumber(exec, i));
     return result;
 }
 
@@ -674,9 +674,9 @@ JSValue* stringProtoFuncSubstr(ExecState* exec, JSObject* thisObj, const ArgList
     double start = a0->toInteger(exec);
     double length = a1->isUndefined() ? len : a1->toInteger(exec);
     if (start >= len)
-      return jsString("");
+      return jsString(exec, "");
     if (length < 0)
-      return jsString("");
+      return jsString(exec, "");
     if (start < 0) {
       start += len;
       if (start < 0)
@@ -684,7 +684,7 @@ JSValue* stringProtoFuncSubstr(ExecState* exec, JSObject* thisObj, const ArgList
     }
     if (length > len)
       length = len;
-    return jsString(s.substr(static_cast<int>(start), static_cast<int>(length)));
+    return jsString(exec, s.substr(static_cast<int>(start), static_cast<int>(length)));
 }
 
 JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -717,7 +717,7 @@ JSValue* stringProtoFuncSubstring(ExecState* exec, JSObject* thisObj, const ArgL
       end = start;
       start = temp;
     }
-    return jsString(s.substr((int)start, (int)end-(int)start));
+    return jsString(exec, s.substr((int)start, (int)end-(int)start));
 }
 
 JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -727,7 +727,7 @@ JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject* thisObj, const Ar
     
     JSString* sVal = thisObj->inherits(&StringObject::info)
         ? static_cast<StringObject*>(thisObj)->internalValue()
-        : static_cast<JSString*>(jsString(s));
+        : static_cast<JSString*>(jsString(exec, s));
     int ssize = s.size();
     if (!ssize)
         return sVal;
@@ -742,7 +742,7 @@ JSValue* stringProtoFuncToLowerCase(ExecState* exec, JSObject* thisObj, const Ar
     }
     if (length == ssize && memcmp(buffer.data(), s.data(), length * sizeof(UChar)) == 0)
         return sVal;
-    return jsString(UString(buffer.releaseBuffer(), length, false));
+    return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
 JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -752,7 +752,7 @@ JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject* thisObj, const Ar
 
     JSString* sVal = thisObj->inherits(&StringObject::info)
         ? static_cast<StringObject*>(thisObj)->internalValue()
-        : static_cast<JSString*>(jsString(s));
+        : static_cast<JSString*>(jsString(exec, s));
     int ssize = s.size();
     if (!ssize)
         return sVal;
@@ -767,7 +767,7 @@ JSValue* stringProtoFuncToUpperCase(ExecState* exec, JSObject* thisObj, const Ar
     }
     if (length == ssize && memcmp(buffer.data(), s.data(), length * sizeof(UChar)) == 0)
         return sVal;
-    return jsString(UString(buffer.releaseBuffer(), length, false));
+    return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
 JSValue* stringProtoFuncToLocaleLowerCase(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -778,7 +778,7 @@ JSValue* stringProtoFuncToLocaleLowerCase(ExecState* exec, JSObject* thisObj, co
     // FIXME: See http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt for locale-sensitive mappings that aren't implemented.
     JSString* sVal = thisObj->inherits(&StringObject::info)
         ? static_cast<StringObject*>(thisObj)->internalValue()
-        : static_cast<JSString*>(jsString(s));
+        : static_cast<JSString*>(jsString(exec, s));
     int ssize = s.size();
     if (!ssize)
         return sVal;
@@ -793,7 +793,7 @@ JSValue* stringProtoFuncToLocaleLowerCase(ExecState* exec, JSObject* thisObj, co
     }
     if (length == ssize && memcmp(buffer.data(), s.data(), length * sizeof(UChar)) == 0)
         return sVal;
-    return jsString(UString(buffer.releaseBuffer(), length, false));
+    return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
 JSValue* stringProtoFuncToLocaleUpperCase(ExecState* exec, JSObject* thisObj, const ArgList&)
@@ -803,7 +803,7 @@ JSValue* stringProtoFuncToLocaleUpperCase(ExecState* exec, JSObject* thisObj, co
 
     JSString* sVal = thisObj->inherits(&StringObject::info)
         ? static_cast<StringObject*>(thisObj)->internalValue()
-        : static_cast<JSString*>(jsString(s));
+        : static_cast<JSString*>(jsString(exec, s));
     int ssize = s.size();
     if (!ssize)
         return sVal;
@@ -818,81 +818,81 @@ JSValue* stringProtoFuncToLocaleUpperCase(ExecState* exec, JSObject* thisObj, co
     }
     if (length == ssize && memcmp(buffer.data(), s.data(), length * sizeof(UChar)) == 0)
         return sVal;
-    return jsString(UString(buffer.releaseBuffer(), length, false));
+    return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
 JSValue* stringProtoFuncLocaleCompare(ExecState* exec, JSObject* thisObj, const ArgList& args)
 {
     if (args.size() < 1)
-      return jsNumber(0);
+      return jsNumber(exec, 0);
 
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
     JSValue* a0 = args[0];
-    return jsNumber(localeCompare(s, a0->toString(exec)));
+    return jsNumber(exec, localeCompare(s, a0->toString(exec)));
 }
 
 JSValue* stringProtoFuncBig(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
-    return jsString("<big>" + s + "</big>");
+    return jsString(exec, "<big>" + s + "</big>");
 }
 
 JSValue* stringProtoFuncSmall(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
-    return jsString("<small>" + s + "</small>");
+    return jsString(exec, "<small>" + s + "</small>");
 }
 
 JSValue* stringProtoFuncBlink(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
-    return jsString("<blink>" + s + "</blink>");
+    return jsString(exec, "<blink>" + s + "</blink>");
 }
 
 JSValue* stringProtoFuncBold(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
-    return jsString("<b>" + s + "</b>");
+    return jsString(exec, "<b>" + s + "</b>");
 }
 
 JSValue* stringProtoFuncFixed(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
-    return jsString("<tt>" + s + "</tt>");
+    return jsString(exec, "<tt>" + s + "</tt>");
 }
 
 JSValue* stringProtoFuncItalics(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
-    return jsString("<i>" + s + "</i>");
+    return jsString(exec, "<i>" + s + "</i>");
 }
 
 JSValue* stringProtoFuncStrike(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
-    return jsString("<strike>" + s + "</strike>");
+    return jsString(exec, "<strike>" + s + "</strike>");
 }
 
 JSValue* stringProtoFuncSub(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
-    return jsString("<sub>" + s + "</sub>");
+    return jsString(exec, "<sub>" + s + "</sub>");
 }
 
 JSValue* stringProtoFuncSup(ExecState* exec, JSObject* thisObj, const ArgList&)
 {
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
-    return jsString("<sup>" + s + "</sup>");
+    return jsString(exec, "<sup>" + s + "</sup>");
 }
 
 JSValue* stringProtoFuncFontcolor(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -900,7 +900,7 @@ JSValue* stringProtoFuncFontcolor(ExecState* exec, JSObject* thisObj, const ArgL
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
     JSValue* a0 = args[0];
-    return jsString("<font color=\"" + a0->toString(exec) + "\">" + s + "</font>");
+    return jsString(exec, "<font color=\"" + a0->toString(exec) + "\">" + s + "</font>");
 }
 
 JSValue* stringProtoFuncFontsize(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -908,7 +908,7 @@ JSValue* stringProtoFuncFontsize(ExecState* exec, JSObject* thisObj, const ArgLi
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
     JSValue* a0 = args[0];
-    return jsString("<font size=\"" + a0->toString(exec) + "\">" + s + "</font>");
+    return jsString(exec, "<font size=\"" + a0->toString(exec) + "\">" + s + "</font>");
 }
 
 JSValue* stringProtoFuncAnchor(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -916,7 +916,7 @@ JSValue* stringProtoFuncAnchor(ExecState* exec, JSObject* thisObj, const ArgList
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
     JSValue* a0 = args[0];
-    return jsString("<a name=\"" + a0->toString(exec) + "\">" + s + "</a>");
+    return jsString(exec, "<a name=\"" + a0->toString(exec) + "\">" + s + "</a>");
 }
 
 JSValue* stringProtoFuncLink(ExecState* exec, JSObject* thisObj, const ArgList& args)
@@ -924,7 +924,7 @@ JSValue* stringProtoFuncLink(ExecState* exec, JSObject* thisObj, const ArgList&
     // This optimizes the common case that thisObj is a StringObject
     UString s = thisObj->inherits(&StringObject::info) ? static_cast<StringObject*>(thisObj)->internalValue()->value() : thisObj->toString(exec);
     JSValue* a0 = args[0];
-    return jsString("<a href=\"" + a0->toString(exec) + "\">" + s + "</a>");
+    return jsString(exec, "<a href=\"" + a0->toString(exec) + "\">" + s + "</a>");
 }
 
 // ------------------------------ StringConstructor ------------------------------
@@ -935,10 +935,10 @@ StringConstructor::StringConstructor(ExecState* exec, FunctionPrototype* funcPro
   // ECMA 15.5.3.1 String.prototype
   putDirect(exec->propertyNames().prototype, stringProto, DontEnum|DontDelete|ReadOnly);
 
-  putDirectFunction(new StringConstructorFunction(exec, funcProto, exec->propertyNames().fromCharCode), DontEnum);
+  putDirectFunction(new (exec) StringConstructorFunction(exec, funcProto, exec->propertyNames().fromCharCode), DontEnum);
 
   // no. of arguments for constructor
-  putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+  putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
 }
 
 
@@ -948,22 +948,22 @@ ConstructType StringConstructor::getConstructData(ConstructData&)
 }
 
 // ECMA 15.5.2
-JSObject *StringConstructor::construct(ExecState *exec, const ArgList &args)
+JSObject* StringConstructor::construct(ExecState* exec, const ArgList& args)
 {
-  JSObject *proto = exec->lexicalGlobalObject()->stringPrototype();
-  if (args.size() == 0)
-    return new StringObject(proto);
-  return new StringObject(proto, args[0]->toString(exec));
+  JSObjectproto = exec->lexicalGlobalObject()->stringPrototype();
+  if (!args.size())
+    return new (exec) StringObject(exec, proto);
+  return new (exec) StringObject(exec, proto, args[0]->toString(exec));
 }
 
 // ECMA 15.5.1
 JSValue *StringConstructor::callAsFunction(ExecState *exec, JSObject* /*thisObj*/, const ArgList &args)
 {
   if (args.isEmpty())
-    return jsString("");
+    return jsString(exec, "");
   else {
     JSValue *v = args[0];
-    return jsString(v->toString(exec));
+    return jsString(exec, v->toString(exec));
   }
 }
 
@@ -973,7 +973,7 @@ JSValue *StringConstructor::callAsFunction(ExecState *exec, JSObject* /*thisObj*
 StringConstructorFunction::StringConstructorFunction(ExecState* exec, FunctionPrototype* funcProto, const Identifier& name)
   : InternalFunction(funcProto, name)
 {
-  putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum);
+  putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete|ReadOnly|DontEnum);
 }
 
 JSValue *StringConstructorFunction::callAsFunction(ExecState *exec, JSObject* /*thisObj*/, const ArgList &args)
@@ -991,7 +991,7 @@ JSValue *StringConstructorFunction::callAsFunction(ExecState *exec, JSObject* /*
   } else
     s = "";
 
-  return jsString(s);
+  return jsString(exec, s);
 }
 
 } // namespace KJS
index 29daca7..a46b261 100644 (file)
@@ -31,8 +31,8 @@ namespace KJS {
 
   class StringObject : public JSWrapperObject {
   public:
-    StringObject(JSObject* prototype);
-    StringObject(JSObject* prototype, const UString&);
+    StringObject(ExecState*, JSObject* prototype);
+    StringObject(ExecState*, JSObject* prototype, const UString&);
 
     static StringObject* create(ExecState*, JSString*);
 
@@ -55,8 +55,8 @@ namespace KJS {
   // WebCore uses this to make style.filter undetectable
   class StringObjectThatMasqueradesAsUndefined : public StringObject {
   public:
-      StringObjectThatMasqueradesAsUndefined(JSObject* proto, const UString& string)
-          : StringObject(proto, string) { }
+      StringObjectThatMasqueradesAsUndefined(ExecState* exec, JSObject* proto, const UString& string)
+          : StringObject(exec, proto, string) { }
       virtual bool masqueradeAsUndefined() const { return true; }
       virtual bool toBoolean(ExecState*) const { return false; }
   };
index 081f9cd..e9207b8 100644 (file)
@@ -404,7 +404,7 @@ inline unsigned UString::toArrayIndex(bool *ok) const
 // huge buffer.
 // FIXME: this should be size_t but that would cause warnings until we
 // fix UString sizes to be size_t instead of int
-static const int minShareSize = Collector::minExtraCostSize / sizeof(UChar);
+static const int minShareSize = Heap::minExtraCostSize / sizeof(UChar);
 
 inline size_t UString::cost() const
 {
index e4aac82..e755902 100644 (file)
@@ -1,3 +1,27 @@
+2008-06-17  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        Prepare JavaScript heap for being per-thread.
+
+        * JSRun.cpp: (JSRun::JSRun): Create JSGlueGlobalObject in a shared JS heap.
+
+        * JSUtils.h: Made getThreadGlobalExecState available throughout JSGlue.
+
+        * JSUtils.cpp:
+        (JSObjectKJSValue): Pass an ExecState where now required.
+        (unprotectGlobalObject):
+        (initializeGlobalObjectKey):
+        (getThreadGlobalExecState):
+        Moved these functions from JSValueWrapper.cpp, as the global exec state is now needed
+        elsewhere. I'm not quite sure how this relates to the global object from JSRun, but
+        since the new uses are all for Heap access, there doesn't seem to be any behavior change.
+
+        * JavaScriptGlue.cpp:
+        (JSLockInterpreter): Don't call registerThread explicitly, as JSLock will do that.
+
+        * UserObjectImp.cpp: (UserObjectImp::toPrimitive): Pass ExecState* where now required.
+
 2008-06-17  Mark Rowe  <mrowe@apple.com>
 
         Reviewed by Darin Adler.
index 1981569..3abf538 100644 (file)
 #include "config.h"
 #include "JSRun.h"
 
+#include <JavaScriptCore/completion.h>
+
 JSRun::JSRun(CFStringRef source, JSFlags inFlags)
     :   JSBase(kJSRunTypeID),
         fSource(CFStringToUString(source)),
-        fGlobalObject(new JSGlueGlobalObject(inFlags)),
+        fGlobalObject(new (JSGlobalObject::Shared) JSGlueGlobalObject(inFlags)),
         fFlags(inFlags)
 {
 }
index f659d4c..487ef13 100644 (file)
@@ -155,14 +155,14 @@ JSValue *JSObjectKJSValue(JSUserObject* ptr)
                     CFTypeID typeID = CFGetTypeID(cfType);
                     if (typeID == CFStringGetTypeID())
                     {
-                        result = jsString(CFStringToUString((CFStringRef)cfType));
+                        result = jsString(getThreadGlobalExecState(), CFStringToUString((CFStringRef)cfType));
                         handled = true;
                     }
                     else if (typeID == CFNumberGetTypeID())
                     {
                         double num;
                         CFNumberGetValue((CFNumberRef)cfType, kCFNumberDoubleType, &num);
-                        result = jsNumber(num);
+                        result = jsNumber(getThreadGlobalExecState(), num);
                         handled = true;
                     }
                     else if (typeID == CFBooleanGetTypeID())
@@ -181,7 +181,7 @@ JSValue *JSObjectKJSValue(JSUserObject* ptr)
         }
         if (!handled)
         {
-            result = new UserObjectImp(ptr);
+            result = new (getThreadGlobalExecState()) UserObjectImp(ptr);
         }
     }
     return result;
@@ -378,3 +378,50 @@ CFTypeRef GetCFNull(void)
     return result;
 }
 
+/*
+ * This is a slight hack. The JSGlue API has no concept of execution state.
+ * However, execution state is an inherent part of JS, and JSCore requires it.
+ * So, we keep a single execution state for the whole thread and supply it
+ * where necessary.
+
+ * The execution state holds two things: (1) exceptions; (2) the global object. 
+ * JSGlue has no API for accessing exceptions, so we just discard them. As for
+ * the global object, JSGlue includes no calls that depend on it. Its property
+ * getters and setters are per-object; they don't walk up the enclosing scope. 
+ * Functions called by JSObjectCallFunction may reference values in the enclosing 
+ * scope, but they do so through an internally stored scope chain, so we don't 
+ * need to supply the global scope.
+ */      
+
+static pthread_key_t globalObjectKey;
+static pthread_once_t globalObjectKeyOnce = PTHREAD_ONCE_INIT;
+
+static void unprotectGlobalObject(void* data) 
+{
+    JSLock lock;
+    gcUnprotect(static_cast<JSGlobalObject*>(data));
+}
+
+static void initializeGlobalObjectKey()
+{
+    pthread_key_create(&globalObjectKey, unprotectGlobalObject);
+}
+
+ExecState* getThreadGlobalExecState()
+{
+    pthread_once(&globalObjectKeyOnce, initializeGlobalObjectKey);
+    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(pthread_getspecific(globalObjectKey));
+    if (!globalObject) {
+        globalObject = new (JSGlobalObject::Shared) JSGlueGlobalObject;
+        gcProtect(globalObject);
+        pthread_setspecific(globalObjectKey, globalObject);
+    }
+    
+    ExecState* exec = globalObject->globalExec();
+
+    // Discard exceptions -- otherwise an exception would forestall JS 
+    // evaluation throughout the thread
+    exec->clearException();
+    return exec;
+}
+
index 71678cb..f9f5d1d 100644 (file)
@@ -61,6 +61,8 @@ CFTypeRef GetCFNull(void);
 inline CFTypeRef RetainCFType(CFTypeRef x) { if (x) x = CFRetain(x); return x; }
 inline void ReleaseCFType(CFTypeRef x) { if (x) CFRelease(x);  }
 
+ExecState* getThreadGlobalExecState();
+
 enum {
     kJSInvalidTypeID = 0,
     kJSObjectTypeID,
index 27d28b2..65741b4 100644 (file)
@@ -46,53 +46,6 @@ JSValue *JSValueWrapper::GetValue()
     return fValue;
 }
 
-/*
- * This is a slight hack. The JSGlue API has no concept of execution state.
- * However, execution state is an inherent part of JS, and JSCore requires it.
- * So, we keep a single execution state for the whole thread and supply it
- * where necessary.
-
- * The execution state holds two things: (1) exceptions; (2) the global object. 
- * JSGlue has no API for accessing exceptions, so we just discard them. As for
- * the global object, JSGlue includes no calls that depend on it. Its property
- * getters and setters are per-object; they don't walk up the enclosing scope. 
- * Functions called by JSObjectCallFunction may reference values in the enclosing 
- * scope, but they do so through an internally stored scope chain, so we don't 
- * need to supply the global scope.
- */      
-
-pthread_key_t globalObjectKey;
-pthread_once_t globalObjectKeyOnce = PTHREAD_ONCE_INIT;
-
-static void unprotectGlobalObject(void* data) 
-{
-    JSLock lock;
-    gcUnprotect(static_cast<JSGlobalObject*>(data));
-}
-
-static void initializeGlobalObjectKey()
-{
-    pthread_key_create(&globalObjectKey, unprotectGlobalObject);
-}
-
-static ExecState* getThreadGlobalExecState()
-{
-    pthread_once(&globalObjectKeyOnce, initializeGlobalObjectKey);
-    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(pthread_getspecific(globalObjectKey));
-    if (!globalObject) {
-        globalObject = new JSGlueGlobalObject;
-        gcProtect(globalObject);
-        pthread_setspecific(globalObjectKey, globalObject);
-    }
-    
-    ExecState* exec = globalObject->globalExec();
-
-    // Discard exceptions -- otherwise an exception would forestall JS 
-    // evaluation throughout the thread
-    exec->clearException();
-    return exec;
-}
-
 void JSValueWrapper::GetJSObectCallBacks(JSObjectCallBacks& callBacks)
 {
     callBacks.dispose = (JSObjectDisposeProcPtr)JSValueWrapper::JSObjectDispose;
index 13fb6c3..eda5dbf 100644 (file)
@@ -32,6 +32,7 @@
 #include "JSBase.h"
 #include "JSObject.h"
 #include "JSRun.h"
+#include <JavaScriptCore/completion.h>
 #include <JavaScriptCore/InitializeThreading.h>
 
 static CFTypeRef sJSCFNullRef = 0;
@@ -338,7 +339,7 @@ void JSCollect()
     initializeThreading();
 
     JSLock lock;
-    Collector::collect();
+    getThreadGlobalExecState()->heap()->collect();
 }
 
 /*
@@ -649,7 +650,6 @@ void JSLockInterpreter()
 {
     initializeThreading();
     JSLock::lock();
-    JSLock::registerThread();
 }
 
 
index 4f3f3dc..c19956b 100644 (file)
@@ -183,15 +183,15 @@ JSValue *UserObjectImp::toPrimitive(ExecState *exec, JSType preferredType) const
                 result = jsBoolean(false);
             }
         } else if (cfType == CFStringGetTypeID()) {
-            result = jsString(CFStringToUString((CFStringRef)cfValue));
+            result = jsString(exec, CFStringToUString((CFStringRef)cfValue));
         } else if (cfType == CFNumberGetTypeID()) {
             double d = 0.0;
             CFNumberGetValue((CFNumberRef)cfValue, kCFNumberDoubleType, &d);
-            result = jsNumber(d);
+            result = jsNumber(exec, d);
         } else if (cfType == CFURLGetTypeID()) {
             CFURLRef absURL = CFURLCopyAbsoluteURL((CFURLRef)cfValue);
             if (absURL) {
-                result = jsString(CFStringToUString(CFURLGetString(absURL)));
+                result = jsString(exec, CFStringToUString(CFURLGetString(absURL)));
                 ReleaseCFType(absURL);
             }
         }
index 1c548d5..5761e2e 100644 (file)
@@ -1,3 +1,216 @@
+2008-06-17  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        Prepare JavaScript heap for being per-thread.
+
+        * ForwardingHeaders/kjs/JSGlobalData.h: Added.
+        * bindings/js/GCController.cpp:
+        (WebCore::collect):
+        (WebCore::GCController::gcTimerFired):
+        (WebCore::GCController::garbageCollectNow):
+        * bindings/js/JSAudioConstructor.cpp:
+        (WebCore::JSAudioConstructor::JSAudioConstructor):
+        * bindings/js/JSCSSRuleCustom.cpp:
+        (WebCore::toJS):
+        * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+        (WebCore::JSCSSStyleDeclaration::nameGetter):
+        * bindings/js/JSCSSValueCustom.cpp:
+        (WebCore::toJS):
+        * bindings/js/JSCanvasPixelArrayCustom.cpp:
+        (WebCore::JSCanvasPixelArray::indexGetter):
+        (WebCore::toJS):
+        * bindings/js/JSCanvasRenderingContext2DCustom.cpp:
+        (WebCore::toJS):
+        * bindings/js/JSClipboardCustom.cpp:
+        (WebCore::JSClipboard::types):
+        (WebCore::JSClipboard::getData):
+        * bindings/js/JSCustomXPathNSResolver.cpp:
+        (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
+        * bindings/js/JSDOMApplicationCacheCustom.cpp:
+        (WebCore::JSDOMApplicationCache::addEventListener):
+        (WebCore::JSDOMApplicationCache::removeEventListener):
+        (WebCore::JSDOMApplicationCache::setOnchecking):
+        (WebCore::JSDOMApplicationCache::setOnerror):
+        (WebCore::JSDOMApplicationCache::setOnnoupdate):
+        (WebCore::JSDOMApplicationCache::setOndownloading):
+        (WebCore::JSDOMApplicationCache::setOnprogress):
+        (WebCore::JSDOMApplicationCache::setOnupdateready):
+        (WebCore::JSDOMApplicationCache::setOncached):
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::jsStringOrNull):
+        (WebCore::jsOwnedStringOrNull):
+        (WebCore::jsStringOrUndefined):
+        (WebCore::jsStringOrFalse):
+        (WebCore::nonCachingStaticFunctionGetter):
+        (WebCore::objectToStringFunctionGetter):
+        * bindings/js/JSDOMBinding.h:
+        (WebCore::DOMObject::DOMObject):
+        (WebCore::cacheDOMObject):
+        (WebCore::cacheSVGDOMObject):
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore::JSDOMWindowBase::JSDOMWindowBase):
+        (WebCore::JSDOMWindowBase::getValueProperty):
+        (WebCore::JSDOMWindowBase::setListener):
+        (WebCore::JSDOMWindowBase::findOrCreateJSEventListener):
+        (WebCore::JSDOMWindowBase::findJSUnprotectedEventListener):
+        (WebCore::JSDOMWindowBase::findOrCreateJSUnprotectedEventListener):
+        (WebCore::windowProtoFuncAToB):
+        (WebCore::windowProtoFuncBToA):
+        (WebCore::windowProtoFuncSetTimeout):
+        (WebCore::windowProtoFuncSetInterval):
+        (WebCore::windowProtoFuncAddEventListener):
+        * bindings/js/JSDOMWindowBase.h:
+        * bindings/js/JSDOMWindowShell.cpp:
+        (WebCore::JSDOMWindowShell::operator new):
+        * bindings/js/JSDOMWindowShell.h:
+        * bindings/js/JSDocumentCustom.cpp:
+        (WebCore::toJS):
+        * bindings/js/JSElementCustom.cpp:
+        (WebCore::toJSNewlyCreated):
+        * bindings/js/JSEventCustom.cpp:
+        (WebCore::toJS):
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::JSLazyEventListener::eventParameterName):
+        (WebCore::JSLazyEventListener::parseCode):
+        * bindings/js/JSEventTargetBase.cpp:
+        (WebCore::jsEventTargetAddEventListener):
+        * bindings/js/JSEventTargetBase.h:
+        (WebCore::JSEventTargetPrototype::self):
+        * bindings/js/JSEventTargetNode.cpp:
+        (WebCore::JSEventTargetNode::setListener):
+        * bindings/js/JSHTMLCollectionCustom.cpp:
+        (WebCore::getNamedItems):
+        (WebCore::toJS):
+        * bindings/js/JSHTMLFormElementCustom.cpp:
+        (WebCore::JSHTMLFormElement::nameGetter):
+        * bindings/js/JSHTMLInputElementBase.cpp:
+        (WebCore::JSHTMLInputElementBase::getValueProperty):
+        * bindings/js/JSHTMLOptionElementConstructor.cpp:
+        (WebCore::JSHTMLOptionElementConstructor::JSHTMLOptionElementConstructor):
+        * bindings/js/JSHTMLOptionsCollectionCustom.cpp:
+        (WebCore::JSHTMLOptionsCollection::length):
+        * bindings/js/JSInspectedObjectWrapper.cpp:
+        (WebCore::JSInspectedObjectWrapper::wrap):
+        * bindings/js/JSInspectorCallbackWrapper.cpp:
+        (WebCore::JSInspectorCallbackWrapper::wrap):
+        * bindings/js/JSLocationCustom.cpp:
+        (WebCore::JSLocation::toString):
+        * bindings/js/JSNamedNodesCollection.cpp:
+        (WebCore::JSNamedNodesCollection::lengthGetter):
+        * bindings/js/JSNavigatorCustom.cpp:
+        (WebCore::JSNavigator::appVersion):
+        * bindings/js/JSNodeCustom.cpp:
+        (WebCore::createWrapper):
+        * bindings/js/JSNodeFilterCustom.cpp:
+        (WebCore::JSNodeFilter::acceptNode):
+        * bindings/js/JSPluginElementFunctions.cpp:
+        (WebCore::getRuntimeObject):
+        * bindings/js/JSRGBColor.cpp:
+        (WebCore::getJSRGBColor):
+        * bindings/js/JSSQLResultSetRowListCustom.cpp:
+        (WebCore::JSSQLResultSetRowList::item):
+        * bindings/js/JSSVGLazyEventListener.cpp:
+        (WebCore::JSSVGLazyEventListener::eventParameterName):
+        * bindings/js/JSStorageCustom.cpp:
+        (WebCore::JSStorage::nameGetter):
+        * bindings/js/JSStyleSheetCustom.cpp:
+        (WebCore::toJS):
+        * bindings/js/JSTextCustom.cpp:
+        (WebCore::toJSNewlyCreated):
+        * bindings/js/JSXMLHttpRequestConstructor.cpp:
+        (WebCore::JSXMLHttpRequestConstructor::construct):
+        * bindings/js/JSXMLHttpRequestCustom.cpp:
+        (WebCore::JSXMLHttpRequest::setOnreadystatechange):
+        (WebCore::JSXMLHttpRequest::setOnload):
+        (WebCore::JSXMLHttpRequest::setOnprogress):
+        (WebCore::JSXMLHttpRequest::getResponseHeader):
+        (WebCore::JSXMLHttpRequest::addEventListener):
+        (WebCore::JSXMLHttpRequest::removeEventListener):
+        * bindings/js/JSXSLTProcessorConstructor.cpp:
+        (WebCore::JSXSLTProcessorConstructor::construct):
+        * bindings/js/JSXSLTProcessorCustom.cpp:
+        (WebCore::JSXSLTProcessor::getParameter):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        * bridge/c/c_instance.cpp:
+        (KJS::Bindings::CInstance::defaultValue):
+        (KJS::Bindings::CInstance::stringValue):
+        (KJS::Bindings::CInstance::numberValue):
+        (KJS::Bindings::CInstance::valueOf):
+        * bridge/c/c_instance.h:
+        * bridge/c/c_utility.cpp:
+        (KJS::Bindings::convertNPVariantToValue):
+        * bridge/jni/jni_instance.cpp:
+        (JavaInstance::stringValue):
+        (JavaInstance::numberValue):
+        (JavaInstance::invokeMethod):
+        (JavaInstance::defaultValue):
+        (JavaInstance::valueOf):
+        * bridge/jni/jni_instance.h:
+        * bridge/jni/jni_jsobject.h:
+        * bridge/jni/jni_jsobject.mm:
+        (JavaJSObject::call):
+        (JavaJSObject::setMember):
+        (JavaJSObject::setSlot):
+        (JavaJSObject::convertJObjectToValue):
+        (JavaJSObject::getListFromJArray):
+        * bridge/jni/jni_objc.mm:
+        (KJS::Bindings::dispatchJNICall):
+        * bridge/jni/jni_runtime.cpp:
+        (JavaArray::convertJObjectToArray):
+        (JavaField::dispatchValueFromInstance):
+        (JavaField::valueFromInstance):
+        (JavaField::dispatchSetValueToInstance):
+        (JavaArray::valueAt):
+        * bridge/jni/jni_utility.h:
+        * bridge/objc/objc_class.mm:
+        (KJS::Bindings::ObjcClass::fallbackObject):
+        * bridge/objc/objc_instance.h:
+        * bridge/objc/objc_instance.mm:
+        (ObjcInstance::defaultValue):
+        (ObjcInstance::stringValue):
+        (ObjcInstance::numberValue):
+        (ObjcInstance::valueOf):
+        * bridge/objc/objc_utility.h:
+        * bridge/objc/objc_utility.mm:
+        (KJS::Bindings::convertNSStringToString):
+        (KJS::Bindings::convertObjcValueToValue):
+        * bridge/runtime.cpp:
+        (KJS::Bindings::Instance::createRuntimeObject):
+        * bridge/runtime.h:
+        (KJS::Bindings::Instance::valueOf):
+        * bridge/runtime_array.cpp:
+        (RuntimeArray::lengthGetter):
+        * bridge/runtime_method.cpp:
+        (RuntimeMethod::lengthGetter):
+        * bridge/runtime_object.cpp:
+        (RuntimeObjectImp::RuntimeObjectImp):
+        (RuntimeObjectImp::methodGetter):
+        (RuntimeObjectImp::defaultValue):
+        * dom/make_names.pl:
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::dropProtection):
+        * bridge/qt/qt_class.cpp:
+        (KJS::Bindings::QtClass::fallbackObject):
+        * bridge/qt/qt_instance.cpp:
+        (KJS::Bindings::QtRuntimeObjectImp::construct):
+        (KJS::Bindings::QtInstance::getRuntimeObject):
+        (KJS::Bindings::QtInstance::invokeDefaultMethod):
+        (KJS::Bindings::QtInstance::defaultValue):
+        (KJS::Bindings::QtInstance::stringValue):
+        (KJS::Bindings::QtInstance::numberValue):
+        (KJS::Bindings::QtInstance::valueOf):
+        * bridge/qt/qt_instance.h:
+        * bridge/qt/qt_runtime.cpp:
+        (KJS::Bindings::convertValueToQVariant):
+        (KJS::Bindings::convertQVariantToValue):
+        (KJS::Bindings::QtRuntimeMetaMethod::lengthGetter):
+        (KJS::Bindings::QtRuntimeMetaMethod::connectGetter):
+        (KJS::Bindings::QtRuntimeMetaMethod::disconnectGetter):
+        (KJS::Bindings::QtRuntimeConnectionMethod::lengthGetter):
+        (KJS::Bindings::QtConnectionObject::execute):
+        Pass ExecState* where now required.
+
 2008-06-19  Timothy Hatcher  <timothy@apple.com>
 
         Update the JavaScript syntax highlight colors to match Xcode.
diff --git a/WebCore/ForwardingHeaders/kjs/JSGlobalData.h b/WebCore/ForwardingHeaders/kjs/JSGlobalData.h
new file mode 100644 (file)
index 0000000..e5f143a
--- /dev/null
@@ -0,0 +1 @@
+#include <JavaScriptCore/JSGlobalData.h>
diff --git a/WebCore/ForwardingHeaders/kjs/completion.h b/WebCore/ForwardingHeaders/kjs/completion.h
new file mode 100644 (file)
index 0000000..329a0e5
--- /dev/null
@@ -0,0 +1 @@
+#include <JavaScriptCore/completion.h>
index 94c48a1..4691828 100644 (file)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "GCController.h"
 
+#include <kjs/JSGlobalData.h>
 #include <kjs/JSLock.h>
 #include <kjs/collector.h>
 
@@ -42,7 +43,7 @@ namespace WebCore {
 static void* collect(void*)
 {
     JSLock lock;
-    Collector::collect();
+    JSGlobalData::threadInstance().heap->collect();
     return 0;
 }
 
@@ -68,13 +69,13 @@ void GCController::garbageCollectSoon()
 void GCController::gcTimerFired(Timer<GCController>*)
 {
     JSLock lock;
-    Collector::collect();
+    JSGlobalData::threadInstance().heap->collect();
 }
 
 void GCController::garbageCollectNow()
 {
     JSLock lock;
-    Collector::collect();
+    JSGlobalData::threadInstance().heap->collect();
 }
 
 void GCController::garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone)
index c839095..7a8c544 100644 (file)
@@ -43,7 +43,7 @@ JSAudioConstructor::JSAudioConstructor(ExecState* exec, Document* document)
     : DOMObject(exec->lexicalGlobalObject()->objectPrototype())
     , m_document(document)
 {
-    putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
+    putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
 }
 
 ConstructType JSAudioConstructor::getConstructData(ConstructData&)
index 44a52a6..6eff6a9 100644 (file)
@@ -55,25 +55,25 @@ JSValue* toJS(ExecState* exec, CSSRule* rule)
 
     switch (rule->type()) {
         case CSSRule::STYLE_RULE:
-            ret = new JSCSSStyleRule(JSCSSRulePrototype::self(exec), static_cast<CSSStyleRule*>(rule));
+            ret = new (exec) JSCSSStyleRule(JSCSSRulePrototype::self(exec), static_cast<CSSStyleRule*>(rule));
             break;
         case CSSRule::MEDIA_RULE:
-            ret = new JSCSSMediaRule(JSCSSMediaRulePrototype::self(exec), static_cast<CSSMediaRule*>(rule));
+            ret = new (exec) JSCSSMediaRule(JSCSSMediaRulePrototype::self(exec), static_cast<CSSMediaRule*>(rule));
             break;
         case CSSRule::FONT_FACE_RULE:
-            ret = new JSCSSFontFaceRule(JSCSSFontFaceRulePrototype::self(exec), static_cast<CSSFontFaceRule*>(rule));
+            ret = new (exec) JSCSSFontFaceRule(JSCSSFontFaceRulePrototype::self(exec), static_cast<CSSFontFaceRule*>(rule));
             break;
         case CSSRule::PAGE_RULE:
-            ret = new JSCSSPageRule(JSCSSPageRulePrototype::self(exec), static_cast<CSSPageRule*>(rule));
+            ret = new (exec) JSCSSPageRule(JSCSSPageRulePrototype::self(exec), static_cast<CSSPageRule*>(rule));
             break;
         case CSSRule::IMPORT_RULE:
-            ret = new JSCSSImportRule(JSCSSImportRulePrototype::self(exec), static_cast<CSSImportRule*>(rule));
+            ret = new (exec) JSCSSImportRule(JSCSSImportRulePrototype::self(exec), static_cast<CSSImportRule*>(rule));
             break;
         case CSSRule::CHARSET_RULE:
-            ret = new JSCSSCharsetRule(JSCSSCharsetRulePrototype::self(exec), static_cast<CSSCharsetRule*>(rule));
+            ret = new (exec) JSCSSCharsetRule(JSCSSCharsetRulePrototype::self(exec), static_cast<CSSCharsetRule*>(rule));
             break;
         default:
-            ret = new JSCSSRule(JSCSSRulePrototype::self(exec), rule);
+            ret = new (exec) JSCSSRule(JSCSSRulePrototype::self(exec), rule);
             break;
     }
 
index 78817b8..cfbdecd 100644 (file)
@@ -140,8 +140,8 @@ JSValue* JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& pr
     RefPtr<CSSValue> v = thisObj->impl()->getPropertyCSSValue(prop);
     if (v) {
         if (pixelOrPos && v->cssValueType() == CSSValue::CSS_PRIMITIVE_VALUE)
-            return jsNumber(static_pointer_cast<CSSPrimitiveValue>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX));
-        return jsStringOrNull(v->cssText());
+            return jsNumber(exec, static_pointer_cast<CSSPrimitiveValue>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX));
+        return jsStringOrNull(exec, v->cssText());
     }
 
     // If the property is a shorthand property (such as "padding"), 
@@ -149,10 +149,10 @@ JSValue* JSCSSStyleDeclaration::nameGetter(ExecState* exec, const Identifier& pr
 
     // Make the SVG 'filter' attribute undetectable, to avoid confusion with the IE 'filter' attribute.
     if (propertyName == "filter")
-        return new StringObjectThatMasqueradesAsUndefined(exec->lexicalGlobalObject()->stringPrototype(),
+        return new (exec) StringObjectThatMasqueradesAsUndefined(exec, exec->lexicalGlobalObject()->stringPrototype(),
             thisObj->impl()->getPropertyValue(prop));
 
-    return jsString(thisObj->impl()->getPropertyValue(prop));
+    return jsString(exec, thisObj->impl()->getPropertyValue(prop));
 }
 
 
index 88147d7..e545119 100644 (file)
@@ -53,17 +53,17 @@ JSValue* toJS(ExecState* exec, CSSValue* value)
         return ret;
 
     if (value->isValueList())
-        ret = new JSCSSValueList(JSCSSValueListPrototype::self(exec), static_cast<CSSValueList*>(value));
+        ret = new (exec) JSCSSValueList(JSCSSValueListPrototype::self(exec), static_cast<CSSValueList*>(value));
 #if ENABLE(SVG)
     else if (value->isSVGPaint())
-        ret = new JSSVGPaint(JSSVGPaintPrototype::self(exec), static_cast<SVGPaint*>(value));
+        ret = new (exec) JSSVGPaint(JSSVGPaintPrototype::self(exec), static_cast<SVGPaint*>(value));
     else if (value->isSVGColor())
-        ret = new JSSVGColor(JSSVGColorPrototype::self(exec), static_cast<SVGColor*>(value));
+        ret = new (exec) JSSVGColor(JSSVGColorPrototype::self(exec), static_cast<SVGColor*>(value));
 #endif
     else if (value->isPrimitiveValue())
-        ret = new JSCSSPrimitiveValue(JSCSSPrimitiveValuePrototype::self(exec), static_cast<CSSPrimitiveValue*>(value));
+        ret = new (exec) JSCSSPrimitiveValue(JSCSSPrimitiveValuePrototype::self(exec), static_cast<CSSPrimitiveValue*>(value));
     else
-        ret = new JSCSSValue(JSCSSValuePrototype::self(exec), value);
+        ret = new (exec) JSCSSValue(JSCSSValuePrototype::self(exec), value);
 
     ScriptInterpreter::putDOMObject(value, ret);
     return ret;
index 5446048..5687450 100644 (file)
@@ -42,7 +42,7 @@ JSValue* JSCanvasPixelArray::indexGetter(ExecState* exec, const Identifier& prop
     unsigned char result;
     if (!array->get(index, result))
         return jsUndefined();
-    return jsNumber(result);
+    return jsNumber(exec, result);
 }
 
 void JSCanvasPixelArray::indexSetter(ExecState* exec, unsigned index, JSValue* value)
@@ -62,9 +62,9 @@ JSValue* toJS(ExecState* exec, CanvasPixelArray* pixels)
     if (ret)
         return ret;
     
-    ret = new JSCanvasPixelArray(JSCanvasPixelArrayPrototype::self(exec), pixels);
+    ret = new (exec) JSCanvasPixelArray(JSCanvasPixelArrayPrototype::self(exec), pixels);
     
-    Collector::reportExtraMemoryCost(pixels->length());
+    exec->heap()->reportExtraMemoryCost(pixels->length());
     
     ScriptInterpreter::putDOMObject(pixels, ret);
     
index 7799b2b..ca99dd3 100644 (file)
@@ -45,7 +45,7 @@ static JSValue* toJS(ExecState* exec, CanvasStyle* style)
         return toJS(exec, style->canvasGradient());
     if (style->pattern())
         return toJS(exec, style->pattern());
-    return jsString(style->color());
+    return jsString(exec, style->color());
 }
 
 static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState* exec, JSValue* value)
index 4602c1d..f99e05e 100644 (file)
@@ -58,7 +58,7 @@ JSValue* JSClipboard::types(ExecState* exec) const
     ArgList list;
     HashSet<String>::const_iterator end = types.end();
     for (HashSet<String>::const_iterator it = types.begin(); it != end; ++it)
-        list.append(jsString(UString(*it)));
+        list.append(jsString(exec, UString(*it)));
     return exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, list);
 }
 
@@ -93,7 +93,7 @@ JSValue* JSClipboard::getData(ExecState* exec, const ArgList& args)
     if (!success)
         return jsUndefined();
 
-    return jsString(result);
+    return jsString(exec, result);
 }
 
 JSValue* JSClipboard::setData(ExecState* exec, const ArgList& args)
index cf45ae7..3bbdb2a 100644 (file)
@@ -97,7 +97,7 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
     RefPtr<JSCustomXPathNSResolver> selfProtector(this);
 
     ArgList args;
-    args.append(jsString(prefix));
+    args.append(jsString(exec, prefix));
 
     String result;
     JSValue* retval;
index a354127..7ba8279 100644 (file)
@@ -73,7 +73,7 @@ JSValue* JSDOMApplicationCache::addEventListener(ExecState* exec, const ArgList&
     Frame* frame = impl()->frame();
     if (!frame)
         return jsUndefined();
-    RefPtr<JSUnprotectedEventListener> listener = toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(args[1], true);
+    RefPtr<JSUnprotectedEventListener> listener = toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, args[1], true);
     if (!listener)
         return jsUndefined();
     impl()->addEventListener(args[0]->toString(exec), listener.release(), args[2]->toBoolean(exec));
@@ -85,7 +85,7 @@ JSValue* JSDOMApplicationCache::removeEventListener(ExecState* exec, const ArgLi
     Frame* frame = impl()->frame();
     if (!frame)
         return jsUndefined();
-    JSUnprotectedEventListener* listener = toJSDOMWindow(frame)->findJSUnprotectedEventListener(args[1], true);
+    JSUnprotectedEventListener* listener = toJSDOMWindow(frame)->findJSUnprotectedEventListener(exec, args[1], true);
     if (!listener)
         return jsUndefined();
     impl()->removeEventListener(args[0]->toString(exec), listener, args[2]->toBoolean(exec));
@@ -102,10 +102,10 @@ JSValue* JSDOMApplicationCache::dispatchEvent(KJS::ExecState* exec, const ArgLis
     return jsBoolean(result);    
 }
 
-void JSDOMApplicationCache::setOnchecking(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnchecking(ExecState* exec, JSValue* value)
 {
     if (Frame* frame = impl()->frame())
-        impl()->setOnCheckingListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+        impl()->setOnCheckingListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
 }
 
 JSValue* JSDOMApplicationCache::onchecking(ExecState*) const
@@ -116,10 +116,10 @@ JSValue* JSDOMApplicationCache::onchecking(ExecState*) const
     return jsNull();
 }
 
-void JSDOMApplicationCache::setOnerror(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnerror(ExecState* exec, JSValue* value)
 {
     if (Frame* frame = impl()->frame())
-        impl()->setOnErrorListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+        impl()->setOnErrorListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
 }
 
 JSValue* JSDOMApplicationCache::onerror(ExecState*) const
@@ -130,10 +130,10 @@ JSValue* JSDOMApplicationCache::onerror(ExecState*) const
     return jsNull();
 }
 
-void JSDOMApplicationCache::setOnnoupdate(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnnoupdate(ExecState* exec, JSValue* value)
 {
     if (Frame* frame = impl()->frame())
-        impl()->setOnNoUpdateListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+        impl()->setOnNoUpdateListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
 }
 
 JSValue* JSDOMApplicationCache::onnoupdate(ExecState*) const
@@ -144,10 +144,10 @@ JSValue* JSDOMApplicationCache::onnoupdate(ExecState*) const
     return jsNull();
 }
 
-void JSDOMApplicationCache::setOndownloading(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOndownloading(ExecState* exec, JSValue* value)
 {
     if (Frame* frame = impl()->frame())
-        impl()->setOnDownloadingListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+        impl()->setOnDownloadingListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
 }
 
 JSValue* JSDOMApplicationCache::ondownloading(ExecState*) const
@@ -158,10 +158,10 @@ JSValue* JSDOMApplicationCache::ondownloading(ExecState*) const
     return jsNull();
 }
 
-void JSDOMApplicationCache::setOnprogress(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnprogress(ExecState* exec, JSValue* value)
 {
     if (Frame* frame = impl()->frame())
-        impl()->setOnProgressListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+        impl()->setOnProgressListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
 }
 
 JSValue* JSDOMApplicationCache::onprogress(ExecState*) const
@@ -172,10 +172,10 @@ JSValue* JSDOMApplicationCache::onprogress(ExecState*) const
     return jsNull();
 }
 
-void JSDOMApplicationCache::setOnupdateready(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOnupdateready(ExecState* exec, JSValue* value)
 {
     if (Frame* frame = impl()->frame())
-        impl()->setOnUpdateReadyListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+        impl()->setOnUpdateReadyListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
 }
 
 JSValue* JSDOMApplicationCache::onupdateready(ExecState*) const
@@ -186,10 +186,10 @@ JSValue* JSDOMApplicationCache::onupdateready(ExecState*) const
     return jsNull();
 }
 
-void JSDOMApplicationCache::setOncached(ExecState*, JSValue* value)
+void JSDOMApplicationCache::setOncached(ExecState* exec, JSValue* value)
 {
     if (Frame* frame = impl()->frame())
-        impl()->setOnCachedListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(value, true));
+        impl()->setOnCachedListener(toJSDOMWindow(frame)->findOrCreateJSUnprotectedEventListener(exec, value, true));
 }
 
 JSValue* JSDOMApplicationCache::oncached(ExecState*) const
index 93a0cef..89a498d 100644 (file)
@@ -204,53 +204,53 @@ void ScriptInterpreter::updateDOMNodeDocument(WebCore::Node* node, Document* old
     }
 }
 
-JSValue* jsStringOrNull(const String& s)
+JSValue* jsStringOrNull(ExecState* exec, const String& s)
 {
     if (s.isNull())
         return jsNull();
-    return jsString(s);
+    return jsString(exec, s);
 }
 
-JSValue* jsOwnedStringOrNull(const KJS::UString& s)
+JSValue* jsOwnedStringOrNull(ExecState* exec, const KJS::UString& s)
 {
     if (s.isNull())
         return jsNull();
-    return jsOwnedString(s);
+    return jsOwnedString(exec, s);
 }
 
-JSValue* jsStringOrUndefined(const String& s)
+JSValue* jsStringOrUndefined(ExecState* exec, const String& s)
 {
     if (s.isNull())
         return jsUndefined();
-    return jsString(s);
+    return jsString(exec, s);
 }
 
-JSValue* jsStringOrFalse(const String& s)
+JSValue* jsStringOrFalse(ExecState* exec, const String& s)
 {
     if (s.isNull())
         return jsBoolean(false);
-    return jsString(s);
+    return jsString(exec, s);
 }
 
-JSValue* jsStringOrNull(const KURL& url)
+JSValue* jsStringOrNull(ExecState* exec, const KURL& url)
 {
     if (url.isNull())
         return jsNull();
-    return jsString(url.string());
+    return jsString(exec, url.string());
 }
 
-JSValue* jsStringOrUndefined(const KURL& url)
+JSValue* jsStringOrUndefined(ExecState* exec, const KURL& url)
 {
     if (url.isNull())
         return jsUndefined();
-    return jsString(url.string());
+    return jsString(exec, url.string());
 }
 
-JSValue* jsStringOrFalse(const KURL& url)
+JSValue* jsStringOrFalse(ExecState* exec, const KURL& url)
 {
     if (url.isNull())
         return jsBoolean(false);
-    return jsString(url.string());
+    return jsString(exec, url.string());
 }
 
 UString valueToStringWithNullCheck(ExecState* exec, JSValue* value)
@@ -337,12 +337,12 @@ void printErrorMessageForFrame(Frame* frame, const String& message)
 JSValue* nonCachingStaticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
 {
     const HashEntry* entry = slot.staticEntry();
-    return new PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
+    return new (exec) PrototypeFunction(exec, entry->length, propertyName, entry->functionValue);
 }
 
 JSValue* objectToStringFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot&)
 {
-    return new PrototypeFunction(exec, 0, propertyName, objectProtoFuncToString);
+    return new (exec) PrototypeFunction(exec, 0, propertyName, objectProtoFuncToString);
 }
 
 } // namespace WebCore
index e0a33c9..aed93b9 100644 (file)
@@ -49,9 +49,6 @@ namespace WebCore {
         explicit DOMObject(KJS::JSValue* prototype) // FIXME: this should take a JSObject once JSLocation has a real prototype
             : JSObject(prototype)
         {
-            // DOMObject destruction is not thread-safe because DOMObjects wrap 
-            // unsafe WebCore DOM data structures.
-            KJS::Collector::collectOnMainThreadOnly(this);