]> git.saurik.com Git - apple/javascriptcore.git/commitdiff
JavaScriptCore-554.1.tar.gz ios-32 v554.1
authorApple <opensource@apple.com>
Mon, 26 Jul 2010 19:16:31 +0000 (19:16 +0000)
committerApple <opensource@apple.com>
Mon, 26 Jul 2010 19:16:31 +0000 (19:16 +0000)
341 files changed:
API/APICast.h
API/JSBase.cpp
API/JSBase.h
API/JSBasePrivate.h
API/JSCallbackConstructor.cpp
API/JSCallbackConstructor.h
API/JSCallbackFunction.cpp
API/JSCallbackFunction.h
API/JSCallbackObject.h
API/JSCallbackObjectFunctions.h
API/JSContextRef.cpp
API/JSContextRef.h
API/JSObjectRef.cpp
API/JSObjectRef.h
API/JSValueRef.cpp
API/WebKitAvailability.h
API/tests/testapi.c
API/tests/testapi.js
AllInOneFile.cpp
ChangeLog-2008-08-10 [deleted file]
DerivedSources.make
GNUmakefile.am
JavaScriptCore.exp
JavaScriptCore.gypi [new file with mode: 0644]
JavaScriptCore.iPhone.order
JavaScriptCore.order
JavaScriptCore.pri
JavaScriptCore.pro
JavaScriptCore.scons [deleted file]
JavaScriptCorePrefix.h
JavaScriptCoreSources.bkl
SConstruct [deleted file]
assembler/ARMv7Assembler.h [new file with mode: 0644]
assembler/AbstractMacroAssembler.h [new file with mode: 0644]
assembler/AssemblerBuffer.h
assembler/AssemblerBufferWithConstantPool.h [new file with mode: 0644]
assembler/CodeLocation.h [new file with mode: 0644]
assembler/LinkBuffer.h [new file with mode: 0644]
assembler/MacroAssembler.h
assembler/MacroAssemblerARMv7.h [new file with mode: 0644]
assembler/MacroAssemblerCodeRef.h [new file with mode: 0644]
assembler/MacroAssemblerX86.h [new file with mode: 0644]
assembler/MacroAssemblerX86Common.h [new file with mode: 0644]
assembler/MacroAssemblerX86_64.h [new file with mode: 0644]
assembler/RepatchBuffer.h [new file with mode: 0644]
assembler/X86Assembler.h
bytecode/CodeBlock.cpp
bytecode/CodeBlock.h
bytecode/EvalCodeCache.h
bytecode/Instruction.h
bytecode/JumpTable.h
bytecode/Opcode.h
bytecode/SamplingTool.cpp
bytecode/SamplingTool.h
bytecode/StructureStubInfo.h
bytecompiler/BytecodeGenerator.cpp
bytecompiler/BytecodeGenerator.h
bytecompiler/SegmentedVector.h [deleted file]
config.h
create_hash_table
debugger/Debugger.cpp
debugger/Debugger.h
debugger/DebuggerActivation.cpp
debugger/DebuggerActivation.h
debugger/DebuggerCallFrame.cpp
debugger/DebuggerCallFrame.h
interpreter/CachedCall.h [new file with mode: 0644]
interpreter/CallFrame.cpp
interpreter/CallFrame.h
interpreter/CallFrameClosure.h [new file with mode: 0644]
interpreter/Interpreter.cpp
interpreter/Interpreter.h
interpreter/Register.h
interpreter/RegisterFile.cpp
interpreter/RegisterFile.h
jit/ExecutableAllocator.h
jit/ExecutableAllocatorFixedVMPool.cpp [new file with mode: 0644]
jit/ExecutableAllocatorPosix.cpp
jit/ExecutableAllocatorWin.cpp
jit/JIT.cpp
jit/JIT.h
jit/JITArithmetic.cpp
jit/JITCall.cpp
jit/JITCode.h [new file with mode: 0644]
jit/JITInlineMethods.h
jit/JITOpcodes.cpp [new file with mode: 0644]
jit/JITPropertyAccess.cpp
jit/JITStubCall.h [new file with mode: 0644]
jit/JITStubs.cpp [new file with mode: 0644]
jit/JITStubs.h [new file with mode: 0644]
jsc.cpp
jsc.pro
jscore.bkl
parser/Grammar.y
parser/Lexer.cpp
parser/Lexer.h
parser/NodeConstructors.h [new file with mode: 0644]
parser/NodeInfo.h
parser/Nodes.cpp
parser/Nodes.h
parser/Parser.cpp
parser/Parser.h
parser/ParserArena.cpp [new file with mode: 0644]
parser/ParserArena.h [new file with mode: 0644]
parser/ResultType.h
parser/SourceProvider.h
pcre/dftables
pcre/pcre_compile.cpp
pcre/pcre_exec.cpp
profiler/CallIdentifier.h
profiler/HeavyProfile.cpp
profiler/HeavyProfile.h
profiler/Profile.cpp
profiler/Profile.h
profiler/ProfileGenerator.cpp
profiler/ProfileGenerator.h
profiler/ProfileNode.cpp
profiler/ProfileNode.h
profiler/Profiler.cpp
profiler/Profiler.h
profiler/ProfilerServer.mm
profiler/TreeProfile.cpp
profiler/TreeProfile.h
runtime/ArgList.cpp
runtime/ArgList.h
runtime/Arguments.cpp
runtime/Arguments.h
runtime/ArrayConstructor.cpp
runtime/ArrayPrototype.cpp
runtime/BatchedTransitionOptimizer.h
runtime/BooleanConstructor.cpp
runtime/BooleanConstructor.h
runtime/BooleanObject.h
runtime/BooleanPrototype.cpp
runtime/CallData.cpp
runtime/CallData.h
runtime/Collector.cpp
runtime/Collector.h
runtime/CommonIdentifiers.cpp
runtime/CommonIdentifiers.h
runtime/Completion.cpp
runtime/Completion.h
runtime/ConstructData.cpp
runtime/ConstructData.h
runtime/DateConstructor.cpp
runtime/DateConversion.cpp [new file with mode: 0644]
runtime/DateConversion.h [new file with mode: 0644]
runtime/DateInstance.cpp
runtime/DateInstance.h
runtime/DateMath.cpp [deleted file]
runtime/DateMath.h [deleted file]
runtime/DatePrototype.cpp
runtime/DatePrototype.h
runtime/Error.cpp
runtime/ErrorConstructor.cpp
runtime/ErrorPrototype.cpp
runtime/ExceptionHelpers.cpp
runtime/ExceptionHelpers.h
runtime/FunctionConstructor.cpp
runtime/FunctionPrototype.cpp
runtime/FunctionPrototype.h
runtime/GetterSetter.cpp
runtime/GetterSetter.h
runtime/InitializeThreading.cpp
runtime/InternalFunction.cpp
runtime/InternalFunction.h
runtime/JSAPIValueWrapper.cpp [new file with mode: 0644]
runtime/JSAPIValueWrapper.h [new file with mode: 0644]
runtime/JSActivation.cpp
runtime/JSActivation.h
runtime/JSArray.cpp
runtime/JSArray.h
runtime/JSByteArray.cpp
runtime/JSByteArray.h
runtime/JSCell.cpp
runtime/JSCell.h
runtime/JSFunction.cpp
runtime/JSFunction.h
runtime/JSGlobalData.cpp
runtime/JSGlobalData.h
runtime/JSGlobalObject.cpp
runtime/JSGlobalObject.h
runtime/JSGlobalObjectFunctions.cpp
runtime/JSGlobalObjectFunctions.h
runtime/JSImmediate.cpp
runtime/JSImmediate.h
runtime/JSNotAnObject.cpp
runtime/JSNotAnObject.h
runtime/JSNumberCell.cpp
runtime/JSNumberCell.h
runtime/JSONObject.cpp [new file with mode: 0644]
runtime/JSONObject.h [new file with mode: 0644]
runtime/JSObject.cpp
runtime/JSObject.h
runtime/JSPropertyNameIterator.cpp
runtime/JSPropertyNameIterator.h
runtime/JSStaticScopeObject.cpp
runtime/JSStaticScopeObject.h
runtime/JSString.cpp
runtime/JSString.h
runtime/JSValue.cpp
runtime/JSValue.h
runtime/JSVariableObject.h
runtime/JSWrapperObject.h
runtime/LiteralParser.cpp [new file with mode: 0644]
runtime/LiteralParser.h [new file with mode: 0644]
runtime/Lookup.cpp
runtime/Lookup.h
runtime/MathObject.cpp
runtime/MathObject.h
runtime/NativeErrorConstructor.cpp
runtime/NativeFunctionWrapper.h [new file with mode: 0644]
runtime/NumberConstructor.cpp
runtime/NumberConstructor.h
runtime/NumberObject.cpp
runtime/NumberObject.h
runtime/NumberPrototype.cpp
runtime/ObjectConstructor.cpp
runtime/ObjectPrototype.cpp
runtime/ObjectPrototype.h
runtime/Operations.cpp
runtime/Operations.h
runtime/PropertyMapHashTable.h
runtime/PropertySlot.cpp
runtime/PropertySlot.h
runtime/Protect.h
runtime/PutPropertySlot.h
runtime/RegExp.cpp
runtime/RegExp.h
runtime/RegExpConstructor.cpp
runtime/RegExpConstructor.h
runtime/RegExpMatchesArray.h
runtime/RegExpObject.cpp
runtime/RegExpObject.h
runtime/RegExpPrototype.cpp
runtime/ScopeChain.h
runtime/SmallStrings.cpp
runtime/StringConstructor.cpp
runtime/StringObject.cpp
runtime/StringObject.h
runtime/StringObjectThatMasqueradesAsUndefined.h
runtime/StringPrototype.cpp
runtime/Structure.cpp
runtime/Structure.h
runtime/StructureChain.cpp
runtime/StructureChain.h
runtime/StructureTransitionTable.h
runtime/TimeoutChecker.cpp [new file with mode: 0644]
runtime/TimeoutChecker.h [new file with mode: 0644]
runtime/TypeInfo.h
runtime/UString.cpp
runtime/UString.h
tests/mozilla/ecma_2/instanceof/instanceof-003.js
tests/mozilla/ecma_2/instanceof/regress-7635.js
tests/mozilla/expected.html
wrec/WREC.cpp
wrec/WRECGenerator.cpp
wrec/WRECGenerator.h
wtf/ASCIICType.h
wtf/AVLTree.h
wtf/Assertions.cpp
wtf/Assertions.h
wtf/ByteArray.h
wtf/CrossThreadRefCounted.h [new file with mode: 0644]
wtf/CurrentTime.cpp
wtf/CurrentTime.h
wtf/DateMath.cpp [new file with mode: 0644]
wtf/DateMath.h [new file with mode: 0644]
wtf/Deque.h
wtf/DisallowCType.h
wtf/FastAllocBase.h [new file with mode: 0644]
wtf/FastMalloc.cpp
wtf/FastMalloc.h
wtf/GOwnPtr.cpp
wtf/GOwnPtr.h
wtf/HashCountedSet.h
wtf/HashMap.h
wtf/HashSet.h
wtf/HashTraits.h
wtf/MainThread.cpp
wtf/MainThread.h
wtf/MathExtras.h
wtf/MessageQueue.h
wtf/NotFound.h
wtf/OwnFastMallocPtr.h [new file with mode: 0644]
wtf/OwnPtr.h
wtf/OwnPtrCommon.h [new file with mode: 0644]
wtf/OwnPtrWin.cpp
wtf/PassOwnPtr.h [new file with mode: 0644]
wtf/PassRefPtr.h
wtf/Platform.h
wtf/PtrAndFlags.h
wtf/RefCounted.h
wtf/RefPtr.h
wtf/RetainPtr.h
wtf/SegmentedVector.h [new file with mode: 0644]
wtf/StdLibExtras.h
wtf/StringExtras.h
wtf/TCPageMap.h
wtf/TCSystemAlloc.cpp
wtf/TCSystemAlloc.h
wtf/ThreadSpecific.h
wtf/ThreadSpecificWin.cpp
wtf/Threading.cpp
wtf/Threading.h
wtf/ThreadingGtk.cpp [deleted file]
wtf/ThreadingNone.cpp
wtf/ThreadingPthreads.cpp
wtf/ThreadingQt.cpp [deleted file]
wtf/ThreadingWin.cpp
wtf/TypeTraits.cpp [new file with mode: 0644]
wtf/TypeTraits.h [new file with mode: 0644]
wtf/VMTags.h [new file with mode: 0644]
wtf/Vector.h
wtf/VectorTraits.h
wtf/chromium/ChromiumThreading.h [new file with mode: 0644]
wtf/chromium/MainThreadChromium.cpp [new file with mode: 0644]
wtf/dtoa.cpp
wtf/dtoa.h
wtf/gtk/MainThreadGtk.cpp
wtf/gtk/ThreadingGtk.cpp [new file with mode: 0644]
wtf/iphone/MainThreadIPhone.mm
wtf/iphone/ThreadingNSThread.mm [deleted file]
wtf/mac/MainThreadMac.mm
wtf/qt/MainThreadQt.cpp
wtf/qt/ThreadingQt.cpp [new file with mode: 0644]
wtf/unicode/Unicode.h
wtf/unicode/glib/UnicodeGLib.cpp [new file with mode: 0644]
wtf/unicode/glib/UnicodeGLib.h [new file with mode: 0644]
wtf/unicode/glib/UnicodeMacrosFromICU.h [new file with mode: 0644]
wtf/unicode/qt4/UnicodeQt4.h
wtf/win/MainThreadWin.cpp
wtf/wx/MainThreadWx.cpp
yarr/RegexCompiler.cpp [new file with mode: 0644]
yarr/RegexCompiler.h [new file with mode: 0644]
yarr/RegexInterpreter.cpp [new file with mode: 0644]
yarr/RegexInterpreter.h [new file with mode: 0644]
yarr/RegexJIT.cpp [new file with mode: 0644]
yarr/RegexJIT.h [new file with mode: 0644]
yarr/RegexParser.h [new file with mode: 0644]
yarr/RegexPattern.h [new file with mode: 0644]

index 1344a1672119167149e068aa757af3548eaa898c..b6d15320aab3badfe0d650d80f09b57132378e2e 100644 (file)
 #ifndef APICast_h
 #define APICast_h
 
+#include "JSAPIValueWrapper.h"
 #include "JSValue.h"
+#include <wtf/Platform.h>
+#include <wtf/UnusedParam.h>
 
 namespace JSC {
     class ExecState;
     class PropertyNameArray;
     class JSGlobalData;
     class JSObject;
-    class JSValuePtr;
+    class JSValue;
 }
 
 typedef const struct OpaqueJSContextGroup* JSContextGroupRef;
@@ -55,9 +58,18 @@ inline JSC::ExecState* toJS(JSGlobalContextRef c)
     return reinterpret_cast<JSC::ExecState*>(c);
 }
 
-inline JSC::JSValuePtr toJS(JSValueRef v)
+inline JSC::JSValue toJS(JSC::ExecState*, JSValueRef v)
 {
-    return JSC::JSValuePtr::decode(reinterpret_cast<JSC::JSValueEncodedAsPointer*>(const_cast<OpaqueJSValue*>(v)));
+#if USE(JSVALUE32_64)
+    JSC::JSCell* jsCell = reinterpret_cast<JSC::JSCell*>(const_cast<OpaqueJSValue*>(v));
+    if (!jsCell)
+        return JSC::JSValue();
+    if (jsCell->isAPIValueWrapper())
+        return static_cast<JSC::JSAPIValueWrapper*>(jsCell)->value();
+    return jsCell;
+#else
+    return JSC::JSValue::decode(reinterpret_cast<JSC::EncodedJSValue>(const_cast<OpaqueJSValue*>(v)));
+#endif
 }
 
 inline JSC::JSObject* toJS(JSObjectRef o)
@@ -75,14 +87,18 @@ inline JSC::JSGlobalData* toJS(JSContextGroupRef g)
     return reinterpret_cast<JSC::JSGlobalData*>(const_cast<OpaqueJSContextGroup*>(g));
 }
 
-inline JSValueRef toRef(JSC::JSValuePtr v)
+inline JSValueRef toRef(JSC::ExecState* exec, JSC::JSValue v)
 {
-    return reinterpret_cast<JSValueRef>(JSC::JSValuePtr::encode(v));
-}
-
-inline JSValueRef* toRef(JSC::JSValuePtr* v)
-{
-    return reinterpret_cast<JSValueRef*>(v);
+#if USE(JSVALUE32_64)
+    if (!v)
+        return 0;
+    if (!v.isCell())
+        return reinterpret_cast<JSValueRef>(asCell(JSC::jsAPIValueWrapper(exec, v)));
+    return reinterpret_cast<JSValueRef>(asCell(v));
+#else
+    UNUSED_PARAM(exec);
+    return reinterpret_cast<JSValueRef>(JSC::JSValue::encode(v));
+#endif
 }
 
 inline JSObjectRef toRef(JSC::JSObject* o)
index 2ffe345d44f55c5061c2b56d7b0385319c5e067d..fc3d0fe1bcbe8707232390a9f23cc1cfc67a2b7a 100644 (file)
@@ -55,15 +55,15 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
 
     if (completion.complType() == Throw) {
         if (exception)
-            *exception = toRef(completion.value());
+            *exception = toRef(exec, completion.value());
         return 0;
     }
-    
+
     if (completion.value())
-        return toRef(completion.value());
+        return toRef(exec, completion.value());
     
     // happens, for example, when the only statement is an empty (';') statement
-    return toRef(jsUndefined());
+    return toRef(exec, jsUndefined());
 }
 
 bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
@@ -76,7 +76,7 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc
     Completion completion = checkSyntax(exec->dynamicGlobalObject()->globalExec(), source);
     if (completion.complType() == Throw) {
         if (exception)
-            *exception = toRef(completion.value());
+            *exception = toRef(exec, completion.value());
         return false;
     }
     
index f44d4ad88345f4901a267fe746cdb228ae9f089f..9f3d88eb18ff457eae53766345d560ac57af8809 100644 (file)
@@ -65,14 +65,28 @@ typedef struct OpaqueJSValue* JSObjectRef;
 /* JavaScript symbol exports */
 
 #undef JS_EXPORT
-#if defined(__GNUC__)
+#if defined(BUILDING_WX__)
+    #define JS_EXPORT
+#elif defined(__GNUC__)
     #define JS_EXPORT __attribute__((visibility("default")))
+#elif defined(_WIN32_WCE)
+    #if defined(JS_BUILDING_JS)
+        #define JS_EXPORT __declspec(dllexport)
+    #elif defined(JS_IMPORT_JS)
+        #define JS_EXPORT __declspec(dllimport)
+    #else
+        #define JS_EXPORT
+    #endif
 #elif defined(WIN32) || defined(_WIN32)
     /*
      * TODO: Export symbols with JS_EXPORT when using MSVC.
      * See http://bugs.webkit.org/show_bug.cgi?id=16227
      */
-    #define JS_EXPORT
+    #if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
+    #define JS_EXPORT __declspec(dllexport)
+    #else
+    #define JS_EXPORT __declspec(dllimport)
+    #endif
 #else
     #define JS_EXPORT
 #endif
index 6beacda221d8f87f84ef939a4501303f92e28cdd..befa31643eab931efe6720de8d81e2e2f318b26a 100644 (file)
@@ -43,7 +43,7 @@ owns a large non-GC memory region. Calling this function will encourage the
 garbage collector to collect soon, hoping to reclaim that large non-GC memory
 region.
 */
-JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT void JSReportExtraMemoryCost(JSContextRef ctx, size_t size) AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 #ifdef __cplusplus
 }
index e10733e8214812646f3e0e6ad7b9326221abe7af..64c83cb04df1496284d1a2586c4442d6eee1f5e5 100644 (file)
@@ -61,10 +61,17 @@ static JSObject* constructJSCallback(ExecState* exec, JSObject* constructor, con
         int argumentCount = static_cast<int>(args.size());
         Vector<JSValueRef, 16> arguments(argumentCount);
         for (int i = 0; i < argumentCount; i++)
-            arguments[i] = toRef(args.at(exec, i));
-            
-        JSLock::DropAllLocks dropAllLocks(exec);
-        return toJS(callback(ctx, constructorRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+            arguments[i] = toRef(exec, args.at(i));
+
+        JSValueRef exception = 0;
+        JSObjectRef result;
+        {
+            JSLock::DropAllLocks dropAllLocks(exec);
+            result = callback(ctx, constructorRef, argumentCount, arguments.data(), &exception);
+        }
+        if (exception)
+            exec->setException(toJS(exec, exception));
+        return toJS(result);
     }
     
     return toJS(JSObjectMake(ctx, static_cast<JSCallbackConstructor*>(constructor)->classRef(), 0));
index cb8307fad90f03b90049fc1575166738953bce35..1f0624911b9830bd65b22fd6219fc3a7f68028b7 100644 (file)
@@ -39,7 +39,7 @@ public:
     JSObjectCallAsConstructorCallback callback() const { return m_callback; }
     static const ClassInfo info;
     
-    static PassRefPtr<Structure> createStructure(JSValuePtr proto) 
+    static PassRefPtr<Structure> createStructure(JSValue proto) 
     { 
         return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot)); 
     }
index 86a2ebcfb6ee0283fd02652b43471db4a423ca9d..1b3217b40416ca82dad19955b4a10358a2a42ca8 100644 (file)
@@ -46,7 +46,7 @@ JSCallbackFunction::JSCallbackFunction(ExecState* exec, JSObjectCallAsFunctionCa
 {
 }
 
-JSValuePtr JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, JSValuePtr thisValue, const ArgList& args)
+JSValue JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args)
 {
     JSContextRef execRef = toRef(exec);
     JSObjectRef functionRef = toRef(functionObject);
@@ -55,10 +55,18 @@ JSValuePtr JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, J
     int argumentCount = static_cast<int>(args.size());
     Vector<JSValueRef, 16> arguments(argumentCount);
     for (int i = 0; i < argumentCount; i++)
-        arguments[i] = toRef(args.at(exec, i));
+        arguments[i] = toRef(exec, args.at(i));
 
-    JSLock::DropAllLocks dropAllLocks(exec);
-    return toJS(static_cast<JSCallbackFunction*>(functionObject)->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+    JSValueRef exception = 0;
+    JSValueRef result;
+    {
+        JSLock::DropAllLocks dropAllLocks(exec);
+        result = static_cast<JSCallbackFunction*>(functionObject)->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
+    }
+    if (exception)
+        exec->setException(toJS(exec, exception));
+
+    return toJS(exec, result);
 }
 
 CallType JSCallbackFunction::getCallData(CallData& callData)
index 46f6fccfcfa381f70caf091fcbaf9d7530c7f3bd..7dd87b59b58c5b9435969580bcc26cf05e50210a 100644 (file)
@@ -39,7 +39,7 @@ public:
     
     // InternalFunction mish-mashes constructor and function behavior -- we should 
     // refactor the code so this override isn't necessary
-    static PassRefPtr<Structure> createStructure(JSValuePtr proto) 
+    static PassRefPtr<Structure> createStructure(JSValue proto) 
     { 
         return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot)); 
     }
@@ -48,7 +48,7 @@ private:
     virtual CallType getCallData(CallData&);
     virtual const ClassInfo* classInfo() const { return &info; }
 
-    static JSValuePtr call(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+    static JSValue JSC_HOST_CALL call(ExecState*, JSObject*, JSValue, const ArgList&);
 
     JSObjectCallAsFunctionCallback m_callback;
 };
index 9001c439252a0c8f667268e5f39b0fb81a807d5b..9d22ad91f0f42b9363ea1a40c0e304baa8bfd923 100644 (file)
@@ -48,7 +48,7 @@ public:
     JSClassRef classRef() const { return m_callbackObjectData->jsClass; }
     bool inherits(JSClassRef) const;
 
-    static PassRefPtr<Structure> createStructure(JSValuePtr proto) 
+    static PassRefPtr<Structure> createStructure(JSValue proto) 
     { 
         return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | OverridesHasInstance)); 
     }
@@ -59,12 +59,12 @@ private:
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
     virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&);
     
-    virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
+    virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
 
     virtual bool deleteProperty(ExecState*, const Identifier&);
     virtual bool deleteProperty(ExecState*, unsigned);
 
-    virtual bool hasInstance(ExecState* exec, JSValuePtr value, JSValuePtr proto);
+    virtual bool hasInstance(ExecState* exec, JSValue value, JSValue proto);
 
     virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
@@ -77,14 +77,14 @@ private:
 
     void init(ExecState*);
  
-    static JSCallbackObject* asCallbackObject(JSValuePtr);
+    static JSCallbackObject* asCallbackObject(JSValue);
  
-    static JSValuePtr call(ExecState*, JSObject* functionObject, JSValuePtr thisValue, const ArgList&);
+    static JSValue JSC_HOST_CALL call(ExecState*, JSObject* functionObject, JSValue thisValue, const ArgList&);
     static JSObject* construct(ExecState*, JSObject* constructor, const ArgList&);
    
-    static JSValuePtr staticValueGetter(ExecState*, const Identifier&, const PropertySlot&);
-    static JSValuePtr staticFunctionGetter(ExecState*, const Identifier&, const PropertySlot&);
-    static JSValuePtr callbackGetter(ExecState*, const Identifier&, const PropertySlot&);
+    static JSValue staticValueGetter(ExecState*, const Identifier&, const PropertySlot&);
+    static JSValue staticFunctionGetter(ExecState*, const Identifier&, const PropertySlot&);
+    static JSValue callbackGetter(ExecState*, const Identifier&, const PropertySlot&);
 
     struct JSCallbackObjectData {
         JSCallbackObjectData(void* privateData, JSClassRef jsClass)
index 23f941da663ae0de557b726483298f7cf5ce764a..1abed3fb563608d82d0c8f1e5eba1017091bbd65 100644 (file)
@@ -40,7 +40,7 @@
 namespace JSC {
 
 template <class Base>
-inline JSCallbackObject<Base>* JSCallbackObject<Base>::asCallbackObject(JSValuePtr value)
+inline JSCallbackObject<Base>* JSCallbackObject<Base>::asCallbackObject(JSValue value)
 {
     ASSERT(asObject(value)->inherits(&info));
     return static_cast<JSCallbackObject*>(asObject(value));
@@ -99,7 +99,7 @@ template <class Base>
 UString JSCallbackObject<Base>::className() const
 {
     UString thisClassName = classRef()->className();
-    if (!thisClassName.isNull())
+    if (!thisClassName.isEmpty())
         return thisClassName;
     
     return Base::className();
@@ -125,9 +125,19 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, const Identifie
         } else if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
             if (!propertyNameRef)
                 propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-            JSLock::DropAllLocks dropAllLocks(exec);
-            if (JSValueRef value = getProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot()))) {
-                slot.setValue(toJS(value));
+            JSValueRef exception = 0;
+            JSValueRef value;
+            {
+                JSLock::DropAllLocks dropAllLocks(exec);
+                value = getProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+            }
+            exec->setException(toJS(exec, exception));
+            if (value) {
+                slot.setValue(toJS(exec, value));
+                return true;
+            }
+            if (exception) {
+                slot.setValue(jsUndefined());
                 return true;
             }
         }
@@ -157,19 +167,25 @@ bool JSCallbackObject<Base>::getOwnPropertySlot(ExecState* exec, unsigned proper
 }
 
 template <class Base>
-void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     JSContextRef ctx = toRef(exec);
     JSObjectRef thisRef = toRef(this);
     RefPtr<OpaqueJSString> propertyNameRef;
-    JSValueRef valueRef = toRef(value);
+    JSValueRef valueRef = toRef(exec, value);
     
     for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
         if (JSObjectSetPropertyCallback setProperty = jsClass->setProperty) {
             if (!propertyNameRef)
                 propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-            JSLock::DropAllLocks dropAllLocks(exec);
-            if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot())))
+            JSValueRef exception = 0;
+            bool result;
+            {
+                JSLock::DropAllLocks dropAllLocks(exec);
+                result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+            }
+            exec->setException(toJS(exec, exception));
+            if (result || exception)
                 return;
         }
         
@@ -180,8 +196,14 @@ void JSCallbackObject<Base>::put(ExecState* exec, const Identifier& propertyName
                 if (JSObjectSetPropertyCallback setProperty = entry->setProperty) {
                     if (!propertyNameRef)
                         propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-                    JSLock::DropAllLocks dropAllLocks(exec);
-                    if (setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, toRef(exec->exceptionSlot())))
+                    JSValueRef exception = 0;
+                    bool result;
+                    {
+                        JSLock::DropAllLocks dropAllLocks(exec);
+                        result = setProperty(ctx, thisRef, propertyNameRef.get(), valueRef, &exception);
+                    }
+                    exec->setException(toJS(exec, exception));
+                    if (result || exception)
                         return;
                 } else
                     throwError(exec, ReferenceError, "Attempt to set a property that is not settable.");
@@ -212,8 +234,14 @@ bool JSCallbackObject<Base>::deleteProperty(ExecState* exec, const Identifier& p
         if (JSObjectDeletePropertyCallback deleteProperty = jsClass->deleteProperty) {
             if (!propertyNameRef)
                 propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-            JSLock::DropAllLocks dropAllLocks(exec);
-            if (deleteProperty(ctx, thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
+            JSValueRef exception = 0;
+            bool result;
+            {
+                JSLock::DropAllLocks dropAllLocks(exec);
+                result = deleteProperty(ctx, thisRef, propertyNameRef.get(), &exception);
+            }
+            exec->setException(toJS(exec, exception));
+            if (result || exception)
                 return true;
         }
         
@@ -266,9 +294,15 @@ JSObject* JSCallbackObject<Base>::construct(ExecState* exec, JSObject* construct
             int argumentCount = static_cast<int>(args.size());
             Vector<JSValueRef, 16> arguments(argumentCount);
             for (int i = 0; i < argumentCount; i++)
-                arguments[i] = toRef(args.at(exec, i));
-            JSLock::DropAllLocks dropAllLocks(exec);
-            return toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+                arguments[i] = toRef(exec, args.at(i));
+            JSValueRef exception = 0;
+            JSObject* result;
+            {
+                JSLock::DropAllLocks dropAllLocks(exec);
+                result = toJS(callAsConstructor(execRef, constructorRef, argumentCount, arguments.data(), &exception));
+            }
+            exec->setException(toJS(exec, exception));
+            return result;
         }
     }
     
@@ -277,15 +311,22 @@ JSObject* JSCallbackObject<Base>::construct(ExecState* exec, JSObject* construct
 }
 
 template <class Base>
-bool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValuePtr value, JSValuePtr)
+bool JSCallbackObject<Base>::hasInstance(ExecState* exec, JSValue value, JSValue)
 {
     JSContextRef execRef = toRef(exec);
     JSObjectRef thisRef = toRef(this);
     
     for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass) {
         if (JSObjectHasInstanceCallback hasInstance = jsClass->hasInstance) {
-            JSLock::DropAllLocks dropAllLocks(exec);
-            return hasInstance(execRef, thisRef, toRef(value), toRef(exec->exceptionSlot()));
+            JSValueRef valueRef = toRef(exec, value);
+            JSValueRef exception = 0;
+            bool result;
+            {
+                JSLock::DropAllLocks dropAllLocks(exec);
+                result = hasInstance(execRef, thisRef, valueRef, &exception);
+            }
+            exec->setException(toJS(exec, exception));
+            return result;
         }
     }
     return false;
@@ -304,7 +345,7 @@ CallType JSCallbackObject<Base>::getCallData(CallData& callData)
 }
 
 template <class Base>
-JSValuePtr JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject, JSValuePtr thisValue, const ArgList& args)
+JSValue JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args)
 {
     JSContextRef execRef = toRef(exec);
     JSObjectRef functionRef = toRef(functionObject);
@@ -315,14 +356,20 @@ JSValuePtr JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObjec
             int argumentCount = static_cast<int>(args.size());
             Vector<JSValueRef, 16> arguments(argumentCount);
             for (int i = 0; i < argumentCount; i++)
-                arguments[i] = toRef(args.at(exec, i));
-            JSLock::DropAllLocks dropAllLocks(exec);
-            return toJS(callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), toRef(exec->exceptionSlot())));
+                arguments[i] = toRef(exec, args.at(i));
+            JSValueRef exception = 0;
+            JSValue result;
+            {
+                JSLock::DropAllLocks dropAllLocks(exec);
+                result = toJS(exec, callAsFunction(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception));
+            }
+            exec->setException(toJS(exec, exception));
+            return result;
         }
     }
     
     ASSERT_NOT_REACHED(); // getCallData should prevent us from reaching here
-    return noValue();
+    return JSValue();
 }
 
 template <class Base>
@@ -376,11 +423,19 @@ double JSCallbackObject<Base>::toNumber(ExecState* exec) const
     
     for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
         if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
-            JSLock::DropAllLocks dropAllLocks(exec);
-            if (JSValueRef value = convertToType(ctx, thisRef, kJSTypeNumber, toRef(exec->exceptionSlot()))) {
-                double dValue;
-                return toJS(value).getNumber(dValue) ? dValue : NaN;
+            JSValueRef exception = 0;
+            JSValueRef value;
+            {
+                JSLock::DropAllLocks dropAllLocks(exec);
+                value = convertToType(ctx, thisRef, kJSTypeNumber, &exception);
             }
+            if (exception) {
+                exec->setException(toJS(exec, exception));
+                return 0;
+            }
+
+            double dValue;
+            return toJS(exec, value).getNumber(dValue) ? dValue : NaN;
         }
             
     return Base::toNumber(exec);
@@ -394,13 +449,17 @@ UString JSCallbackObject<Base>::toString(ExecState* exec) const
     
     for (JSClassRef jsClass = classRef(); jsClass; jsClass = jsClass->parentClass)
         if (JSObjectConvertToTypeCallback convertToType = jsClass->convertToType) {
+            JSValueRef exception = 0;
             JSValueRef value;
             {
                 JSLock::DropAllLocks dropAllLocks(exec);
-                value = convertToType(ctx, thisRef, kJSTypeString, toRef(exec->exceptionSlot()));
+                value = convertToType(ctx, thisRef, kJSTypeString, &exception);
             }
-            if (value)
-                return toJS(value).getString();
+            if (exception) {
+                exec->setException(toJS(exec, exception));
+                return "";
+            }
+            return toJS(exec, value).getString();
         }
             
     return Base::toString(exec);
@@ -429,7 +488,7 @@ bool JSCallbackObject<Base>::inherits(JSClassRef c) const
 }
 
 template <class Base>
-JSValuePtr JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
 {
     JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
     
@@ -442,16 +501,24 @@ JSValuePtr JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Iden
                 if (JSObjectGetPropertyCallback getProperty = entry->getProperty) {
                     if (!propertyNameRef)
                         propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-                    JSLock::DropAllLocks dropAllLocks(exec);
-                    if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
-                        return toJS(value);
+                    JSValueRef exception = 0;
+                    JSValueRef value;
+                    {
+                        JSLock::DropAllLocks dropAllLocks(exec);
+                        value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
+                    }
+                    exec->setException(toJS(exec, exception));
+                    if (value)
+                        return toJS(exec, value);
+                    if (exception)
+                        return jsUndefined();
                 }
                     
     return throwError(exec, ReferenceError, "Static value property defined with NULL getProperty callback.");
 }
 
 template <class Base>
-JSValuePtr JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
 {
     JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
     
@@ -476,7 +543,7 @@ JSValuePtr JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const I
 }
 
 template <class Base>
-JSValuePtr JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
 {
     JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
     
@@ -487,9 +554,17 @@ JSValuePtr JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identif
         if (JSObjectGetPropertyCallback getProperty = jsClass->getProperty) {
             if (!propertyNameRef)
                 propertyNameRef = OpaqueJSString::create(propertyName.ustring());
-            JSLock::DropAllLocks dropAllLocks(exec);
-            if (JSValueRef value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), toRef(exec->exceptionSlot())))
-                return toJS(value);
+            JSValueRef exception = 0;
+            JSValueRef value;
+            {
+                JSLock::DropAllLocks dropAllLocks(exec);
+                value = getProperty(toRef(exec), thisRef, propertyNameRef.get(), &exception);
+            }
+            exec->setException(toJS(exec, exception));
+            if (value)
+                return toJS(exec, value);
+            if (exception)
+                return jsUndefined();
         }
             
     return throwError(exec, ReferenceError, "hasProperty callback returned true for a property that doesn't exist.");
index c331179ec71070d533c63bf79e600b28a4f1bfc9..a3bdc69ab2f24f7a32bed6325992391bfe4db773 100644 (file)
@@ -97,7 +97,7 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
 
     JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalObjectClass);
     ExecState* exec = globalObject->globalExec();
-    JSValuePtr prototype = globalObjectClass->prototype(exec);
+    JSValue prototype = globalObjectClass->prototype(exec);
     if (!prototype)
         prototype = jsNull();
     globalObject->resetPrototype(prototype);
index bc89511cb85924ff6d48a64c96ace428f27ebad8..c5c8a71e6467464919a3204fff699254dc37cd06 100644 (file)
@@ -48,7 +48,7 @@ extern "C" {
  synchronization is required.
 @result The created JSContextGroup.
 */
-JS_EXPORT JSContextGroupRef JSContextGroupCreate() AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSContextGroupRef JSContextGroupCreate() AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 /*!
 @function
@@ -56,14 +56,14 @@ JS_EXPORT JSContextGroupRef JSContextGroupCreate() AVAILABLE_AFTER_WEBKIT_VERSIO
 @param group The JSContextGroup to retain.
 @result A JSContextGroup that is the same as group.
 */
-JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 /*!
 @function
 @abstract Releases a JavaScript context group.
 @param group The JSContextGroup to release.
 */
-JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT void JSContextGroupRelease(JSContextGroupRef group) AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 /*!
 @function
@@ -92,7 +92,7 @@ JS_EXPORT JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
 @result A JSGlobalContext with a global object of class globalObjectClass and a context
  group equal to group.
 */
-JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 /*!
 @function
@@ -123,7 +123,7 @@ JS_EXPORT JSObjectRef JSContextGetGlobalObject(JSContextRef ctx);
 @param ctx The JSContext whose group you want to get.
 @result ctx's group.
 */
-JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSContextGroupRef JSContextGetGroup(JSContextRef ctx) AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 #ifdef __cplusplus
 }
index e81e5129fc55a3a8866d50e3802fad1efe1a56f0..50ee6354f9484a095d9830aee883a33f6d9bb55f 100644 (file)
@@ -105,10 +105,10 @@ JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsClass, JSObje
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    JSValuePtr jsPrototype = jsClass 
-        ? jsClass->prototype(exec)
-        : exec->lexicalGlobalObject()->objectPrototype();
-    
+    JSValue jsPrototype = jsClass ? jsClass->prototype(exec) : 0;
+    if (!jsPrototype)
+        jsPrototype = exec->lexicalGlobalObject()->objectPrototype();
+
     JSCallbackConstructor* constructor = new (exec) JSCallbackConstructor(exec->lexicalGlobalObject()->callbackConstructorStructure(), jsClass, callAsConstructor);
     constructor->putDirect(exec->propertyNames().prototype, jsPrototype, DontEnum | DontDelete | ReadOnly);
     return toRef(constructor);
@@ -122,7 +122,7 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
 
     Identifier nameID = name ? name->identifier(&exec->globalData()) : Identifier(exec, "anonymous");
     
-    ArgList args;
+    MarkedArgumentBuffer args;
     for (unsigned i = 0; i < parameterCount; i++)
         args.append(jsString(exec, parameterNames[i]->ustring()));
     args.append(jsString(exec, body->ustring()));
@@ -130,7 +130,7 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa
     JSObject* result = constructFunction(exec, args, nameID, sourceURL->ustring(), startingLineNumber);
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         result = 0;
     }
@@ -145,9 +145,9 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
 
     JSObject* result;
     if (argumentCount) {
-        ArgList argList;
+        MarkedArgumentBuffer argList;
         for (size_t i = 0; i < argumentCount; ++i)
-            argList.append(toJS(arguments[i]));
+            argList.append(toJS(exec, arguments[i]));
 
         result = constructArray(exec, argList);
     } else
@@ -155,7 +155,7 @@ JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSVa
 
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         result = 0;
     }
@@ -169,14 +169,14 @@ JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSVal
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    ArgList argList;
+    MarkedArgumentBuffer argList;
     for (size_t i = 0; i < argumentCount; ++i)
-        argList.append(toJS(arguments[i]));
+        argList.append(toJS(exec, arguments[i]));
 
     JSObject* result = constructDate(exec, argList);
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         result = 0;
     }
@@ -190,14 +190,14 @@ JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSVa
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    ArgList argList;
+    MarkedArgumentBuffer argList;
     for (size_t i = 0; i < argumentCount; ++i)
-        argList.append(toJS(arguments[i]));
+        argList.append(toJS(exec, arguments[i]));
 
     JSObject* result = constructError(exec, argList);
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         result = 0;
     }
@@ -211,14 +211,14 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    ArgList argList;
+    MarkedArgumentBuffer argList;
     for (size_t i = 0; i < argumentCount; ++i)
-        argList.append(toJS(arguments[i]));
+        argList.append(toJS(exec, arguments[i]));
 
     JSObject* result = constructRegExp(exec, argList);
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         result = 0;
     }
@@ -226,16 +226,24 @@ JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSV
     return toRef(result);
 }
 
-JSValueRef JSObjectGetPrototype(JSContextRef, JSObjectRef object)
+JSValueRef JSObjectGetPrototype(JSContextRef ctx, JSObjectRef object)
 {
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
     JSObject* jsObject = toJS(object);
-    return toRef(jsObject->prototype());
+    return toRef(exec, jsObject->prototype());
 }
 
-void JSObjectSetPrototype(JSContextRef, JSObjectRef object, JSValueRef value)
+void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value)
 {
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
     JSObject* jsObject = toJS(object);
-    JSValuePtr jsValue = toJS(value);
+    JSValue jsValue = toJS(exec, value);
 
     jsObject->setPrototype(jsValue.isObject() ? jsValue : jsNull());
 }
@@ -259,13 +267,13 @@ JSValueRef JSObjectGetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef
 
     JSObject* jsObject = toJS(object);
 
-    JSValuePtr jsValue = jsObject->get(exec, propertyName->identifier(&exec->globalData()));
+    JSValue jsValue = jsObject->get(exec, propertyName->identifier(&exec->globalData()));
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
     }
-    return toRef(jsValue);
+    return toRef(exec, jsValue);
 }
 
 void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSPropertyAttributes attributes, JSValueRef* exception)
@@ -276,7 +284,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
 
     JSObject* jsObject = toJS(object);
     Identifier name(propertyName->identifier(&exec->globalData()));
-    JSValuePtr jsValue = toJS(value);
+    JSValue jsValue = toJS(exec, value);
 
     if (attributes && !jsObject->hasProperty(exec, name))
         jsObject->putWithAttributes(exec, name, jsValue, attributes);
@@ -287,7 +295,7 @@ void JSObjectSetProperty(JSContextRef ctx, JSObjectRef object, JSStringRef prope
 
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
     }
 }
@@ -300,13 +308,13 @@ JSValueRef JSObjectGetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsi
 
     JSObject* jsObject = toJS(object);
 
-    JSValuePtr jsValue = jsObject->get(exec, propertyIndex);
+    JSValue jsValue = jsObject->get(exec, propertyIndex);
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
     }
-    return toRef(jsValue);
+    return toRef(exec, jsValue);
 }
 
 
@@ -317,12 +325,12 @@ void JSObjectSetPropertyAtIndex(JSContextRef ctx, JSObjectRef object, unsigned p
     JSLock lock(exec);
 
     JSObject* jsObject = toJS(object);
-    JSValuePtr jsValue = toJS(value);
+    JSValue jsValue = toJS(exec, value);
     
     jsObject->put(exec, propertyIndex, jsValue);
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
     }
 }
@@ -338,7 +346,7 @@ bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr
     bool result = jsObject->deleteProperty(exec, propertyName->identifier(&exec->globalData()));
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
     }
     return result;
@@ -389,19 +397,19 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
     if (!jsThisObject)
         jsThisObject = exec->globalThisValue();
 
-    ArgList argList;
+    MarkedArgumentBuffer argList;
     for (size_t i = 0; i < argumentCount; i++)
-        argList.append(toJS(arguments[i]));
+        argList.append(toJS(exec, arguments[i]));
 
     CallData callData;
     CallType callType = jsObject->getCallData(callData);
     if (callType == CallTypeNone)
         return 0;
 
-    JSValueRef result = toRef(call(exec, jsObject, callType, callData, jsThisObject, argList));
+    JSValueRef result = toRef(exec, call(exec, jsObject, callType, callData, jsThisObject, argList));
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         result = 0;
     }
@@ -428,13 +436,13 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
     if (constructType == ConstructTypeNone)
         return 0;
 
-    ArgList argList;
+    MarkedArgumentBuffer argList;
     for (size_t i = 0; i < argumentCount; i++)
-        argList.append(toJS(arguments[i]));
+        argList.append(toJS(exec, arguments[i]));
     JSObjectRef result = toRef(construct(exec, jsObject, constructType, constructData, argList));
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         result = 0;
     }
index 461764c4fae3740d1bb99c40b5e48d91dd81c0f9..3e8b0eb62e3107ffae1bb5a1c960475e70c4b7b6 100644 (file)
@@ -441,7 +441,7 @@ JS_EXPORT JSObjectRef JSObjectMakeConstructor(JSContextRef ctx, JSClassRef jsCla
  @discussion The behavior of this function does not exactly match the behavior of the built-in Array constructor. Specifically, if one argument 
  is supplied, this function returns an array with one element.
  */
-JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 /*!
  @function
@@ -452,7 +452,7 @@ JS_EXPORT JSObjectRef JSObjectMakeArray(JSContextRef ctx, size_t argumentCount,
  @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result A JSObject that is a Date.
  */
-JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 /*!
  @function
@@ -463,7 +463,7 @@ JS_EXPORT JSObjectRef JSObjectMakeDate(JSContextRef ctx, size_t argumentCount, c
  @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result A JSObject that is a Error.
  */
-JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 /*!
  @function
@@ -474,7 +474,7 @@ JS_EXPORT JSObjectRef JSObjectMakeError(JSContextRef ctx, size_t argumentCount,
  @param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
  @result A JSObject that is a RegExp.
  */
-JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_3_1;
+JS_EXPORT JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) AVAILABLE_IN_WEBKIT_VERSION_4_0;
 
 /*!
 @function
index 70809526fcaa3dc1e20afd6d0c1e4dce07484f9c..2207181bd6223e833533c1a2f2b4c4ac792c834f 100644 (file)
 
 #include <algorithm> // for std::min
 
-JSType JSValueGetType(JSContextRef, JSValueRef value)
+JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
 {
-    JSC::JSValuePtr jsValue = toJS(value);
+    JSC::ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSC::JSLock lock(exec);
+
+    JSC::JSValue jsValue = toJS(exec, value);
+
     if (jsValue.isUndefined())
         return kJSTypeUndefined;
     if (jsValue.isNull())
@@ -60,45 +65,73 @@ JSType JSValueGetType(JSContextRef, JSValueRef value)
 
 using namespace JSC; // placed here to avoid conflict between JSC::JSType and JSType, above.
 
-bool JSValueIsUndefined(JSContextRef, JSValueRef value)
+bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
 {
-    JSValuePtr jsValue = toJS(value);
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    JSValue jsValue = toJS(exec, value);
     return jsValue.isUndefined();
 }
 
-bool JSValueIsNull(JSContextRef, JSValueRef value)
+bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
 {
-    JSValuePtr jsValue = toJS(value);
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    JSValue jsValue = toJS(exec, value);
     return jsValue.isNull();
 }
 
-bool JSValueIsBoolean(JSContextRef, JSValueRef value)
+bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
 {
-    JSValuePtr jsValue = toJS(value);
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    JSValue jsValue = toJS(exec, value);
     return jsValue.isBoolean();
 }
 
-bool JSValueIsNumber(JSContextRef, JSValueRef value)
+bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
 {
-    JSValuePtr jsValue = toJS(value);
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    JSValue jsValue = toJS(exec, value);
     return jsValue.isNumber();
 }
 
-bool JSValueIsString(JSContextRef, JSValueRef value)
+bool JSValueIsString(JSContextRef ctx, JSValueRef value)
 {
-    JSValuePtr jsValue = toJS(value);
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    JSValue jsValue = toJS(exec, value);
     return jsValue.isString();
 }
 
-bool JSValueIsObject(JSContextRef, JSValueRef value)
+bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
 {
-    JSValuePtr jsValue = toJS(value);
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    JSValue jsValue = toJS(exec, value);
     return jsValue.isObject();
 }
 
-bool JSValueIsObjectOfClass(JSContextRef, JSValueRef value, JSClassRef jsClass)
+bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
 {
-    JSValuePtr jsValue = toJS(value);
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    JSValue jsValue = toJS(exec, value);
     
     if (JSObject* o = jsValue.getObject()) {
         if (o->inherits(&JSCallbackObject<JSGlobalObject>::info))
@@ -115,25 +148,28 @@ bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* ex
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    JSValuePtr jsA = toJS(a);
-    JSValuePtr jsB = toJS(b);
+    JSValue jsA = toJS(exec, a);
+    JSValue jsB = toJS(exec, b);
 
-    bool result = JSValuePtr::equal(exec, jsA, jsB); // false if an exception is thrown
+    bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
     }
     return result;
 }
 
-bool JSValueIsStrictEqual(JSContextRef, JSValueRef a, JSValueRef b)
+bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
 {
-    JSValuePtr jsA = toJS(a);
-    JSValuePtr jsB = toJS(b);
-    
-    bool result = JSValuePtr::strictEqual(jsA, jsB);
-    return result;
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    JSValue jsA = toJS(exec, a);
+    JSValue jsB = toJS(exec, b);
+
+    return JSValue::strictEqual(jsA, jsB);
 }
 
 bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
@@ -142,32 +178,45 @@ bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObject
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    JSValuePtr jsValue = toJS(value);
+    JSValue jsValue = toJS(exec, value);
+
     JSObject* jsConstructor = toJS(constructor);
     if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
         return false;
     bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
     }
     return result;
 }
 
-JSValueRef JSValueMakeUndefined(JSContextRef)
+JSValueRef JSValueMakeUndefined(JSContextRef ctx)
 {
-    return toRef(jsUndefined());
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    return toRef(exec, jsUndefined());
 }
 
-JSValueRef JSValueMakeNull(JSContextRef)
+JSValueRef JSValueMakeNull(JSContextRef ctx)
 {
-    return toRef(jsNull());
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    return toRef(exec, jsNull());
 }
 
-JSValueRef JSValueMakeBoolean(JSContextRef, bool value)
+JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
 {
-    return toRef(jsBoolean(value));
+    ExecState* exec = toJS(ctx);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    return toRef(exec, jsBoolean(value));
 }
 
 JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
@@ -176,7 +225,7 @@ JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    return toRef(jsNumber(exec, value));
+    return toRef(exec, jsNumber(exec, value));
 }
 
 JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
@@ -185,13 +234,16 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    return toRef(jsString(exec, string->ustring()));
+    return toRef(exec, jsString(exec, string->ustring()));
 }
 
 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
 {
     ExecState* exec = toJS(ctx);
-    JSValuePtr jsValue = toJS(value);
+    exec->globalData().heap.registerThread();
+    JSLock lock(exec);
+
+    JSValue jsValue = toJS(exec, value);
     return jsValue.toBoolean(exec);
 }
 
@@ -201,12 +253,12 @@ double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    JSValuePtr jsValue = toJS(value);
+    JSValue jsValue = toJS(exec, value);
 
     double number = jsValue.toNumber(exec);
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         number = NaN;
     }
@@ -219,12 +271,12 @@ JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef*
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    JSValuePtr jsValue = toJS(value);
+    JSValue jsValue = toJS(exec, value);
     
     RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         stringRef.clear();
     }
@@ -237,12 +289,12 @@ JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exce
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    JSValuePtr jsValue = toJS(value);
+    JSValue jsValue = toJS(exec, value);
     
     JSObjectRef objectRef = toRef(jsValue.toObject(exec));
     if (exec->hadException()) {
         if (exception)
-            *exception = toRef(exec->exception());
+            *exception = toRef(exec, exec->exception());
         exec->clearException();
         objectRef = 0;
     }
@@ -255,7 +307,7 @@ void JSValueProtect(JSContextRef ctx, JSValueRef value)
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    JSValuePtr jsValue = toJS(value);
+    JSValue jsValue = toJS(exec, value);
     gcProtect(jsValue);
 }
 
@@ -265,6 +317,6 @@ void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
     exec->globalData().heap.registerThread();
     JSLock lock(exec);
 
-    JSValuePtr jsValue = toJS(value);
+    JSValue jsValue = toJS(exec, value);
     gcUnprotect(jsValue);
 }
index 127336095a649a6e040ada2c338fefae95caab8e..8402528317a920ac270dff409206a7d7b60f11d7 100644 (file)
@@ -38,6 +38,7 @@
 #define WEBKIT_VERSION_2_0    0x0200
 #define WEBKIT_VERSION_3_0    0x0300
 #define WEBKIT_VERSION_3_1    0x0310
+#define WEBKIT_VERSION_4_0    0x0400
 #define WEBKIT_VERSION_LATEST 0x9999
 
 #ifdef __APPLE__
 
 
 /*
- * AVAILABLE_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_IN_WEBKIT_VERSION_4_0
  * 
- * Used on declarations introduced after WebKit 3.1
+ * Used on declarations introduced in WebKit 4.0
  */
 #if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_LATEST
-    #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1     UNAVAILABLE_ATTRIBUTE
+    #define AVAILABLE_IN_WEBKIT_VERSION_4_0     UNAVAILABLE_ATTRIBUTE
 #elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_LATEST
-    #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1     WEAK_IMPORT_ATTRIBUTE
+    #define AVAILABLE_IN_WEBKIT_VERSION_4_0     WEAK_IMPORT_ATTRIBUTE
 #else
-    #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1
+    #define AVAILABLE_IN_WEBKIT_VERSION_4_0
 #endif
 
 /*
- * AVAILABLE_AFTER_WEBKIT_VERSION_3_1_BUT_DEPRECATED
+ * AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED
  * 
- * Used on declarations introduced after WebKit 3.1
- * and deprecated after WebKit 3.1
+ * Used on declarations introduced in WebKit 4.0
+ * and deprecated in WebKit 4.0
  */
 #if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
-    #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1_BUT_DEPRECATED    DEPRECATED_ATTRIBUTE
+    #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED    DEPRECATED_ATTRIBUTE
 #else
-    #define AVAILABLE_AFTER_WEBKIT_VERSION_3_1_BUT_DEPRECATED    AVAILABLE_AFTER_WEBKIT_VERSION_3_1
+    #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED    AVAILABLE_IN_WEBKIT_VERSION_4_0
 #endif
 
 /*
- * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
  * 
  * Used on declarations introduced in WebKit 1.0, 
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
  */
 #if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
-    #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    DEPRECATED_ATTRIBUTE
+    #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
-    #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
+    #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
 #endif
 
 /*
- * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
  * 
  * Used on declarations introduced in WebKit 1.1, 
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
  */
 #if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
-    #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    DEPRECATED_ATTRIBUTE
+    #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
-    #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
+    #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
 #endif
 
 /*
- * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
  * 
  * Used on declarations introduced in WebKit 1.2, 
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
  */
 #if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
-    #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    DEPRECATED_ATTRIBUTE
+    #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
-    #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
+    #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
 #endif
 
 /*
- * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
  * 
  * Used on declarations introduced in WebKit 1.3, 
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
  */
 #if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
-    #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    DEPRECATED_ATTRIBUTE
+    #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
-    #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
+    #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
 #endif
 
 /*
- * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
  * 
  * Used on declarations introduced in WebKit 2.0, 
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
  */
 #if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
-    #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    DEPRECATED_ATTRIBUTE
+    #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
-    #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
+    #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
 #endif
 
 /*
- * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
  * 
  * Used on declarations introduced in WebKit 3.0, 
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
  */
 #if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
-    #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    DEPRECATED_ATTRIBUTE
+    #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
-    #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
+    #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
 #endif
 
 /*
- * AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0
  * 
  * Used on declarations introduced in WebKit 3.1, 
- * but later deprecated after WebKit 3.1
+ * but later deprecated in WebKit 4.0
  */
 #if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
-    #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    DEPRECATED_ATTRIBUTE
+    #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
-    #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_3_1    AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
+    #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
 #endif
 
 /*
- * DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+ * DEPRECATED_IN_WEBKIT_VERSION_4_0
  * 
- * Used on types deprecated after WebKit 3.1
+ * Used on types deprecated in WebKit 4.0
  */
 #if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
-    #define DEPRECATED_AFTER_WEBKIT_VERSION_3_1    DEPRECATED_ATTRIBUTE
+    #define DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
-    #define DEPRECATED_AFTER_WEBKIT_VERSION_3_1
+    #define DEPRECATED_IN_WEBKIT_VERSION_4_0
 #endif
 
 
index 48c8583b60f8e2582f4e144318ad907d419c33ed..1f413e184365f76562bfbcb8fe4d406060a94f6e 100644 (file)
@@ -26,6 +26,7 @@
 #include "JavaScriptCore.h"
 #include "JSBasePrivate.h"
 #include <math.h>
+#define ASSERT_DISABLED 0
 #include <wtf/Assertions.h>
 #include <wtf/UnusedParam.h>
 
@@ -41,11 +42,13 @@ static double nan(const char*)
 #endif
 
 static JSGlobalContextRef context = 0;
-
+static int failed = 0;
 static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
 {
-    if (JSValueToBoolean(context, value) != expectedValue)
+    if (JSValueToBoolean(context, value) != expectedValue) {
         fprintf(stderr, "assertEqualsAsBoolean failed: %p, %d\n", value, expectedValue);
+        failed = 1;
+    }
 }
 
 static void assertEqualsAsNumber(JSValueRef value, double expectedValue)
@@ -55,8 +58,10 @@ static void assertEqualsAsNumber(JSValueRef value, double expectedValue)
     // FIXME <rdar://4668451> - On i386 the isnan(double) macro tries to map to the isnan(float) function,
     // causing a build break with -Wshorten-64-to-32 enabled.  The issue is known by the appropriate team.
     // After that's resolved, we can remove these casts
-    if (number != expectedValue && !(isnan((float)number) && isnan((float)expectedValue)))
+    if (number != expectedValue && !(isnan((float)number) && isnan((float)expectedValue))) {
         fprintf(stderr, "assertEqualsAsNumber failed: %p, %lf\n", value, expectedValue);
+        failed = 1;
+    }
 }
 
 static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue)
@@ -68,12 +73,17 @@ static void assertEqualsAsUTF8String(JSValueRef value, const char* expectedValue
     JSStringGetUTF8CString(valueAsString, jsBuffer, jsSize);
     
     unsigned i;
-    for (i = 0; jsBuffer[i]; i++)
-        if (jsBuffer[i] != expectedValue[i])
+    for (i = 0; jsBuffer[i]; i++) {
+        if (jsBuffer[i] != expectedValue[i]) {
             fprintf(stderr, "assertEqualsAsUTF8String failed at character %d: %c(%d) != %c(%d)\n", i, jsBuffer[i], jsBuffer[i], expectedValue[i], expectedValue[i]);
-        
-    if (jsSize < strlen(jsBuffer) + 1)
+            failed = 1;
+        }
+    }
+
+    if (jsSize < strlen(jsBuffer) + 1) {
         fprintf(stderr, "assertEqualsAsUTF8String failed: jsSize was too small\n");
+        failed = 1;
+    }
 
     free(jsBuffer);
     JSStringRelease(valueAsString);
@@ -94,16 +104,30 @@ static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedVa
     CFStringGetCharacters(expectedValueAsCFString, CFRangeMake(0, cfLength), cfBuffer);
     CFRelease(expectedValueAsCFString);
 
-    if (memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) != 0)
+    if (memcmp(jsBuffer, cfBuffer, cfLength * sizeof(UniChar)) != 0) {
         fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsBuffer != cfBuffer\n");
+        failed = 1;
+    }
     
-    if (jsLength != (size_t)cfLength)
+    if (jsLength != (size_t)cfLength) {
         fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsLength(%ld) != cfLength(%ld)\n", jsLength, cfLength);
-    
+        failed = 1;
+    }
+
     free(cfBuffer);
     JSStringRelease(valueAsString);
 }
 
+static bool timeZoneIsPST()
+{
+    char timeZoneName[70];
+    struct tm gtm;
+    memset(&gtm, 0, sizeof(gtm));
+    strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
+
+    return 0 == strcmp("PST", timeZoneName);
+}
+
 static JSValueRef jsGlobalValue; // non-stack value for testing JSValueProtect()
 
 /* MyObject pseudo-class */
@@ -115,6 +139,7 @@ static bool MyObject_hasProperty(JSContextRef context, JSObjectRef object, JSStr
 
     if (JSStringIsEqualToUTF8CString(propertyName, "alwaysOne")
         || JSStringIsEqualToUTF8CString(propertyName, "cantFind")
+        || JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")
         || JSStringIsEqualToUTF8CString(propertyName, "myPropertyName")
         || JSStringIsEqualToUTF8CString(propertyName, "hasPropertyLie")
         || JSStringIsEqualToUTF8CString(propertyName, "0")) {
@@ -140,7 +165,11 @@ static JSValueRef MyObject_getProperty(JSContextRef context, JSObjectRef object,
     if (JSStringIsEqualToUTF8CString(propertyName, "cantFind")) {
         return JSValueMakeUndefined(context);
     }
-    
+
+    if (JSStringIsEqualToUTF8CString(propertyName, "throwOnGet")) {
+        return JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+    }
+
     if (JSStringIsEqualToUTF8CString(propertyName, "0")) {
         *exception = JSValueMakeNumber(context, 1);
         return JSValueMakeNumber(context, 1);
@@ -159,6 +188,10 @@ static bool MyObject_setProperty(JSContextRef context, JSObjectRef object, JSStr
     if (JSStringIsEqualToUTF8CString(propertyName, "cantSet"))
         return true; // pretend we set the property in order to swallow it
     
+    if (JSStringIsEqualToUTF8CString(propertyName, "throwOnSet")) {
+        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+    }
+    
     return false;
 }
 
@@ -171,7 +204,7 @@ static bool MyObject_deleteProperty(JSContextRef context, JSObjectRef object, JS
         return true;
     
     if (JSStringIsEqualToUTF8CString(propertyName, "throwOnDelete")) {
-        *exception = JSValueMakeNumber(context, 2);
+        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
         return false;
     }
 
@@ -201,6 +234,11 @@ static JSValueRef MyObject_callAsFunction(JSContextRef context, JSObjectRef obje
     UNUSED_PARAM(thisObject);
     UNUSED_PARAM(exception);
 
+    if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnCall")) {
+        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+        return JSValueMakeUndefined(context);
+    }
+
     if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
         return JSValueMakeNumber(context, 1);
     
@@ -212,6 +250,11 @@ static JSObjectRef MyObject_callAsConstructor(JSContextRef context, JSObjectRef
     UNUSED_PARAM(context);
     UNUSED_PARAM(object);
 
+    if (argumentCount > 0 && JSValueIsString(context, arguments[0]) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, arguments[0], 0), "throwOnConstruct")) {
+        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), object, JSStringCreateWithUTF8CString("test script"), 1, exception);
+        return object;
+    }
+
     if (argumentCount > 0 && JSValueIsStrictEqual(context, arguments[0], JSValueMakeNumber(context, 0)))
         return JSValueToObject(context, JSValueMakeNumber(context, 1), exception);
     
@@ -223,6 +266,11 @@ static bool MyObject_hasInstance(JSContextRef context, JSObjectRef constructor,
     UNUSED_PARAM(context);
     UNUSED_PARAM(constructor);
 
+    if (JSValueIsString(context, possibleValue) && JSStringIsEqualToUTF8CString(JSValueToStringCopy(context, possibleValue, 0), "throwOnHasInstance")) {
+        JSEvaluateScript(context, JSStringCreateWithUTF8CString("throw 'an exception'"), constructor, JSStringCreateWithUTF8CString("test script"), 1, exception);
+        return false;
+    }
+
     JSStringRef numberString = JSStringCreateWithUTF8CString("Number");
     JSObjectRef numberConstructor = JSValueToObject(context, JSObjectGetProperty(context, JSContextGetGlobalObject(context), numberString, exception), exception);
     JSStringRelease(numberString);
@@ -297,6 +345,122 @@ static JSClassRef MyObject_class(JSContextRef context)
     return jsClass;
 }
 
+static bool EvilExceptionObject_hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleValue, JSValueRef* exception)
+{
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(constructor);
+    
+    JSStringRef hasInstanceName = JSStringCreateWithUTF8CString("hasInstance");
+    JSValueRef hasInstance = JSObjectGetProperty(context, constructor, hasInstanceName, exception);
+    JSStringRelease(hasInstanceName);
+    if (!hasInstance)
+        return false;
+    JSObjectRef function = JSValueToObject(context, hasInstance, exception);
+    JSValueRef result = JSObjectCallAsFunction(context, function, constructor, 1, &possibleValue, exception);
+    return result && JSValueToBoolean(context, result);
+}
+
+static JSValueRef EvilExceptionObject_convertToType(JSContextRef context, JSObjectRef object, JSType type, JSValueRef* exception)
+{
+    UNUSED_PARAM(object);
+    UNUSED_PARAM(exception);
+    JSStringRef funcName;
+    switch (type) {
+    case kJSTypeNumber:
+        funcName = JSStringCreateWithUTF8CString("toNumber");
+        break;
+    case kJSTypeString:
+        funcName = JSStringCreateWithUTF8CString("toStringExplicit");
+        break;
+    default:
+        return NULL;
+        break;
+    }
+    
+    JSValueRef func = JSObjectGetProperty(context, object, funcName, exception);
+    JSStringRelease(funcName);    
+    JSObjectRef function = JSValueToObject(context, func, exception);
+    if (!function)
+        return NULL;
+    JSValueRef value = JSObjectCallAsFunction(context, function, object, 0, NULL, exception);
+    if (!value) {
+        JSStringRef errorString = JSStringCreateWithUTF8CString("convertToType failed"); 
+        JSValueRef errorStringRef = JSValueMakeString(context, errorString);
+        JSStringRelease(errorString);
+        return errorStringRef;
+    }
+    return value;
+}
+
+JSClassDefinition EvilExceptionObject_definition = {
+    0,
+    kJSClassAttributeNone,
+
+    "EvilExceptionObject",
+    NULL,
+
+    NULL,
+    NULL,
+
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    EvilExceptionObject_hasInstance,
+    EvilExceptionObject_convertToType,
+};
+
+static JSClassRef EvilExceptionObject_class(JSContextRef context)
+{
+    UNUSED_PARAM(context);
+    
+    static JSClassRef jsClass;
+    if (!jsClass)
+        jsClass = JSClassCreate(&EvilExceptionObject_definition);
+    
+    return jsClass;
+}
+
+JSClassDefinition EmptyObject_definition = {
+    0,
+    kJSClassAttributeNone,
+    
+    NULL,
+    NULL,
+    
+    NULL,
+    NULL,
+    
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+};
+
+static JSClassRef EmptyObject_class(JSContextRef context)
+{
+    UNUSED_PARAM(context);
+    
+    static JSClassRef jsClass;
+    if (!jsClass)
+        jsClass = JSClassCreate(&EmptyObject_definition);
+    
+    return jsClass;
+}
+
+
 static JSValueRef Base_get(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception)
 {
     UNUSED_PARAM(object);
@@ -539,6 +703,17 @@ static JSValueRef globalObject_call(JSContextRef ctx, JSObjectRef function, JSOb
     return JSValueMakeNumber(ctx, 3);
 }
 
+static JSValueRef functionGC(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    UNUSED_PARAM(function);
+    UNUSED_PARAM(thisObject);
+    UNUSED_PARAM(argumentCount);
+    UNUSED_PARAM(arguments);
+    UNUSED_PARAM(exception);
+    JSGarbageCollect(context);
+    return JSValueMakeUndefined(context);
+}
+
 static JSStaticValue globalObject_staticValues[] = {
     { "globalStaticValue", globalObject_get, globalObject_set, kJSPropertyAttributeNone },
     { 0, 0, 0, 0 }
@@ -546,6 +721,7 @@ static JSStaticValue globalObject_staticValues[] = {
 
 static JSStaticFunction globalObject_staticFunctions[] = {
     { "globalStaticFunction", globalObject_call, kJSPropertyAttributeNone },
+    { "gc", functionGC, kJSPropertyAttributeNone },
     { 0, 0, 0 }
 };
 
@@ -656,6 +832,16 @@ int main(int argc, char* argv[])
     JSObjectSetProperty(context, globalObject, myObjectIString, myObject, kJSPropertyAttributeNone, NULL);
     JSStringRelease(myObjectIString);
     
+    JSObjectRef EvilExceptionObject = JSObjectMake(context, EvilExceptionObject_class(context), NULL);
+    JSStringRef EvilExceptionObjectIString = JSStringCreateWithUTF8CString("EvilExceptionObject");
+    JSObjectSetProperty(context, globalObject, EvilExceptionObjectIString, EvilExceptionObject, kJSPropertyAttributeNone, NULL);
+    JSStringRelease(EvilExceptionObjectIString);
+    
+    JSObjectRef EmptyObject = JSObjectMake(context, EmptyObject_class(context), NULL);
+    JSStringRef EmptyObjectIString = JSStringCreateWithUTF8CString("EmptyObject");
+    JSObjectSetProperty(context, globalObject, EmptyObjectIString, EmptyObject, kJSPropertyAttributeNone, NULL);
+    JSStringRelease(EmptyObjectIString);
+    
     JSValueRef exception;
 
     // Conversions that throw exceptions
@@ -846,7 +1032,7 @@ int main(int argc, char* argv[])
     JSStringRelease(functionBody);
     
     string = JSValueToStringCopy(context, function, NULL);
-    assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) {return foo;}");
+    assertEqualsAsUTF8String(JSValueMakeString(context, string), "function foo(foo) { return foo;\n}");
     JSStringRelease(string);
 
     JSStringRef print = JSStringCreateWithUTF8CString("print");
@@ -898,7 +1084,8 @@ int main(int argc, char* argv[])
 
     JSValueRef argumentsDateValues[] = { JSValueMakeNumber(context, 0) };
     o = JSObjectMakeDate(context, 1, argumentsDateValues, NULL);
-    assertEqualsAsUTF8String(o, "Wed Dec 31 1969 16:00:00 GMT-0800 (PST)");
+    if (timeZoneIsPST())
+        assertEqualsAsUTF8String(o, "Wed Dec 31 1969 16:00:00 GMT-0800 (PST)");
 
     string = JSStringCreateWithUTF8CString("an error message");
     JSValueRef argumentsErrorValues[] = { JSValueMakeString(context, string) };
@@ -953,10 +1140,18 @@ int main(int argc, char* argv[])
     ASSERT(JSValueIsEqual(context, v, o, NULL));
     JSStringRelease(script);
 
+    // Verify that creating a constructor for a class with no static functions does not trigger
+    // an assert inside putDirect or lead to a crash during GC. <https://bugs.webkit.org/show_bug.cgi?id=25785>
+    nullDefinition = kJSClassDefinitionEmpty;
+    nullClass = JSClassCreate(&nullDefinition);
+    myConstructor = JSObjectMakeConstructor(context, nullClass, 0);
+    JSClassRelease(nullClass);
+
     char* scriptUTF8 = createStringWithContentsOfFile(scriptPath);
-    if (!scriptUTF8)
+    if (!scriptUTF8) {
         printf("FAIL: Test script could not be loaded.\n");
-    else {
+        failed = 1;
+    } else {
         script = JSStringCreateWithUTF8CString(scriptUTF8);
         result = JSEvaluateScript(context, script, NULL, NULL, 1, &exception);
         if (JSValueIsUndefined(context, result))
@@ -968,6 +1163,7 @@ int main(int argc, char* argv[])
             CFShow(exceptionCF);
             CFRelease(exceptionCF);
             JSStringRelease(exceptionIString);
+            failed = 1;
         }
         JSStringRelease(script);
         free(scriptUTF8);
@@ -978,6 +1174,7 @@ int main(int argc, char* argv[])
     v = NULL;
     o = NULL;
     globalObject = NULL;
+    myConstructor = NULL;
 
     JSStringRelease(jsEmptyIString);
     JSStringRelease(jsOneIString);
@@ -991,6 +1188,27 @@ int main(int argc, char* argv[])
     JSGlobalContextRelease(context);
     JSClassRelease(globalObjectClass);
 
+    // Test for an infinite prototype chain that used to be created. This test
+    // passes if the call to JSObjectHasProperty() does not hang.
+
+    JSClassDefinition prototypeLoopClassDefinition = kJSClassDefinitionEmpty;
+    prototypeLoopClassDefinition.staticFunctions = globalObject_staticFunctions;
+    JSClassRef prototypeLoopClass = JSClassCreate(&prototypeLoopClassDefinition);
+    JSGlobalContextRef prototypeLoopContext = JSGlobalContextCreateInGroup(NULL, prototypeLoopClass);
+
+    JSStringRef nameProperty = JSStringCreateWithUTF8CString("name");
+    JSObjectHasProperty(prototypeLoopContext, JSContextGetGlobalObject(prototypeLoopContext), nameProperty);
+
+    JSGlobalContextRelease(prototypeLoopContext);
+    JSClassRelease(prototypeLoopClass);
+
+    printf("PASS: Infinite prototype chain does not occur.\n");
+
+    if (failed) {
+        printf("FAIL: Some tests failed.\n");
+        return 1;
+    }
+
     printf("PASS: Program exited normally.\n");
     return 0;
 }
index 9c8ca9ee2fd86e31e0025ff6c97d1ea28d46d029..82756b57c6e3cc1353adcc0c31fa5e8b2476f05b 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
+function bludgeonArguments() { if (0) arguments; return function g() {} }
+h = bludgeonArguments();
+gc();
+
+var failed = false;
+function pass(msg)
+{
+    print("PASS: " + msg, "green");
+}
+
+function fail(msg)
+{
+    print("FAIL: " + msg, "red");
+    failed = true;
+}
+
 function shouldBe(a, b)
 {
     var evalA;
@@ -33,23 +49,22 @@ function shouldBe(a, b)
     }
     
     if (evalA == b || isNaN(evalA) && typeof evalA == 'number' && isNaN(b) && typeof b == 'number')
-        print("PASS: " + a + " should be " + b + " and is.", "green");
+        pass(a + " should be " + b + " and is.");
     else
-        print("__FAIL__: " + a + " should be " + b + " but instead is " + evalA + ".", "red");
+        fail(a + " should be " + b + " but instead is " + evalA + ".");
 }
 
 function shouldThrow(a)
 {
-    var result = "__FAIL__: " + a + " did not throw an exception.";
-    
     var evalA;
     try {
         eval(a);
     } catch(e) {
-        result = "PASS: " + a + " threw: " + e;
+        pass(a + " threw: " + e);
+        return;
     }
-    
-    print(result);
+
+    fail(a + " did not throw an exception.");
 }
 
 function globalStaticFunction()
@@ -70,9 +85,14 @@ shouldBe("MyObject.alwaysOne", 1);
 MyObject.cantDelete = 1;
 delete MyObject.cantDelete;
 shouldBe("MyObject.cantDelete", 1);
-shouldBe("delete MyObject.throwOnDelete", 2); // deleteProperty -- should throw 2
+shouldBe("delete MyObject.throwOnDelete", "an exception");
 MyObject.cantSet = 1;
 shouldBe("MyObject.cantSet", undefined);
+shouldBe("MyObject.throwOnGet", "an exception");
+shouldBe("MyObject.throwOnSet = 5", "an exception");
+shouldBe("MyObject('throwOnCall')", "an exception");
+shouldBe("new MyObject('throwOnConstruct')", "an exception");
+shouldBe("'throwOnHasInstance' instanceof MyObject", "an exception");
 
 var foundMyPropertyName = false;
 var foundRegularType = false;
@@ -82,12 +102,16 @@ for (var p in MyObject) {
     if (p == "regularType")
         foundRegularType = true;
 }
-print(foundMyPropertyName
-      ? "PASS: MyObject.myPropertyName was enumerated"
-      : "__FAIL__: MyObject.myPropertyName was not enumerated");
-print(foundRegularType
-      ? "PASS: MyObject.regularType was enumerated"
-      : "__FAIL__: MyObject.regularType was not enumerated");
+
+if (foundMyPropertyName)
+    pass("MyObject.myPropertyName was enumerated");
+else
+    fail("MyObject.myPropertyName was not enumerated");
+
+if (foundRegularType)
+    pass("MyObject.regularType was enumerated");
+else
+    fail("MyObject.regularType was not enumerated");
 
 myObject = new MyObject();
 
@@ -100,7 +124,7 @@ shouldBe("MyObject ? 1 : 0", true); // toBoolean
 shouldBe("+MyObject", 1); // toNumber
 shouldBe("(MyObject.toString())", "[object MyObject]"); // toString
 shouldBe("String(MyObject)", "MyObjectAsString"); // type conversion to string
-shouldBe("MyObject - 0", NaN); // toPrimitive
+shouldBe("MyObject - 0", 1); // toNumber
 
 shouldBe("typeof MyConstructor", "object");
 constructedObject = new MyConstructor(1);
@@ -130,3 +154,21 @@ shouldBe("derived.baseDup = 0", 2);
 shouldBe("derived.baseOnly = 0", 1);
 shouldBe("derived.derivedOnly = 0", 2)
 shouldBe("derived.protoDup = 0", 2);
+
+shouldBe("undefined instanceof MyObject", false);
+EvilExceptionObject.hasInstance = function f() { return f(); };
+EvilExceptionObject.__proto__ = undefined;
+shouldThrow("undefined instanceof EvilExceptionObject");
+EvilExceptionObject.hasInstance = function () { return true; };
+shouldBe("undefined instanceof EvilExceptionObject", true);
+
+EvilExceptionObject.toNumber = function f() { return f(); }
+shouldThrow("EvilExceptionObject*5");
+EvilExceptionObject.toStringExplicit = function f() { return f(); }
+shouldThrow("String(EvilExceptionObject)");
+
+shouldBe("EmptyObject", "[object CallbackObject]");
+
+if (failed)
+    throw "Some tests failed";
+
index 904734f332eac206ddc527325c87eb3289cd7604..7b67dbe946e1f77829f2d853443642082b742e73 100644 (file)
@@ -34,6 +34,7 @@
 #include "runtime/JSStaticScopeObject.cpp"
 #include "runtime/JSFunction.cpp"
 #include "runtime/Arguments.cpp"
+#include "runtime/JSAPIValueWrapper.cpp"
 #include "runtime/JSGlobalObjectFunctions.cpp"
 #include "runtime/PrototypeFunction.cpp"
 #include "runtime/GlobalEvalFunction.cpp"
@@ -47,7 +48,7 @@
 #include "runtime/Collector.cpp"
 #include "runtime/CommonIdentifiers.cpp"
 #include "runtime/DateConstructor.cpp"
-#include "runtime/DateMath.cpp"
+#include "runtime/DateConversion.cpp"
 #include "runtime/DatePrototype.cpp"
 #include "runtime/DateInstance.cpp"
 #include "wtf/dtoa.cpp"
diff --git a/ChangeLog-2008-08-10 b/ChangeLog-2008-08-10
deleted file mode 100644 (file)
index 0912aec..0000000
+++ /dev/null
@@ -1,31482 +0,0 @@
-2008-08-10  Jan Michael Alonzo  <jmalonzo@webkit.org>
-
-        Reviewed (and updated) by Alp Toker.
-
-        https://bugs.webkit.org/show_bug.cgi?id=16620
-        [GTK] Autotools make dist and make check support
-
-        Get make dist working.
-
-        Note that not all possible configurations have been tested yet.
-
-        * GNUmakefile.am:
-
-2008-08-09  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Sam Weinig.
-
-        Added same heap debug checks to more code paths.
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::put):
-        (KJS::JSActivation::putWithAttributes):
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::putWithAttributes):
-        * kjs/JSObject.h:
-        (KJS::JSObject::putDirect):
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTablePut):
-        (KJS::JSVariableObject::symbolTablePutWithAttributes):
-
-2008-08-09  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Fix some style issues in the sampling tool.
-
-        * VM/SamplingTool.cpp:
-        (KJS::sleepForMicroseconds):
-        (KJS::SamplingTool::dump):
-
-2008-08-09  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Revision 35651, despite being a rather trivial change, introduced a
-        large regression on the regexp-dna SunSpider test. This regression
-        stemmed from an increase in the size of CodeBlock::dump(). There is
-        no reason for this method (and several related methods) to be compiled
-        in non-debug builds with the sampling tool disabled. This patch
-        conditionally compiles them, reversing the regression on SunSpider.
-
-        * JavaScriptCore.exp:
-        * VM/CodeBlock.cpp:
-        * VM/CodeBlock.h:
-        * VM/Machine.cpp:
-
-2008-08-08  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 20330: JSCore crash loading any filehurricane media page
-        <https://bugs.webkit.org/show_bug.cgi?id=20330>
-
-        Fix a typo in the constant loading patch. Also, add a case for
-        op_unexpected_load to CodeBlock::dump().
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addUnexpectedConstant):
-
-2008-08-08  Matt Lilek  <webkit@mattlilek.com>
-
-        Not reviewed, build fix.
-
-        * JavaScriptCore.exp:
-
-2008-08-08  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Cameron Zwarich.
-
-        Improve performance of arithmetic operators
-
-        Added a fast (non-virtual) mechanism to determine if a non-immediate JSValue*
-        is a JSNumberCell.  We then use this to allow improved specialisation in many
-        arithmetic operators.  SunSpider reports a 2.5% progression overall, with greater
-        than 10% progressions on a number of arithmetic heavy tests.
-
-        * VM/Machine.cpp:
-        (KJS::fastIsNumber):
-        (KJS::fastToInt32):
-        (KJS::fastToUInt32):
-        (KJS::jsLess):
-        (KJS::jsLessEq):
-        (KJS::jsAdd):
-        (KJS::Machine::privateExecute):
-        * kjs/JSNumberCell.h:
-        (KJS::JSNumberCell::fastToInt32):
-        (KJS::JSNumberCell::fastToUInt32):
-        * kjs/collector.cpp:
-        (KJS::allocateBlock):
-        (KJS::Heap::heapAllocate):
-        * kjs/collector.h:
-        (KJS::Heap::fastIsNumber):
-
-2008-08-06  Adam Roben  <aroben@apple.com>
-
-        Try to fix the Windows build bots
-
-        * API/JSBase.cpp: Touch this to force JSC to rebuild and re-copy the
-        WTF headers.
-
-2008-08-06  Tor Arne Vestbø  <tavestbo@trolltech.com>
-
-        Revert change 35595.
-
-        * wtf/RetainPtr.h:
-
-2008-08-06  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Fix non-Mac build.
-
-        * wtf/RetainPtr.h: CoreFoundation only for PLATFORM(MAC)
-
-2008-08-06  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Fix non-Mac build.
-
-        * wtf/RetainPtr.h: CoreFoundation only for PLATFORM(MAC)
-
-2008-08-06  Csaba Osztrogonac  <oszi@inf.u-szeged.hu>
-
-        Reviewed by Darin. Landed by Cameron.
-
-        Bug 20272: typo in JavaScriptCore
-        <https://bugs.webkit.org/show_bug.cgi?id=20272>
-
-        Correct the documentation for op_not. (typo)
-        Fix #undef. (typo)
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-08-06  Cameron Zwarich  <cwzwarich@webkit.org>
-
-        Reviewed by Maciej.
-
-        Bug 20286: Load constants all at once instead of using op_load
-        <https://bugs.webkit.org/show_bug.cgi?id=20286>
-
-        Load constants all at once into temporary registers instead of using
-        individual instances of op_load.
-
-        This is a 2.6% speedup on SunSpider.
-
-        * JavaScriptCore.exp:
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        (KJS::CodeBlock::mark):
-        * VM/CodeBlock.h:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::newTemporary):
-        (KJS::CodeGenerator::addConstant):
-        (KJS::CodeGenerator::addUnexpectedConstant):
-        (KJS::CodeGenerator::emitLoad):
-        (KJS::CodeGenerator::emitUnexpectedLoad):
-        (KJS::CodeGenerator::emitNewError):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::slideRegisterWindowForCall):
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::throwException):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        * VM/Opcode.h:
-        * VM/RegisterID.h:
-        (KJS::RegisterID::RegisterID):
-        (KJS::RegisterID::makeConstant):
-        (KJS::RegisterID::isTemporary):
-        * kjs/NodeInfo.h:
-        * kjs/Parser.cpp:
-        (KJS::Parser::didFinishParsing):
-        * kjs/Parser.h:
-        (KJS::Parser::parse):
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::NullNode::emitCode):
-        (KJS::BooleanNode::emitCode):
-        (KJS::NumberNode::emitCode):
-        (KJS::StringNode::emitCode):
-        (KJS::ArrayNode::emitCode):
-        (KJS::DeleteResolveNode::emitCode):
-        (KJS::DeleteValueNode::emitCode):
-        (KJS::VoidNode::emitCode):
-        (KJS::ConstDeclNode::emitCodeSingle):
-        (KJS::ReturnNode::emitCode):
-        (KJS::ScopeNode::ScopeNode):
-        (KJS::ProgramNode::ProgramNode):
-        (KJS::ProgramNode::create):
-        (KJS::EvalNode::EvalNode):
-        (KJS::EvalNode::create):
-        (KJS::FunctionBodyNode::FunctionBodyNode):
-        (KJS::FunctionBodyNode::create):
-        (KJS::FunctionBodyNode::emitCode):
-        * kjs/nodes.h:
-        (KJS::ScopeNode::neededConstants):
-
-2008-08-05  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Cameron.
-
-        - add fast path for immediates to % operator, as we have for many other math ops
-        
-        This fixes handling for a 0 divisor relative to the last patch. Only an 0.2% speedup on SunSpider but
-        still a 1.4x win on Oliver's prime test.
-        
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-08-05  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Darin.
-
-        Bug 20293: Crash in JavaScript codegen for eval("const a;")
-        <https://bugs.webkit.org/show_bug.cgi?id=20293>
-
-        Correctly handle constant declarations in eval code with no initializer.
-
-        * kjs/nodes.cpp:
-        (KJS::ConstDeclNode::emitCodeSingle):
-
-2008-08-05  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Roll out r35555 because of correctness issues.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-08-05  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - add fast path for immediates to % operator, as we have for many other math ops
-        
-        0.6% speedup on SunSpider. 1.4x speedup on a prime testing torture test that Oliver whipped up.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-07-31  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Cameron Zwarich.
-
-        Bug 19359: JavaScriptCore behaves differently from FF2/3 and IE when handling context in catch statement
-        <https://bugs.webkit.org/show_bug.cgi?id=19359>
-
-        Make our catch behave like Firefox and IE, we do this by using a StaticScopeObject
-        instead of a generic JSObject for the scope node.  We still don't make use of the
-        fact that we have a static scope inside the catch block, so the internal performance
-        of the catch block is not improved, even though technically it would be possible to
-        do so.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitPushNewScope):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::createExceptionScope):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        * VM/Opcode.h:
-        * kjs/JSStaticScopeObject.cpp:
-        (KJS::JSStaticScopeObject::toThisObject):
-        (KJS::JSStaticScopeObject::put):
-        * kjs/JSStaticScopeObject.h:
-        * kjs/nodes.cpp:
-        (KJS::TryNode::emitCode):
-
-2008-08-02  Rob Gowin  <robg@gowin.net>
-
-        Reviewed by Eric Seidel.
-
-        Added JavaScriptCore/API/WebKitAvailability to list of files in
-        javascriptcore_h_api.
-
-        * GNUmakefile.am:
-
-2008-08-01  Alexey Proskuryakov  <ap@webkit.org>
-
-        Rubber-stamped by Maciej.
-
-        Remove JSGlobalData::DataInstance. It was only needed when we had per-thread JSGlobalData
-        instances.
-
-        * kjs/JSGlobalData.h:
-
-2008-07-31  Kevin Ollivier <kevino@theolliviers.com>
-
-        Second attempt at Windows/wx build fix. Instead of avoiding inclusion of windows.h,
-        use defines, etc. to avoid conflicts in each affected file. Also, change PLATFORM(WIN)
-        to PLATFORM(WIN_OS) so that other ports using Windows headers get the right impls.
-
-        * VM/SamplingTool.cpp:
-        * wtf/Threading.h:
-
-2008-07-31  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Adam.
-
-        Fix Windows build.
-        
-        * kjs/collector.h:
-        * wtf/FastMalloc.cpp:
-
-2008-07-31  Csaba Osztrogonac  <oszi@inf.u-szeged.hu>
-
-        Reviewed by Simon.
-
-        Bug 20170: [Qt] missing namespace defines in JavaScriptCore.pro
-        <https://bugs.webkit.org/show_bug.cgi?id=20170>
-
-        * JavaScriptCore.pro: Added missing define.
-
-2008-07-31  Alexey Proskuryakov  <ap@webkit.org>
-
-        Rubber-stamped by Maciej.
-
-        Eliminate JSLock (it was already disabled, removing the stub implementaion and all
-        call sites now).
-
-        * API/JSBase.cpp:
-        (JSEvaluateScript):
-        (JSCheckScriptSyntax):
-        (JSGarbageCollect):
-        * API/JSCallbackConstructor.cpp:
-        (KJS::constructJSCallback):
-        * API/JSCallbackFunction.cpp:
-        (KJS::JSCallbackFunction::call):
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::init):
-        (KJS::::getOwnPropertySlot):
-        (KJS::::put):
-        (KJS::::deleteProperty):
-        (KJS::::construct):
-        (KJS::::hasInstance):
-        (KJS::::call):
-        (KJS::::getPropertyNames):
-        (KJS::::toNumber):
-        (KJS::::toString):
-        (KJS::::staticValueGetter):
-        (KJS::::callbackGetter):
-        * API/JSContextRef.cpp:
-        (JSGlobalContextCreateInGroup):
-        (JSGlobalContextRetain):
-        (JSGlobalContextRelease):
-        * API/JSObjectRef.cpp:
-        (JSObjectMake):
-        (JSObjectMakeFunctionWithCallback):
-        (JSObjectMakeConstructor):
-        (JSObjectMakeFunction):
-        (JSObjectHasProperty):
-        (JSObjectGetProperty):
-        (JSObjectSetProperty):
-        (JSObjectGetPropertyAtIndex):
-        (JSObjectSetPropertyAtIndex):
-        (JSObjectDeleteProperty):
-        (JSObjectCallAsFunction):
-        (JSObjectCallAsConstructor):
-        (JSObjectCopyPropertyNames):
-        (JSPropertyNameArrayRelease):
-        (JSPropertyNameAccumulatorAddName):
-        * API/JSStringRef.cpp:
-        (JSStringRelease):
-        * API/JSValueRef.cpp:
-        (JSValueIsEqual):
-        (JSValueIsInstanceOfConstructor):
-        (JSValueMakeNumber):
-        (JSValueMakeString):
-        (JSValueToNumber):
-        (JSValueToStringCopy):
-        (JSValueToObject):
-        (JSValueProtect):
-        (JSValueUnprotect):
-        * ForwardingHeaders/JavaScriptCore/JSLock.h: Removed.
-        * GNUmakefile.am:
-        * JavaScriptCore.exp:
-        * JavaScriptCore.order:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * kjs/AllInOneFile.cpp:
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        * kjs/JSGlobalData.h:
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::~JSGlobalObject):
-        (KJS::JSGlobalObject::init):
-        * kjs/JSLock.cpp: Removed.
-        * kjs/JSLock.h: Removed.
-        * kjs/Shell.cpp:
-        (functionGC):
-        (jscmain):
-        * kjs/collector.cpp:
-        (KJS::Heap::~Heap):
-        (KJS::Heap::heapAllocate):
-        (KJS::Heap::setGCProtectNeedsLocking):
-        (KJS::Heap::protect):
-        (KJS::Heap::unprotect):
-        (KJS::Heap::collect):
-        * kjs/identifier.cpp:
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::checkSyntax):
-        (KJS::Interpreter::evaluate):
-
-2008-07-31  Alexey Proskuryakov  <ap@webkit.org>
-
-        Rubber-stamped by Oliver Hunt.
-
-        Fix the Mac project to not display "test/" as part of file name for tests.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-07-31  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Alexey Proskuryakov.
-        
-        Rename USE(MULTIPLE_THREADS) to ENABLE(JSC_MULTIPLE_THREADS)
-        to better match the use/enable pattern (and better describe
-        the usage of the feature in question.)
-        
-        I also fixed a couple other ENABLE_ macros to be pre-processor
-        definition override-able to match the rest of the ENABLE_ macros
-        since it seems to be our convention that build systems can set
-        ENABLE_ macros in Makefiles.
-
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreadingOnce):
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        (KJS::JSGlobalData::~JSGlobalData):
-        * kjs/MathObject.cpp:
-        * kjs/collector.cpp:
-        (KJS::Heap::Heap):
-        (KJS::Heap::~Heap):
-        (KJS::allocateBlock):
-        (KJS::Heap::markStackObjectsConservatively):
-        * kjs/collector.h:
-        * kjs/dtoa.cpp:
-        (KJS::pow5mult):
-        (KJS::rv_alloc):
-        (KJS::freedtoa):
-        (KJS::dtoa):
-        * wtf/FastMalloc.cpp:
-        * wtf/Platform.h:
-        * wtf/RefCountedLeakCounter.cpp:
-
-2008-07-30  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Mark Rowe.
-        
-        Try to clean up our usage of USE(MULTIPLE_THREADS) vs. USE(PTHREADS) a little.
-        It looks like JSC assumes that if MULTIPLE_THREADS is defined, then pthreads will always be available
-        I'm not sure that's always the case for gtk, certainly not for Windows.  We should eventually go back
-        and fix wtf/Threading.h to cover all these cases some day.
-
-        * kjs/JSLock.cpp:
-        * kjs/collector.h:
-        * wtf/Platform.h:
-
-2008-07-30  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Oliver.
-        
-        MSVC warns when structs are called classes or vice versa.
-        Make all the source refer to JSGlobalData as a class.
-
-        * kjs/CommonIdentifiers.h:
-        * kjs/JSGlobalData.h:
-        * kjs/Parser.h:
-        * kjs/lexer.h:
-
-2008-07-30  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff Garen.
-
-        Add consistency checks to UString to document and enforce its design.
-
-        * kjs/ustring.cpp:
-        (KJS::UString::Rep::create):
-        (KJS::UString::Rep::destroy):
-        (KJS::UString::Rep::checkConsistency):
-        (KJS::UString::expandCapacity):
-        (KJS::UString::expandPreCapacity):
-        (KJS::UString::UString):
-        (KJS::UString::spliceSubstringsWithSeparators):
-        (KJS::UString::append):
-        * kjs/ustring.h:
-        (KJS::UString::Rep::checkConsistency):
-
-2008-07-30  Gavin Barraclough  <barraclough@apple.com>
-
-        Reviewed by Geoff Garen.
-
-        Fixes for Windows and non-AllInOne file build with SamplingTool, plus review fixes.
-
-        * GNUmakefile.am:              Adding SamplingTool.cpp to build.
-        * JavaScriptCore.exp:          Export hooks to init & control SamplingTool.
-        * JavaScriptCore.pri:          Adding SamplingTool.cpp to build.
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Adding SamplingTool.cpp to build.
-        * JavaScriptCore.xcodeproj/project.pbxproj: Adding SamplingTool.cpp to build.
-        * JavaScriptCoreSources.bkl:   Adding SamplingTool.cpp to build.
-        * VM/Machine.cpp:              MACHINE_SAMPLING_callingNativeFunction renamed MACHINE_SAMPLING_callingHostFunction
-        * VM/Machine.h:
-        * VM/Opcode.cpp:               SamplingTool moved to SamplingTool.cpp/.h, opcodeNames generated from FOR_EACH_OPCODE_ID.
-        * VM/Opcode.h:
-        * VM/SamplingTool.cpp:         Added .cpp/.h for SamplingTool.
-        * VM/SamplingTool.h:
-        * kjs/Shell.cpp:               Switched SAMPLING_TOOL_ENABLED to ENABLE_SAMPLING_TOOL.
-        * wtf/Platform.h:              Added ENABLE_SAMPLING_TOOL config option.
-        * kjs/nodes.cpp:               Header include to fix non-AllInOne builds.
-
-2008-07-30  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Reviewed by Alexey Proskuryakov.
-
-        Fix compilation without multi-threading support.
-
-        * kjs/collector.cpp:
-        (KJS::Heap::Heap):
-
-2008-07-30  Anders Carlsson  <andersca@apple.com>
-        
-        Add WebKitAvailability.h forwarding header.
-        
-        * ForwardingHeaders/JavaScriptCore/WebKitAvailability.h: Added.
-
-2008-07-30  Anders Carlsson  <andersca@apple.com>
-
-        Fix the else.
-        
-        * API/WebKitAvailability.h:
-
-2008-07-30  Anders Carlsson  <andersca@apple.com>
-
-        * API/WebKitAvailability.h:
-        Fix Windows (and other non-Mac builds).
-        
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        Add WebKitAvailability.h to the project.
-
-2008-07-30  Anders Carlsson  <andersca@apple.com>
-
-        One step closer towards fixing the Windows build.
-        
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
-        Make sure to copy WebKitAvailability.h
-
-2008-07-29  Gavin Barraclough  <barraclough@apple.com>
-
-        Reviewed by Geoff Garen.
-
-        Bug 20209: Atomize constant strings
-        <https://bugs.webkit.org/show_bug.cgi?id=20209>
-
-        Prevents significant performance degradation seen when a script contains multiple
-        identical strings that are used as keys to identify properties on objects.
-
-        No performance change on SunSpider.
-
-        * kjs/nodes.cpp: Atomize constant strings.
-
-2008-07-30  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Alexey Proskuryakov.
-
-        <rdar://problem/6111648> JavaScript exceptions fail if the scope chain includes the global object
-
-        In an attempt to remove the branch I just added to KJS::depth I
-        used the existence of a Variable Object at a point in the scope
-        chain as an indicator of function or global scope activation.
-        However this assumption results in incorrect behaviour if the
-        global object is injected into the scope chain with 'with'.
-
-        * VM/Machine.cpp:
-        (KJS::depth):
-
-2008-07-30  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff Garen.
-
-        Don't call JSGarbageCollect() on a released context.
-
-        * API/testapi.c: (main):
-
-2008-07-29  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff Garen.
-
-        Implement JSContextGroup APIs to make concurrent execution possible for
-        JavaScriptCore clients.
-
-        This changes the behavior of JSGlobalContextCreate(), so that it now uses a private context
-        group for each context, making JSlock implicit locking unnecessary.
-
-        * API/JSContextRef.h:
-        * API/JSContextRef.cpp:
-        (JSContextGroupCreate):
-        (JSContextGroupRetain):
-        (JSContextGroupRelease):
-        (JSGlobalContextCreate):
-        (JSGlobalContextCreateInGroup):
-        (JSGlobalContextRelease):
-        (JSContextGetGroup):
-        Added new methods. JSGlobalContextCreate() calls JSGlobalContextCreateInGroup() now.
-
-        * API/APICast.h: (toJS): (toRef): Added converters for JSContextGroupRef.
-        * API/JSBase.cpp: (JSGarbageCollect): JSGarbageCollect(0) is now a no-op, and the passed in
-        context is actually used.
-
-        * API/JSBase.h: Aded a typedef for JSContextGroupRef. Updated documentation for
-        JSGarbageCollect().
-
-        * JavaScriptCore.exp: Removed JSGlobalData::sharedInstance().
-
-        * kjs/JSGlobalData.cpp:
-        * kjs/JSGlobalData.h:
-        Removed support for JSGlobalData shared instance. JSGlobalData::isSharedInstance member
-        variable still remains, to be deleted in a followup patch.
-
-        * kjs/JSLock.cpp: (KJS::JSLock::JSLock): Disabled JSLock, to be deleted in a follow-up patch.
-        
-        * kjs/collector.cpp:
-        (KJS::Heap::markOtherThreadConservatively): Removed an assertion that referenced
-        JSGlobalData::sharedInstance.
-
-        * kjs/collector.h: Made Heap destructor public, so that JSContextRelease can use it.
-
-2008-07-29  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff Garen.
-
-        Fix a leak of ThreadRegistrar objects.
-
-        As the heap is usually deleted when registered threads still exist, ThreadSpecific doesn't
-        have a chance to clean up per-thread object. Switched to native pthread calls, storing a
-        plain pointer that doesn't require cleanup.
-
-        * kjs/collector.cpp:
-        (KJS::PlatformThread::PlatformThread):
-        (KJS::Heap::Thread::Thread):
-        (KJS::Heap::Heap):
-        (KJS::Heap::~Heap):
-        (KJS::Heap::registerThread):
-        (KJS::Heap::unregisterThread):
-        * kjs/collector.h:
-
-2008-07-29  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Sam Weinig.
-
-        https://bugs.webkit.org/show_bug.cgi?id=20169
-        Memory allocated with fastMalloc is freed with delete
-
-        * VM/JSPropertyNameIterator.cpp:
-        (KJS::JSPropertyNameIterator::invalidate): Free the array properly.
-        (KJS::JSPropertyNameIterator::~JSPropertyNameIterator): Delete the array by calling
-        invalidate().
-
-2008-07-29  Mark Rowe  <mrowe@apple.com>
-
-        Attempt to fix the Qt build.
-
-        * wtf/ThreadingQt.cpp: Add the extra argument to createThread.
-
-2008-07-29  Adam Roben  <aroben@apple.com>
-
-        Change Vector::find to return an index instead of an iterator
-
-        Indices are more natural than iterators when working with Vector.
-
-        Reviewed by John Sullivan.
-
-        * wtf/Vector.h:
-        (WTF::Vector::find): Changed to iterate the Vector manually and return
-        the index of the found item, rather than an iterator. When the item
-        could not be found, we return WTF::notFound.
-
-2008-07-29  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * wtf/ThreadingWin.cpp:
-        (WTF::setThreadName): Move a misplaced assertion to here...
-        (WTF::createThread): ...from here.
-
-2008-07-29  Adam Roben  <aroben@apple.com>
-
-        Add support for setting thread names on Windows
-
-        These thread names make it much easier to identify particular threads
-        in Visual Studio's Threads panel.
-
-        WTF::createThread now takes a const char* representing the thread's
-        name. On Windows, we throw a special exception to set this string as
-        the thread's name. Other platforms do nothing with this name for now.
-
-        Reviewed by Anders Carlsson.
-
-        * JavaScriptCore.exp: Export the new version of createThread that
-        takes 3 arguments (the old one continues to be exported for backward
-        compatibility).
-        * wtf/Threading.h: Add a threadName argument to createThread.
-
-        * wtf/ThreadingGtk.cpp:
-        (WTF::createThread):
-        * wtf/ThreadingNone.cpp:
-        (WTF::createThread):
-        Updated for function signature change.
-
-        * wtf/ThreadingPthreads.cpp:
-        (WTF::createThread): Updated for function signature change. We keep
-        around the old 2-argument version of createThread for backward
-        compatibility.
-
-        * wtf/ThreadingWin.cpp:
-        (WTF::setThreadName): Added. This function's implementation came from
-        MSDN.
-        (WTF::initializeThreading): Set the name of the main thread.
-        (WTF::createThread): Call setThreadName. We keep around the old
-        2-argument version of createThread for backward compatibility.
-
-2008-07-29  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Store UString::Rep::isStatic bit in identifierTable pointer instead of reportedCost for
-        slightly nicer code and a 0.5% SunSpider improvement.
-
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::~OpaqueJSClass):
-        (OpaqueJSClassContextData::OpaqueJSClassContextData):
-        * API/JSStringRef.cpp:
-        (JSStringRelease):
-        * kjs/PropertyNameArray.cpp:
-        (KJS::PropertyNameArray::add):
-        * kjs/identifier.cpp:
-        (KJS::IdentifierTable::~IdentifierTable):
-        (KJS::IdentifierTable::add):
-        (KJS::Identifier::addSlowCase):
-        (KJS::Identifier::remove):
-        * kjs/identifier.h:
-        (KJS::Identifier::add):
-        * kjs/ustring.cpp:
-        (KJS::):
-        (KJS::UString::Rep::create):
-        (KJS::UString::Rep::destroy):
-        * kjs/ustring.h:
-        (KJS::UString::Rep::identifierTable):
-        (KJS::UString::Rep::setIdentifierTable):
-        (KJS::UString::Rep::isStatic):
-        (KJS::UString::Rep::setStatic):
-        (KJS::UString::cost):
-
-2008-07-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Renamed "ConstructTypeNative" => "ConstructTypeHost".
-        
-2008-07-26  Mark Rowe  <mrowe@apple.com>
-
-        Speculative fix for the wx build.
-
-        * JavaScriptCoreSources.bkl:  Add JSStaticScopeObject.cpp to the list of source files.
-
-2008-07-25  Oliver Hunt  <oliver@apple.com>
-
-        RS=Cameron Zwarich.
-
-        Whoops, forgot to save style correction.
-
-        * kjs/JSStaticScopeObject.h:
-
-2008-07-25  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Cameron Zwarich.
-
-        Bug 19718: Named anonymous functions are slow accessing global variables
-        <https://bugs.webkit.org/show_bug.cgi?id=19718>
-
-        To fix this we switch over to an activation-like scope object for
-        on which we attach the function name property, and add logic to 
-        prevent cross scope assignment to read only properties.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::findScopedProperty):
-        (KJS::CodeGenerator::emitResolve):
-        * VM/CodeGenerator.h:
-        * kjs/AllInOneFile.cpp:
-        * kjs/JSStaticScopeObject.cpp: Added.
-        (KJS::JSStaticScopeObject::putWithAttributes):
-        (KJS::JSStaticScopeObject::isDynamicScope):
-        (KJS::JSStaticScopeObject::~JSStaticScopeObject):
-        (KJS::JSStaticScopeObject::getOwnPropertySlot):
-        * kjs/JSStaticScopeObject.h: Added.
-        (KJS::JSStaticScopeObject::JSStaticScopeObjectData::JSStaticScopeObjectData):
-        (KJS::JSStaticScopeObject::JSStaticScopeObject):
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallResolveNode::emitCode):
-        (KJS::PostfixResolveNode::emitCode):
-        (KJS::PrefixResolveNode::emitCode):
-        (KJS::ReadModifyResolveNode::emitCode):
-        (KJS::AssignResolveNode::emitCode):
-        (KJS::FuncExprNode::makeFunction):
-
-2008-07-25  kevino  <kevino@theolliviers.com>
-
-        wx build fix for Win.
-        
-        On wx/Win, including windows.h in Threading.h causes multiply-defined symbol errors
-        for libjpeg and wx, and also wx needs to include windows.h itself first for wx
-        includes to work right. So until we can find a better solution to this problem,
-        on wx, we work around the need to include windows.h here.
-
-        * wtf/Threading.h:
-
-2008-07-25  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * JavaScriptCore.vcproj/testapi/testapi.vcproj: Add API/ to the
-        include path.
-
-2008-07-25  Simon Hausmann  <hausmann@webkit.org>
-
-        Fix the build of jsc on Qt/Windows, make sure os-win32 is in the
-        include search path (added by WebKit.pri).
-
-        * kjs/jsc.pro:
-
-2008-07-25  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Simon Hausmann.
-
-        Move JavaScriptCore API tests into a subdirectory of their own to avoid header name
-        conflicts and developer confusion.
-
-        * API/JSNode.c: Removed.
-        * API/JSNode.h: Removed.
-        * API/JSNodeList.c: Removed.
-        * API/JSNodeList.h: Removed.
-        * API/Node.c: Removed.
-        * API/Node.h: Removed.
-        * API/NodeList.c: Removed.
-        * API/NodeList.h: Removed.
-        * API/minidom.c: Removed.
-        * API/minidom.html: Removed.
-        * API/minidom.js: Removed.
-        * API/testapi.c: Removed.
-        * API/testapi.js: Removed.
-        * API/tests: Added.
-        * API/tests/JSNode.c: Copied from JavaScriptCore/API/JSNode.c.
-        * API/tests/JSNode.h: Copied from JavaScriptCore/API/JSNode.h.
-        * API/tests/JSNodeList.c: Copied from JavaScriptCore/API/JSNodeList.c.
-        * API/tests/JSNodeList.h: Copied from JavaScriptCore/API/JSNodeList.h.
-        * API/tests/Node.c: Copied from JavaScriptCore/API/Node.c.
-        * API/tests/Node.h: Copied from JavaScriptCore/API/Node.h.
-        * API/tests/NodeList.c: Copied from JavaScriptCore/API/NodeList.c.
-        * API/tests/NodeList.h: Copied from JavaScriptCore/API/NodeList.h.
-        * API/tests/minidom.c: Copied from JavaScriptCore/API/minidom.c.
-        * API/tests/minidom.html: Copied from JavaScriptCore/API/minidom.html.
-        * API/tests/minidom.js: Copied from JavaScriptCore/API/minidom.js.
-        * API/tests/testapi.c: Copied from JavaScriptCore/API/testapi.c.
-        * API/tests/testapi.js: Copied from JavaScriptCore/API/testapi.js.
-        * GNUmakefile.am:
-        * JavaScriptCore.vcproj/testapi/testapi.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-07-25  Simon Hausmann  <hausmann@webkit.org>
-
-        Prospective WX build fix, add JavaScriptCore/API to the include search
-        path.
-
-        * jscore.bkl:
-
-2008-07-25  Simon Hausmann  <hausmann@webkit.org>
-
-        Rubber-stamped by Lars.
-
-        Fix the build on Windows. operator new for ArgList is implemented using fastMalloc()
-        but operator delete was not implemented. Unfortunately MSVC decides to call/reference
-        the function, so a simple implementation using fastFree() fixes the build.
-
-        * kjs/ArgList.h:
-        (KJS::ArgList::operator delete):
-
-2008-07-25  Simon Hausmann  <hausmann@webkit.org>
-
-        Discussed with and rubber-stamped by Lars.
-
-        Fix the build system for the Qt port.
-
-        Recent JavaScriptCore changes require the addition of JavaScriptCore/API to the
-        include search path. With a build process that combines JavaScriptCore and
-        WebCore in one build process/Makefile the existance of
-        JavaScriptCore/API/Node.h and WebCore/dom/Node.h causes include conflicts.
-
-        This commit solves this by introducing a separate build of JavaScriptCore into
-        a static library.
-
-        As a result of the split-up a race-condition due to broken dependencies of
-        regular source files to header files of generated sources showed up very
-        frequently when doing parallel builds (which the buildbot does). This commit at
-        the same time tries to address the dependency problem by making the
-        addExtraCompiler() function also generate a pseudo extra compiler that
-        represents the header file output, so that qmake is aware of the creation of
-        the header file for dependency calculation.
-
-        At the same time I removed a lot of cruft from the pro files to ease maintenance.
-
-        * JavaScriptCore.pri:
-        * JavaScriptCore.pro: Added.
-        * kjs/jsc.pro:
-
-2008-07-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed a strict aliasing violation, which caused hash tables with floating
-        point keys not to find items that were indeed in the tables
-        (intermittently, and only in release builds, of course).
-        
-        SunSpider reports no change.
-        
-        This bug doesn't seem to affect any existing code, but it causes obvious
-        crashes in some new code I'm working on.
-
-        * wtf/HashFunctions.h:
-        (WTF::FloatHash::hash): Use a union when punning between a float / double
-        and an unsigned (bucket of bits). With strict aliasing enabled, unions
-        are the only safe way to do this kind of type punning.
-
-        * wtf/HashTable.h: When rehashing, ASSERT that the item we just added to
-        the table is indeed in the table. In the buggy case described above, this
-        ASSERT fires.
-
-2008-07-24  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Alexey Proskuryakov.
-
-        Bug 20142: REGRESSION(r35245): /=/ weirdness
-        <https://bugs.webkit.org/show_bug.cgi?id=20142>
-
-        When adding all the meta data needed for exception error messages
-        I accidentally clobbered the handling of regex beginning with /=.
-
-        * kjs/grammar.y:
-
-2008-07-23  Alp Toker  <alp@nuanti.com>
-
-        Build fix after r35293: Add API/ to the include path.
-
-        * GNUmakefile.am:
-
-2008-07-23  Adam Roben  <aroben@apple.com>
-
-        Windows build fixes
-
-        Build fix after r35293:
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add API/
-        to the include path.
-
-        Build fix after r35305:
-
-        * VM/Machine.cpp:
-        * VM/Machine.h:
-        * VM/Opcode.cpp:
-        * VM/Opcode.h:
-        Completely compile out all sampler-related code when
-        SAMPLING_TOOL_ENABLED is 0. The sampler code can't be compiled 1) on
-        non-AllInOne configurations due to circular header dependencies, and
-        2) on platforms that don't have a usleep() function, such as Windows.
-
-2008-07-23  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff Garen and Sam Weinig.
-
-        Improve switch performance.
-
-        Improve switch performance by converting to a hashmap based jump
-        table to avoid the sequence of dispatches that would otherwise be
-        needed.  This results in a 9-19x performance win for string switches
-        based on ad hoc testing, and a 6x improvement for integer switch
-        statements.  SunSpider reports a 1.2% progression.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        (KJS::SimpleJumpTable::offsetForValue):
-        * VM/CodeBlock.h:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::beginSwitch):
-        (KJS::prepareJumpTableForImmediateSwitch):
-        (KJS::prepareJumpTableForCharacterSwitch):
-        (KJS::prepareJumpTableForStringSwitch):
-        (KJS::CodeGenerator::endSwitch):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::offsetForStringSwitch):
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.cpp:
-        (KJS::):
-        * VM/Opcode.h:
-        * kjs/JSImmediate.h:
-        * kjs/nodes.cpp:
-        (KJS::):
-        (KJS::processClauseList):
-        (KJS::CaseBlockNode::tryOptimisedSwitch):
-        (KJS::CaseBlockNode::emitCodeForBlock):
-        * kjs/nodes.h:
-        (KJS::SwitchInfo::):
-
-2008-07-23  Gavin Barraclough  <barraclough@apple.com>
-
-        Reviewed by Geoff Garen.
-
-        Sampling tool to analyze cost of instruction execution and identify hot regions of JS code.
-        Enable Switches by setting SAMPLING_TOOL_ENABLED in Opcode.h.
-
-        * JavaScriptCore.exp: Export symbols for Shell.cpp.
-        * VM/Machine.cpp:     Added sampling hooks.
-        * VM/Machine.h:       Machine contains a pointer to a sampler, when sampling.
-        * VM/Opcode.cpp:      Tool implementation.
-        * VM/Opcode.h:        Tool declaration.
-        * kjs/Shell.cpp:      Initialize the sampler, if enabled.
-        * kjs/nodes.cpp:      Added sampling hooks.
-
-2008-07-23  Gabor Loki  <loki@inf.u-szeged.hu>
-
-        Bug 20097: [Qt] 20% Sunspider slow-down
-
-        <https://bugs.webkit.org/show_bug.cgi?id=20097>
-
-        Reviewed by Simon Hausmann.
-
-        * kjs/jsc.pro: Added missing NDEBUG define for release builds.
-
-2008-07-23  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff Garen.
-
-        JSClassRef is created context-free, but gets infatuated with the first context it sees.
-
-        The implicit API contract is that JSClassRef can be used with any context on any thread.
-        This no longer worked, because UStrings in the class were turned into per-context
-        identifiers, and the cached JSObject prototype was tied to JSGlobalData, too.
-
-        * API/JSClassRef.h: Made a separate struct for context-dependent parts of OpaqueJSClass.
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::OpaqueJSClass): Updated for renames and changed member variable order.
-        (OpaqueJSClass::~OpaqueJSClass): Assert that string members are not identifiers.
-        (clearReferenceToPrototype): Update for the new reference location.
-        (OpaqueJSClassContextData::OpaqueJSClassContextData): Make a deep copy of all strings.
-        (OpaqueJSClass::contextData): Added a function that finds the per-context part of
-        OpaqueJSClass in JSGlobalData, or creates it if not found.
-        (OpaqueJSClass::className): Always make a deep copy. Callers of this function do not have
-        a way to access JSGlobalData, so a per-context copy could not be made.
-        (OpaqueJSClass::staticValues): Updated for new data location.
-        (OpaqueJSClass::staticFunctions): Ditto.
-        (OpaqueJSClass::prototype): Changed to take an internal type for consistency.
-
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        (KJS::JSGlobalData::~JSGlobalData):
-        * kjs/JSGlobalData.h:
-        Keep a HashMap to access per-context JSClass data given a pointr to the shared part.
-
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::className):
-        (KJS::::getOwnPropertySlot):
-        (KJS::::put):
-        (KJS::::deleteProperty):
-        (KJS::::getPropertyNames):
-        (KJS::::staticValueGetter):
-        (KJS::::staticFunctionGetter):j
-        Use function accessors instead of accessing OpaqueJSClass members directly.
-
-        * API/JSContextRef.cpp: (JSGlobalContextCreate): Updated for the change in
-        OpaqueJSClass::prototype() argument type.
-
-        * API/JSObjectRef.cpp:
-        (JSObjectMake): Updated for the change in OpaqueJSClass::prototype() argument type.
-        (JSObjectMakeConstructor): Ditto.
-
-2008-07-23  Alexey Proskuryakov  <ap@webkit.org>
-
-        Build fix.
-
-        * kjs/ArgList.h: (KJS::ArgList::operator new): removed an extraneous "ArgList::" inside the
-        class definition.
-
-2008-07-22  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt and Sam Weinig.
-
-        Next step toward putting doubles in registers: Prepare the Register class
-        and its clients for registers that don't contain JSValue*s.
-        
-        This means a few things:
-        
-        1. Register::jsValue() clients, including ArgList clients, must now supply
-        an ExecState* when accessing an entry in an ArgList, in case the entry
-        will need to create a JSValue* on the fly.
-        
-        2. Register clients that definitely don't want to create a JSValue* on
-        the fly now use different APIs: getJSValue() for clients that know
-        the register contains a JSValue*, and v() for clients who just want a
-        void*.
-        
-        3. I had to change some headers around in order to resolve dependency
-        problems created by using a Register in the ArgList header.
-        
-        SunSpider reports no change.
-        
-2008-07-22  Gavin Barraclough  <barraclough@apple.com>
-
-        Reviewed by Alexey Proskuryakov.
-
-        Prevent integer overflow when reallocating storage vector for arrays.
-
-        Sunspider reports 1.005x as fast (no change expected).
-
-        * kjs/JSArray.cpp:
-
-2008-07-21  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        <rdar://problem/6091287> Revamp the handling of CFBundleShortVersionString to be fixed at the major component of the version number.
-
-        * Configurations/Version.xcconfig:
-        * Info.plist:
-
-2008-07-21  Adam Roben  <aroben@apple.com>
-
-        Add Vector::find
-
-        This is a convenience wrapper around std::find.
-
-        Reviewed by Anders Carlsson.
-
-        * wtf/Vector.h:
-
-2008-07-19  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Cameron Zwarich.
-
-        Bug 20104: Exception in tables/mozilla_expected_failures/bugs/bug92868_1.html includes the equals operator in the quoted expression
-        <https://bugs.webkit.org/show_bug.cgi?id=20104>
-
-        To make this correct we make the dot and bracket assign nodes emit the information to indicate
-        the failure range is the dot/bracket accessor.
-
-        * kjs/grammar.y:
-
-2008-07-18  Steve Falkenburg  <sfalken@apple.com>
-
-        Windows build fix.
-
-        * kjs/JSGlobalObjectFunctions.cpp:
-        (KJS::isStrWhiteSpace):
-
-2008-07-18  Steve Falkenburg  <sfalken@apple.com>
-
-        Windows build fix.
-
-        * kjs/nodes.h:
-        (KJS::ThrowableExpressionData::ThrowableExpressionData):
-
-2008-07-18  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Cameron Zwarich.
-
-        Bug 18774: SQUIRRELFISH: print meaningful error messages <https://bugs.webkit.org/show_bug.cgi?id=18774>
-        <rdar://problem/5769353> SQUIRRELFISH: JavaScript error messages are missing informative text
-
-        Add support for decent error messages in JavaScript.  This patch achieves this by providing
-        ensuring the common errors and exceptions have messages that provide the text of expression
-        that trigger the exception.  In addition it attaches a number of properties to the exception
-        object detailing where in the source the expression came from.
-
-        * JavaScriptCore.exp:
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::lineNumberForVPC):
-        (KJS::CodeBlock::expressionRangeForVPC): 
-            Function to recover the expression range for an instruction
-            that triggered an exception.
-        * VM/CodeBlock.h:
-        (KJS::ExpressionRangeInfo::):
-        (KJS::CodeBlock::CodeBlock):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitCall):
-        (KJS::CodeGenerator::emitCallEval):
-            Emit call needed to be modified so to place the expression range info internally,
-            as the CodeGenerator emits the arguments nodes itself, rather than the various call
-            nodes.
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::emitExpressionInfo):
-            Record the expression range info.
-        * VM/ExceptionHelpers.cpp:
-        (KJS::createErrorMessage):
-        (KJS::createInvalidParamError):
-        (KJS::createUndefinedVariableError):
-        (KJS::createNotAConstructorError):
-        (KJS::createNotAFunctionError):
-        (KJS::createNotAnObjectErrorStub):
-        (KJS::createNotAnObjectError):
-            Rewrite all the code for the error messages so that they make use of the newly available
-            information.
-        * VM/ExceptionHelpers.h:
-        * VM/Machine.cpp:
-        (KJS::isNotObject):  Now needs vPC and codeBlock
-        (KJS::Machine::throwException):
-            New logic to handle the NotAnObjectErrorStub and to handle the absurd "no default value" edge case
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        * kjs/DebuggerCallFrame.cpp:
-        (KJS::DebuggerCallFrame::evaluate):
-        * kjs/Error.cpp:
-        (KJS::Error::create):
-        * kjs/Error.h:
-        * kjs/JSGlobalObjectFunctions.cpp:
-        * kjs/JSImmediate.cpp:
-        (KJS::JSImmediate::toObject):
-        (KJS::JSImmediate::prototype):
-            My changes to the JSNotAnObject constructor needed to be handled here.
-        * kjs/JSNotAnObject.h:
-        (KJS::JSNotAnObjectErrorStub::JSNotAnObjectErrorStub):
-        (KJS::JSNotAnObjectErrorStub::isNull):
-        (KJS::JSNotAnObjectErrorStub::isNotAnObjectErrorStub):
-            Added a JSNotAnObjectErrorStub class to ease the handling of toObject failure exceptions,
-            and potentially allow even more detailed error messages in future.
-        * kjs/JSObject.h:
-        * kjs/Parser.h:
-        (KJS::Parser::parse):
-        * kjs/SourceRange.h:
-        * kjs/grammar.y:
-            Large amounts of position propagation.
-        * kjs/lexer.cpp:
-        (KJS::Lexer::Lexer):
-        (KJS::Lexer::shift):
-        (KJS::Lexer::lex):
-            The lexer needed a few changes to be able to correctly track token character positions.
-        * kjs/lexer.h:
-        * kjs/nodes.cpp:
-        (KJS::ThrowableExpressionData::emitThrowError):
-        (KJS::StatementNode::StatementNode):
-        (KJS::ResolveNode::emitCode):
-        (KJS::BracketAccessorNode::emitCode):
-        (KJS::DotAccessorNode::emitCode):
-        (KJS::NewExprNode::emitCode):
-        (KJS::EvalFunctionCallNode::emitCode):
-        (KJS::FunctionCallValueNode::emitCode):
-        (KJS::FunctionCallResolveNode::emitCode):
-        (KJS::FunctionCallBracketNode::emitCode):
-        (KJS::FunctionCallDotNode::emitCode):
-        (KJS::PostfixResolveNode::emitCode):
-        (KJS::PostfixBracketNode::emitCode):
-        (KJS::PostfixDotNode::emitCode):
-        (KJS::DeleteResolveNode::emitCode):
-        (KJS::DeleteBracketNode::emitCode):
-        (KJS::DeleteDotNode::emitCode):
-        (KJS::PrefixResolveNode::emitCode):
-        (KJS::PrefixBracketNode::emitCode):
-        (KJS::PrefixDotNode::emitCode):
-        (KJS::ThrowableBinaryOpNode::emitCode):
-        (KJS::ReadModifyResolveNode::emitCode):
-        (KJS::AssignResolveNode::emitCode):
-        (KJS::AssignDotNode::emitCode):
-        (KJS::ReadModifyDotNode::emitCode):
-        (KJS::AssignBracketNode::emitCode):
-        (KJS::ReadModifyBracketNode::emitCode):
-        (KJS::ForInNode::ForInNode):
-        (KJS::ForInNode::emitCode):
-        (KJS::WithNode::emitCode):
-        (KJS::LabelNode::emitCode):
-        (KJS::ThrowNode::emitCode):
-        (KJS::ProgramNode::ProgramNode):
-        (KJS::ProgramNode::create):
-        (KJS::EvalNode::generateCode):
-        (KJS::FunctionBodyNode::create):
-        (KJS::FunctionBodyNode::generateCode):
-        (KJS::ProgramNode::generateCode):
-            All of these methods were handling the position information.  
-            Constructors and create methods were modified to store the information.
-            All the emitCall implementations listed needed to be updated to actually
-            record the position information we have so carefully collected.
-        * kjs/nodes.h:
-        (KJS::ThrowableExpressionData::ThrowableExpressionData):
-        (KJS::ThrowableExpressionData::setExceptionSourceRange):
-        (KJS::ThrowableExpressionData::divot):
-        (KJS::ThrowableExpressionData::startOffset):
-        (KJS::ThrowableExpressionData::endOffset):
-        (KJS::ThrowableSubExpressionData::ThrowableSubExpressionData):
-        (KJS::ThrowableSubExpressionData::setSubexpressionInfo):
-        (KJS::ThrowablePrefixedSubExpressionData::ThrowablePrefixedSubExpressionData):
-        (KJS::ThrowablePrefixedSubExpressionData::setSubexpressionInfo):
-            ThrowableExpressionData is just a uniform mechanism for storing the position
-            information.
-        (KJS::ResolveNode::):
-        (KJS::PrePostResolveNode::):
-        (KJS::ThrowableBinaryOpNode::):
-        (KJS::WithNode::):
-
-2008-07-18  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Cameron Zwarich.
-        
-        Three renames:
-        
-        "CallTypeNative" => "CallTypeHost"
-        "code" => "byteCode"
-        "generatedCode" => "generatedByteCode"
-
-2008-07-18  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Optimized <= for immediate number cases.
-        
-        SunSpider reports no overall change, but a 10% speedup on access-nsieve.
-
-2008-07-18  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Sam Weinig.
-
-        Fix some casts added in a previous build fix to match the style used
-        throughout WebKit.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::initializeCallFrame):
-        * VM/Register.h:
-        (KJS::Register::Register):
-
-2008-07-18  Landry Breuil  <landry@openbsd.org>
-
-        Bug 19975: [OpenBSD] Patches to enable build of WebKit
-
-        <https://bugs.webkit.org/show_bug.cgi?id=19975>
-
-        Reviewed by David Kilzer.
-
-        Support for OpenBSD, mostly threading and libm tweaks.
-
-        * kjs/collector.cpp: #include <pthread.h>
-        (KJS::currentThreadStackBase): use pthread_stackseg_np() to get stack base
-        * kjs/config.h: OpenBSD also provides <pthread_np.h>
-        * wtf/MathExtras.h: #include <sys/types.h> and <machine/ieee.h>
-        (isfinite), (signbit): as long as we don't have those functions provide fallback implementations
-        * wtf/Platform.h: Add support for PLATFORM(OPENBSD) and PLATFORM(SPARC64) macro
-
-2008-07-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Next step toward putting doubles in registers: Store constant pool
-        entries as registers, not JSValue*s.
-        
-        SunSpider reports no change.
-
-2008-07-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by John Sullivan and Oliver Hunt.
-        
-        A tiny bit of tidying in function call register allocation.
-        
-        This patch saves one register when invoking a function expression and/or
-        a new expression that is stored in a temporary.
-        
-        Since it's just one register, I can't make a testcase for it.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitCall): No need to ref the function we're calling
-        or its base. We'd like the call frame to overlap with them, if possible.
-        op_call will read the function and its base before writing the call frame,
-        so this is safe.
-
-        * kjs/nodes.cpp:
-        (KJS::NewExprNode::emitCode): No need to ref the function we're new-ing,
-        for the same reasons stated above.
-        
-        (KJS::FunctionCallValueNode::emitCode): ditto
-
-2008-07-17  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-        
-        * kjs/InternalFunction.cpp:
-
-2008-07-17  Sam Weinig  <sam@webkit.org>
-
-        Roll out r35199 as it is causing failures on the PPC build.
-
-2008-07-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by David Kilzer.
-        
-        Fixed https://bugs.webkit.org/show_bug.cgi?id=20067
-        Support function.name (Firefox extension)
-        
-        Pretty straight-forward.
-
-2008-07-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed <rdar://problem/6081636> Functions calls use more temporary
-        registers than necessary
-        
-        Holding a reference to the last statement result register caused each
-        successive statement to output its result to an even higher register.
-        
-        Happily, statements don't actually need to return a result register
-        at all. I hope to make this clearer in a future cleanup patch,
-        but this change will fix the major bug for now.
-
-        * kjs/nodes.cpp:
-        (KJS::statementListEmitCode):
-
-2008-07-17  Gavin Barraclough  <barraclough@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Merge pre&post dot nodes to simplify the parse tree.
-        Sunspider results show 0.6% progression (no performance change expected).
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        * kjs/nodes.h:
-        * kjs/nodes2string.cpp:
-
-2008-07-17  Gavin Barraclough  <barraclough@apple.com>
-
-        Reviewed by Cameron Zwarich.
-
-        Merge pre&post resolve nodes to simplify the parse tree.
-        Sunspider results show no performance change.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        * kjs/nodes.h:
-        * kjs/nodes2string.cpp:
-
-2008-07-17  Gavin Barraclough  <barraclough@apple.com>
-
-        Reviewed by Cameron Zwarich.
-
-        Merge logical nodes to simplify the parse tree.
-        Sunspider results show 0.6% progression (no performance change expected).
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        * kjs/nodes.h:
-        * kjs/nodes2string.cpp:
-
-2008-07-17  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Reviewed by Simon.
-
-        Fix MinGW build (broken in r35198) and simplify getLocalTime().
-
-        * kjs/DateMath.cpp:
-        (KJS::getLocalTime):
-
-2008-07-17  Gavin Barraclough  <barraclough@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Merge pre&post bracket nodes to simplify the parse tree.
-        Sunspider results show no performance change.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        * kjs/nodes.h:
-        * kjs/nodes2string.cpp:
-
-2008-07-17  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Reviewed by Simon.
-
-        Fix the 32-bit gcc builds, conversion from "long int" to Register is
-        ambiguous. Explicitly choose the intptr_t constructor.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::initializeCallFrame):
-        * VM/Register.h:
-        (KJS::Register::Register):
-
-2008-07-16  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Geoff Garen.
-
-        Fix JavaScript in 64-bit by using a pointer-sized integer
-        type in the Register union.  Also includes a rename of
-        the intType constant to IntType.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::initializeCallFrame):
-        * VM/Register.h:
-        (KJS::Register::):
-        (KJS::Register::Register):
-
-2008-07-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        First step toward putting doubles in registers: Turned Register into a
-        proper abstraction layer. It is no longer possible to cast a Register
-        to a JSValue*, or a Register& to a JSValue*&, or to access the union
-        inside a Register directly.
-        
-        SunSpider reports no change.
-        
-        In support of this change, I had to make the following mechanical changes
-        in a lot of places:
-        
-        1. Clients now use explicit accessors to read data out of Registers, and
-        implicit copy constructors to write data into registers.
-        
-        So, assignment that used to look like
-        
-            x.u.jsValue = y;
-        
-        now looks like
-        
-            x = y;
-            
-        And access that used to look like
-        
-            x = y.u.jsValue;
-        
-        now looks like
-        
-            x = y.jsValue();
-
-        2. I made generic flow control specific in opcodes that made their flow
-        control generic by treating a Register& as a JSValue*&. This had the
-        added benefit of removing some exception checking branches from immediate
-        number code.
-
-        3. I beefed up PropertySlot to support storing a Register* in a property
-        slot. For now, only JSVariableObject's symbolTableGet and symbolTablePut
-        use this functionality, but I expect more clients to use it in the future.
-        
-        4. I changed ArgList to be a buffer of Registers, not JSValue*'s, and I
-        changed ArgList iterator clients to iterate Registers, not JSValue*'s.
-
-2008-07-16  Ada Chan  <adachan@apple.com>
-
-        Fixed build.
-
-        * kjs/JSGlobalObject.cpp:
-
-2008-07-16  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam and Geoff.
-
-        <rdar://problem/5958840> Navigating to another page while profiler is
-        attached results in slow JavaScript for all time.
-
-        - The UNLIKELY keeps this from being a sunspider performance regression.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::~JSGlobalObject): Stop the profiler associated
-        with this exec state.
-
-2008-07-16  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Steve Falkenburg.
-
-        Replace adopting UString constructor in favor of explicit
-        static adopt method.
-
-        * API/JSStringRefCF.cpp:
-        (JSStringCreateWithCFString):
-        * kjs/StringConstructor.cpp:
-        (KJS::stringFromCharCode):
-        * kjs/StringPrototype.cpp:
-        (KJS::stringProtoFuncToLowerCase):
-        (KJS::stringProtoFuncToUpperCase):
-        (KJS::stringProtoFuncToLocaleLowerCase):
-        (KJS::stringProtoFuncToLocaleUpperCase):
-        * kjs/ustring.cpp:
-        (KJS::UString::adopt):
-        * kjs/ustring.h:
-        (KJS::UString::UString):
-        (KJS::UString::~UString):
-
-2008-07-16  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Reviewed by Simon.
-
-        http://trolltech.com/developer/task-tracker/index_html?method=entry&id=216179
-        Fix potential crash (on Qt for Windows port) when performing JavaScript date
-        conversion.
-
-        * kjs/DateMath.cpp:
-        (KJS::getLocalTime): For the Qt port, prefer to use Windows code, i.e.
-        localtime_s() instead of localtime() since the latter might crash (on Windows)
-        given a non-sensible, e.g. NaN, argument.
-
-2008-07-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Anders and Geoff.
-
-        https://bugs.webkit.org/show_bug.cgi?id=20023
-        Failed assertion in PropertyNameArray.cpp
-
-        This is already tested by testapi.
-
-        * API/JSObjectRef.cpp: (JSPropertyNameAccumulatorAddName): Add the string to identifier
-        table to appease PropertyNameArray.
-
-2008-07-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff.
-
-        Dereference identifiers when deleting a hash table (fixes leaks with private JSGlobalData
-        objects).
-
-        * kjs/JSGlobalData.cpp: (KJS::JSGlobalData::~JSGlobalData):
-        * kjs/lookup.cpp: (KJS::HashTable::deleteTable):
-        * kjs/lookup.h:
-        * kjs/lexer.cpp: (KJS::Lexer::~Lexer)
-        HashTable cannot have a destructor, because check-for-global-initializers complains about
-        having a global constructor then.
-
-2008-07-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff.
-
-        Check pthread_key_create return value.
-
-        This check was helpful when debugging a crash in run-webkit-tests --threaded that happened
-        because JSGlobalData objects were not deleted, and we were running out of pthread keys soon.
-        It also looks useful for production builds.
-
-        * wtf/ThreadSpecific.h: (WTF::::ThreadSpecific):
-
-2008-07-15  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Geoff.
-
-        Rename pageGroupIdentifier to profileGroup to keep mention of a
-        pageGroup out of JavaScriptCore.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::init):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::setProfileGroup):
-        (KJS::JSGlobalObject::profileGroup):
-        * profiler/ProfileGenerator.cpp:
-        (KJS::ProfileGenerator::create):
-        (KJS::ProfileGenerator::ProfileGenerator):
-        * profiler/ProfileGenerator.h:
-        (KJS::ProfileGenerator::profileGroup):
-        * profiler/Profiler.cpp:
-        (KJS::Profiler::startProfiling):
-        (KJS::dispatchFunctionToProfiles):
-        (KJS::Profiler::willExecute):
-        (KJS::Profiler::didExecute):
-
-2008-07-14  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Fix https://bugs.webkit.org/show_bug.cgi?id=20037
-        Bug 20037: GCC 4.2 build broken due to strict aliasing violation.
-
-        * kjs/ustring.cpp:
-        (KJS::UString::Rep::computeHash): Add a version of computeHash that takes a char* and explicit length.
-        * kjs/ustring.h:
-        * profiler/CallIdentifier.h:
-        (WTF::): Use new version of computeHash that takes a char* and explicit length to avoid unsafe aliasing.
-
-2008-07-14  David Hyatt  <hyatt@apple.com>
-
-        Fix a crashing bug in ListHashSet's -- operator.  Make sure that end() can be -- by special-casing the null
-        position.
-
-        Reviewed by Maciej
-
-        * wtf/ListHashSet.h:
-        (WTF::ListHashSetConstIterator::operator--):
-
-2008-07-14  David Hyatt  <hyatt@apple.com>
-
-        Buidl fix.  Make sure the second insertBefore method returns a value.
-
-        * wtf/ListHashSet.h:
-        (WTF::::insertBefore):
-
-2008-07-14  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * JavaScriptCore.vcproj/jsc/jsc.vcproj: Added include/pthreads to the
-        include path.
-
-2008-07-14  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Kevin McCullough.
-
-        Make JSGlobalData refcounted in preparation to adding a way to create contexts that share
-        global data.
-
-        * JavaScriptCore.exp:
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::create):
-        * kjs/JSGlobalData.h:
-        Made contructor private, and added a static create() method. Made the class inherit from
-        RefCounted.
-
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::globalData):
-        JSGlobalData is now owned by JSGlobalObject (except for the shared one, and the common
-        WebCore one, which are never deleted).
-
-        * kjs/Shell.cpp: (main): Create JSGlobalData with create() method.
-
-2008-07-14  Simon Hausmann  <hausmann@webkit.org>
-
-        Fix the single-threaded build.
-
-        * kjs/JSLock.cpp: Removed undeclared registerThread() function.
-        * kjs/collector.cpp:
-        (KJS::Heap::registerThread): Added dummy implementation.
-
-2008-07-14  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff Garen.
-
-        Eliminate per-thread JavaScript global data instance support and make arbitrary
-        global data/global object combinations possible.
-
-        * kjs/collector.cpp:
-        (KJS::Heap::Heap): Store a JSGlobalData pointer instead of multiple pointers to its members.
-        This allows for going from any JS object to its associated global data, currently used in
-        JSGlobalObject constructor to initialize its JSGlobalData pointer.
-        (KJS::Heap::registerThread): Changed thread registration data to be per-heap. Previously,
-        only the shared heap could be used from multiple threads, so it was the only one that needed
-        thread registration, but now this can happen to any heap.
-        (KJS::Heap::unregisterThread): Ditto.
-        (KJS::Heap::markStackObjectsConservatively): Adapt for the above changes.
-        (KJS::Heap::setGCProtectNeedsLocking): Ditto.
-        (KJS::Heap::protect): Ditto.
-        (KJS::Heap::unprotect): Ditto.
-        (KJS::Heap::collect): Ditto.
-        (KJS::Heap::globalObjectCount): Use global object list associated with the current heap,
-        not the late per-thread one.
-        (KJS::Heap::protectedGlobalObjectCount): Ditto.
-
-        * kjs/collector.h:
-        (KJS::Heap::ThreadRegistrar): Added a helper object that unregisters a thread when it is
-        destroyed.
-
-        * kjs/JSLock.cpp:
-        (KJS::JSLock::JSLock):
-        * kjs/JSLock.h:
-        (KJS::JSLock::JSLock):
-        Don't use JSLock to implicitly register threads. I've added registerThread() calls to most
-        places that use JSLock - we cannot guarantee absolute safety unless we always mark all
-        threads in the process, but these implicit registration calls should cover reasonable usage
-        scenarios, I hope.
-
-        * API/JSBase.cpp:
-        (JSEvaluateScript): Explicitly register the current thread.
-        (JSCheckScriptSyntax): Explicitly register the current thread.
-        (JSGarbageCollect): Changed to use the passed in context. Unfortunately, this creates a race
-        condition for clients that pass an already released context to JSGarbageCollect - but it is
-        unlikely to create real life problems.
-        To maintain compatibility, the shared heap is collected if NULL is passed.
-
-        * API/JSContextRef.cpp:
-        (JSGlobalContextCreate): Use a new syntax for JSGlobalObject allocation.
-        (JSGlobalContextRetain): Register the thread.
-        (JSContextGetGlobalObject): Register the thread.
-
-        * API/JSObjectRef.cpp:
-        (JSObjectMake):
-        (JSObjectMakeFunctionWithCallback):
-        (JSObjectMakeConstructor):
-        (JSObjectMakeFunction):
-        (JSObjectHasProperty):
-        (JSObjectGetProperty):
-        (JSObjectSetProperty):
-        (JSObjectGetPropertyAtIndex):
-        (JSObjectSetPropertyAtIndex):
-        (JSObjectDeleteProperty):
-        (JSObjectCallAsFunction):
-        (JSObjectCallAsConstructor):
-        (JSObjectCopyPropertyNames):
-        (JSPropertyNameAccumulatorAddName):
-        * API/JSValueRef.cpp:
-        (JSValueIsEqual):
-        (JSValueIsInstanceOfConstructor):
-        (JSValueMakeNumber):
-        (JSValueMakeString):
-        (JSValueToNumber):
-        (JSValueToStringCopy):
-        (JSValueToObject):
-        (JSValueProtect):
-        (JSValueUnprotect):
-        Register the thread.
-
-        * API/JSStringRef.cpp: (JSStringRelease): Changed a comment to not mention per-thread contexts.
-
-        * API/JSStringRefCF.cpp: Removed an unnecessary include of JSLock.h.
-
-        * JavaScriptCore.exp: Export JSGlobalData constructor/destructor, now that anyone can have
-        their own instances. Adapt to other changes, too.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Made ThreadSpecific.h private, as it is now
-        included by collector.h and is thus needed in other projects.
-
-        * kjs/InitializeThreading.cpp: (KJS::initializeThreadingOnce): Don't initialize per-thread
-        global data, as it no longer exists.
-
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        (KJS::JSGlobalData::~JSGlobalData):
-        * kjs/JSGlobalData.h:
-        Removed support for per-thread instance. Made constructor and destructor public.
-
-        * kjs/JSGlobalObject.cpp: (KJS::JSGlobalObject::init): Get to now arbitrary  JSGlobalData
-        via the heap.
-        (KJS::JSGlobalObject::operator new): Changed ot take JSGlobalDatra pointer.
-        * kjs/JSGlobalObject.h:
-
-        * kjs/Shell.cpp:
-        (main):
-        (jscmain):
-        Changed to maintain a custom JSGlobalData pointer instead of a per-thread one.
-
-2008-07-13  Ada Chan  <adachan@apple.com>
-
-        Windows build fix: Add wtf/RefCountedLeakCounter to the project.
-
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-
-2008-07-12  Jan Michael Alonzo  <jmalonzo@webkit.org>
-
-        Gtk, Qt and Wx build fix: Add wtf/RefCountedLeakCounter in the
-        build scripts
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCoreSources.bkl:
-
-2008-07-11  Stephanie Lewis  <slewis@apple.com>
-
-        Reviewed by Darin Adler and Oliver Hunt.
-
-        Refactor RefCounting Leak counting code into a common class.
-
-        In order to export the symbols I needed to put the debug defines inside the function names
-        
-        Before we had a separate channel for each Logging each Leak type.  Since the leak channels were only used in one location, and only at quit for simplicity I combined them all into one leak channel.
-
-        * JavaScriptCore.exp:
-        * JavaScriptCore.xcodeproj/project.pbxproj: add new class
-        * kjs/nodes.cpp: remove old leak counting code
-        * wtf/RefCountedLeakCounter.cpp: Added. create a common leak counting class
-        * wtf/RefCountedLeakCounter.h: Added.
-
-2008-07-11  David Hyatt  <hyatt@apple.com>
-
-        Add an insertBefore method to ListHashSet to allow for insertions in the middle of the list (rather than just
-        at the end).
-
-        Reviewed by Anders
-
-        * wtf/ListHashSet.h:
-        (WTF::::insertBefore):
-        (WTF::::insertNodeBefore):
-
-2008-07-11  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Darin Adler.
-
-        Move call function to CallData.cpp and construct to ConstructData.cpp.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * kjs/AllInOneFile.cpp:
-        * kjs/CallData.cpp: Copied from kjs/JSValue.cpp.
-        * kjs/ConstructData.cpp: Copied from kjs/JSValue.cpp.
-        * kjs/JSValue.cpp:
-
-2008-07-10  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Define WEBKIT_VERSION_MIN_REQUIRED=WEBKIT_VERSION_LATEST when building WebKit to ensure that no symbols end up with the weak_import attribute.
-
-        * Configurations/Base.xcconfig:
-
-2008-07-10  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Fix the Tiger build by omitting annotations from methods declared in categories when using old versions of GCC.
-
-        * API/WebKitAvailability.h:
-
-2008-07-10  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Darin.
-
-        -Minor cleanup. Renamed callTree() to head() and no longer use m_head
-        directly but instead keep it private and access via a method().
-
-        * profiler/HeavyProfile.cpp:
-        (KJS::HeavyProfile::HeavyProfile):
-        (KJS::HeavyProfile::generateHeavyStructure):
-        (KJS::HeavyProfile::addNode):
-        * profiler/Profile.h:
-        (KJS::Profile::head):
-        * profiler/ProfileGenerator.cpp:
-        (KJS::ProfileGenerator::ProfileGenerator):
-
-2008-07-10  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Mark Rowe.
-
-        Eliminate CollectorHeapIntrospector.
-
-        CollectorHeapIntrospector was added primarily in the hopes to improve leaks tool output,
-        a result that it didn't deliver. Also, it helped by labeling JSC heap regions as reported by
-        vmmap tool, but at the same time, it made them mislabeled as malloc'd ones - the correct
-        way to label mapped regions is to use a VM tag.
-
-        So, it makes more sense to remove it completely than to make it work with multiple heaps.
-
-        * JavaScriptCore.exp:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/AllInOneFile.cpp:
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreading):
-        * kjs/collector.cpp:
-        * kjs/collector.h:
-        * kjs/CollectorHeapIntrospector.cpp: Removed.
-        * kjs/CollectorHeapIntrospector.h: Removed.
-
-2008-07-09  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5951532> JSProfiler: Implement heavy (or bottom-up)
-        view (19228)
-        - Implemented the time and call count portionof heavy.  Now all that we
-        need is some UI.
-
-        * profiler/CallIdentifier.h: Removed an unused constructor.
-        * profiler/HeavyProfile.cpp: 
-        (KJS::HeavyProfile::HeavyProfile): Set the initial time of the head
-        node so that percentages work correctly.
-        (KJS::HeavyProfile::mergeProfiles): Sum the times and call count of
-        nodes being merged.
-        * profiler/ProfileNode.cpp: Set the intital values of time and call
-        count when copying ProfileNodes.
-        (KJS::ProfileNode::ProfileNode):
-
-2008-07-10  Jan Michael Alonzo  <jmalonzo@webkit.org>
-
-        Gtk build fix.
-
-        * GNUmakefile.am: Add HeavyProfile.cpp
-
-2008-07-09  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Geoff Garen.
-
-        Don't warn about deprecated functions in production builds.
-
-        * Configurations/Base.xcconfig:
-        * Configurations/DebugRelease.xcconfig:
-
-2008-07-09  Darin Adler  <darin@apple.com>
-
-        * JavaScriptCore.pri: Fix Qt build by adding HeavyProfile.cpp.
-
-2008-07-09  Kevin Ollivier  <kevino@theolliviers.com>
-
-        wx biuld fix. Add HeavyProfile.cpp to build files.
-
-        * JavaScriptCoreSources.bkl:
-
-2008-07-09  Kevin McCullough  <kmccullough@apple.com>
-
-        - Windows build fix.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-07-09  Kevin McCullough  <kmccullough@apple.com>
-
-        - Build fix.
-
-        * profiler/HeavyProfile.cpp:
-        (KJS::HeavyProfile::mergeProfiles):
-
-2008-07-09  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Geoff and Adam.
-
-        <rdar://problem/5951532> JSProfiler: Implement Bottom-Up view (19228)
-        - This is the plumbing for bottom-up, but does not include calculating
-        time, mostly because I'm still undclear about what the end result should
-        look like.
-        - This, obviously, does not include the UI to expose this in the
-        inspector yet.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * profiler/CallIdentifier.h:
-        (KJS::CallIdentifier::CallIdentifier):
-        (WTF::): Added HashTraits for CallIdentifiers to be used by a HashMap.
-        * profiler/HeavyProfile.cpp: Added.
-        (KJS::HeavyProfile::HeavyProfile):
-        (KJS::HeavyProfile::generateHeavyStructure):
-        (KJS::HeavyProfile::addNode):
-        (KJS::HeavyProfile::mergeProfiles):
-        (KJS::HeavyProfile::addAncestorsAsChildren):
-        * profiler/HeavyProfile.h: Added.
-        (KJS::HeavyProfile::create):
-        (KJS::HeavyProfile::heavyProfile):
-        (KJS::HeavyProfile::treeProfile):
-        * profiler/Profile.cpp: Removed old commented out includes.
-        * profiler/Profile.h: The m_head is needed by the HeavyProfile so it
-        is now protected as opposed to private.
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::ProfileNode): Created a constructor to copy
-        ProfileNodes.
-        (KJS::ProfileNode::findChild): Added a null check to make HeavyProfile
-        children finding easier and avoid a potential crasher.
-        * profiler/ProfileNode.h: Mostly moved things around but also added some
-        functionality needed by HeavyProfile.
-        (KJS::ProfileNode::create):
-        (KJS::ProfileNode::functionName):
-        (KJS::ProfileNode::url):
-        (KJS::ProfileNode::lineNumber):
-        (KJS::ProfileNode::head):
-        (KJS::ProfileNode::setHead):
-        (KJS::ProfileNode::setNextSibling):
-        (KJS::ProfileNode::actualTotalTime):
-        (KJS::ProfileNode::actualSelfTime):
-        * profiler/TreeProfile.cpp: Implemented the ability to get a
-        HeavyProfile.
-        (KJS::TreeProfile::heavyProfile):
-        * profiler/TreeProfile.h:
-
-2008-07-08  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Added support for checking if an object has custom properties in its
-        property map. WebCore uses this to optimize marking DOM wrappers.
-
-2008-07-08  Simon Hausmann  <hausmann@webkit.org>
-
-        Prospective Gtk/Wx build fixes, add ProfileGenerator.cpp to the build.
-
-        * GNUmakefile.am:
-        * JavaScriptCoreSources.bkl:
-
-2008-07-08  Simon Hausmann  <hausmann@webkit.org>
-
-        Fix the Qt build, add ProfileGenerator.cpp to the build.
-
-        * JavaScriptCore.pri:
-
-2008-07-07  David Kilzer  <ddkilzer@apple.com>
-
-        releaseFastMallocFreeMemory() should always be defined
-
-        Reviewed by Darin.
-
-        * JavaScriptCore.exp: Changed to export C++ binding for
-        WTF::releaseFastMallocFreeMemory() instead of C binding for
-        releaseFastMallocFreeMemory().
-        * wtf/FastMalloc.cpp: Moved definitions of
-        releaseFastMallocFreeMemory() to be in the WTF namespace
-        regardless whether FORCE_SYSTEM_MALLOC is defined.
-        * wtf/FastMalloc.h: Moved releaseFastMallocFreeMemory() from
-        extern "C" binding to WTF::releaseFastMallocFreeMemory().
-
-2008-07-07  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Geoff.
-
-        Bug 19926: URL causes crash within a minute
-        <https://bugs.webkit.org/show_bug.cgi?id=19926>
-
-        Add a check that lastGlobalObject is non-null in Machine::execute()
-        before copying its globals to the current register file.
-
-        In theory, it is possible to make a test case for this, but it will
-        take a while to get it right.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-
-2008-07-07  Darin Adler  <darin@apple.com>
-
-        Rubber stamped by Adele.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Fix a typo in a comment.
-
-2008-07-07  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fixes.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.vcproj/testapi/testapi.vcproj:
-
-2008-07-07  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Darin.
-
-        When the profiler is running it gathers information and creates a
-        Profile.  After it finishes the Profile can be sorted and have other
-        data refinements run over it.  Both of these were done in the same class
-        before.  Now I split the gathering operations into a new class called
-        ProfileGenerator.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * profiler/Profile.cpp: Removed code related to the gather stage of a
-        Profile's creation.  
-        (KJS::Profile::create):
-        (KJS::Profile::Profile):
-        * profiler/Profile.h: Ditto.
-        (KJS::Profile::title):
-        (KJS::Profile::callTree):
-        (KJS::Profile::setHead):
-        * profiler/ProfileGenerator.cpp: Added. This is the class that will
-        handle the stage of creating a Profile.  Once the Profile is finished
-        being created, this class goes away.
-        (KJS::ProfileGenerator::create):
-        (KJS::ProfileGenerator::ProfileGenerator):
-        (KJS::ProfileGenerator::title):
-        (KJS::ProfileGenerator::willExecute):
-        (KJS::ProfileGenerator::didExecute):
-        (KJS::ProfileGenerator::stopProfiling):
-        (KJS::ProfileGenerator::didFinishAllExecution):
-        (KJS::ProfileGenerator::removeProfileStart):
-        (KJS::ProfileGenerator::removeProfileEnd):
-        * profiler/ProfileGenerator.h: Added.
-        (KJS::ProfileGenerator::profile):
-        (KJS::ProfileGenerator::originatingGlobalExec):
-        (KJS::ProfileGenerator::pageGroupIdentifier):
-        (KJS::ProfileGenerator::client):
-        (KJS::ProfileGenerator::stoppedProfiling):
-        * profiler/Profiler.cpp: Now operates with the ProfileGenerator instead
-        of the Profile.
-        (KJS::Profiler::startProfiling):
-        (KJS::Profiler::stopProfiling):
-        (KJS::Profiler::didFinishAllExecution): It is here that the Profile is
-        handed off to its client and the Profile Generator is no longer needed.
-        (KJS::dispatchFunctionToProfiles):
-        (KJS::Profiler::willExecute):
-        (KJS::Profiler::didExecute):
-        * profiler/Profiler.h: Cleaned up the includes and subsequently the
-        forward declarations.  Also use the new ProfileGenerator.
-        (KJS::ProfilerClient::~ProfilerClient):
-        (KJS::Profiler::currentProfiles):
-        * profiler/TreeProfile.cpp: Use Profile's new interface.
-        (KJS::TreeProfile::create):
-        (KJS::TreeProfile::TreeProfile):
-        * profiler/TreeProfile.h:
-
-2008-07-07  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Cameron Zwarich.
-
-        Third step in broad cleanup effort.
-
-        [ File list elided ]
-
-2008-07-06  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Cameron Zwarich.
-
-        Second step in broad cleanup effort.
-
-        [ File list elided ]
-
-2008-07-05  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Cameron Zwarich.
-
-        First step in broad cleanup effort.
-
-        [ File list elided ]
-
-2008-07-05  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Cameron Zwarich.
-
-        Rename list.h/cpp to ArgList.h/cpp.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * VM/Machine.h:
-        * kjs/AllInOneFile.cpp:
-        * kjs/ArgList.cpp: Copied from JavaScriptCore/kjs/list.cpp.
-        * kjs/ArgList.h: Copied from JavaScriptCore/kjs/list.h.
-        * kjs/IndexToNameMap.cpp:
-        * kjs/JSGlobalData.cpp:
-        * kjs/JSGlobalData.h:
-        * kjs/JSObject.h:
-        * kjs/collector.cpp:
-        * kjs/list.cpp: Removed.
-        * kjs/list.h: Removed.
-
-2008-07-05  Sam Weinig  <sam@webkit.org>
-
-        Fix non-AllInOne builds again.
-
-        * kjs/BooleanPrototype.cpp:
-        * kjs/ErrorPrototype.cpp:
-        * kjs/FunctionPrototype.cpp:
-        * kjs/NumberPrototype.cpp:
-        * kjs/ObjectPrototype.cpp:
-
-2008-07-05  Sam Weinig  <sam@webkit.org>
-
-        Fix build on case-sensitive build systems.
-
-        * kjs/IndexToNameMap.cpp:
-
-2008-07-05  Sam Weinig  <sam@webkit.org>
-
-        Fix build.
-
-        * kjs/Arguments.cpp:
-        * kjs/BooleanPrototype.cpp:
-        * kjs/DateConstructor.cpp:
-        * kjs/ErrorPrototype.cpp:
-        * kjs/FunctionPrototype.cpp:
-        * kjs/NumberPrototype.cpp:
-        * kjs/ObjectPrototype.cpp:
-        * kjs/RegExpPrototype.cpp:
-        * kjs/StringConstructor.cpp:
-        * kjs/lookup.cpp:
-
-2008-07-05  Sam Weinig  <sam@webkit.org>
-
-        Fix non-AllInOne build.
-
-        * kjs/JSGlobalObject.cpp:
-
-2008-07-05  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Cameron Zwarich.
-
-        Split Arguments, IndexToNameMap, PrototypeFunction, GlobalEvalFunction and 
-        the functions on the global object out of JSFunction.h/cpp.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * VM/Machine.cpp:
-        * kjs/AllInOneFile.cpp:
-        * kjs/Arguments.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
-        * kjs/Arguments.h: Copied from JavaScriptCore/kjs/JSFunction.h.
-        * kjs/GlobalEvalFunction.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
-        * kjs/GlobalEvalFunction.h: Copied from JavaScriptCore/kjs/JSFunction.h.
-        * kjs/IndexToNameMap.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
-        * kjs/IndexToNameMap.h: Copied from JavaScriptCore/kjs/JSFunction.h.
-        * kjs/JSActivation.cpp:
-        * kjs/JSFunction.cpp:
-        * kjs/JSFunction.h:
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSGlobalObjectFunctions.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
-        * kjs/JSGlobalObjectFunctions.h: Copied from JavaScriptCore/kjs/JSFunction.h.
-        The functions on the global object should be in JSGlobalObject.cpp, but putting them there
-        was a 0.5% regression.
-
-        * kjs/PrototypeFunction.cpp: Copied from JavaScriptCore/kjs/JSFunction.cpp.
-        * kjs/PrototypeFunction.h: Copied from JavaScriptCore/kjs/JSFunction.h.
-        * kjs/Shell.cpp:
-        * kjs/lexer.cpp:
-        * kjs/ustring.cpp:
-
-2008-07-04  Sam Weinig  <sam@webkit.org>
-
-        Really fix the mac build.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-07-04  Sam Weinig  <sam@webkit.org>
-
-        Fix mac build.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-07-04  Sam Weinig  <sam@webkit.org>
-
-        Fix non-AllInOne builds.
-
-        * kjs/Error.cpp:
-        * kjs/GetterSetter.cpp:
-        * kjs/JSImmediate.cpp:
-        * kjs/operations.cpp:
-
-2008-07-04  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Dan Bernstein.
-
-        Split Error and GetterSetter out of JSObject.h.
-
-        * API/JSCallbackObjectFunctions.h:
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * kjs/AllInOneFile.cpp:
-        * kjs/ClassInfo.h: Copied from JavaScriptCore/kjs/JSObject.h.
-        * kjs/Error.cpp: Copied from JavaScriptCore/kjs/JSObject.cpp.
-        * kjs/Error.h: Copied from JavaScriptCore/kjs/JSObject.h.
-        * kjs/GetterSetter.cpp:
-        * kjs/GetterSetter.h: Copied from JavaScriptCore/kjs/JSObject.h.
-        * kjs/JSObject.cpp:
-        * kjs/JSObject.h:
-        * kjs/nodes.h:
-
-2008-07-04  Simon Hausmann  <hausmann@webkit.org>
-
-        Fix the Wx build, added TreeProfile.cpp to the build.
-
-        * JavaScriptCoreSources.bkl:
-
-2008-07-03  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Fix output path of recently-added script phase to reference the correct file.
-        This prevents Xcode from running the script phase unnecessarily, which caused
-        the generated header to be recreated and lead to AllInOneFile.cpp rebuilding.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-07-03  Mark Rowe  <mrowe@apple.com>
-
-        Follow-up to the 64-bit build fix.  Use intptr_t rather than ssize_t as
-        the latter is non-standard and does not exist on Windows.
-
-        * kjs/JSLock.cpp:
-        (KJS::JSLock::lockCount):
-        (KJS::JSLock::lock):
-        (KJS::JSLock::unlock):
-        (KJS::JSLock::DropAllLocks::DropAllLocks):
-        * kjs/JSLock.h:
-
-2008-07-02  Mark Rowe  <mrowe@apple.com>
-
-        Fix the 64-bit build.  pthread_getspecific works with pointer-sized values,
-        so use ssize_t rather than int to track the lock count to avoid warnings about
-        truncating the result of pthread_getspecific.
-
-        * kjs/JSLock.cpp:
-        (KJS::JSLock::lockCount):
-        (KJS::JSLock::lock):
-        (KJS::JSLock::unlock):
-        (KJS::JSLock::DropAllLocks::DropAllLocks):
-        * kjs/JSLock.h:
-
-2008-07-03  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Removed checking for the array get/put fast case from the array code.
-        Callers who want the fast case should call getIndex and/or setIndex
-        instead. (get_by_val and put_by_val already do this.)
-        
-        SunSpider reports no change overall, but a 1.4% speedup on fannkuch and
-        a 3.6% speedup on nsieve.
-
-2008-07-03  Dan Bernstein  <mitz@apple.com>
-
-        - Windows build fix
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Added TreeProfile.{h,cpp}.
-
-2008-07-03  Dan Bernstein  <mitz@apple.com>
-
-        Reviewed by Anders Carlsson.
-
-        - Windows build fix
-
-        * VM/Machine.cpp:
-        (KJS::Machine::Machine):
-
-2008-07-03  Simon Hausmann  <hausmann@webkit.org>
-
-        Reviewed by Alexey Proskuryakov.
-
-        Fix the non-threaded build.
-
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::threadInstanceInternal):
-
-2008-07-03  Simon Hausmann  <hausmann@webkit.org>
-
-        Fix the Qt build, added TreeProfile to the build.
-
-        * JavaScriptCore.pri:
-
-2008-07-02  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff.
-
-        Don't create unnecessary JSGlobalData instances.
-
-        * kjs/JSGlobalData.h:
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::threadInstanceExists):
-        (KJS::JSGlobalData::sharedInstanceExists):
-        (KJS::JSGlobalData::threadInstance):
-        (KJS::JSGlobalData::sharedInstance):
-        (KJS::JSGlobalData::threadInstanceInternal):
-        (KJS::JSGlobalData::sharedInstanceInternal):
-        Added methods to query instance existence.
-
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreadingOnce):
-        Initialize thread instance static in a new way.
-
-        * API/JSBase.cpp:
-        (JSGarbageCollect):
-        * kjs/collector.cpp:
-        (KJS::Heap::collect):
-        Check for instance existence before accessing it.
-
-2008-07-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Cameron Zwarich.
-        
-        Fixed https://bugs.webkit.org/show_bug.cgi?id=19862
-        REGRESSION (r34907): Gmail crashes in JavaScriptCore code while editing drafts
-        
-        I was never able to reproduce this issue, but Cameron could, and he says
-        that this patch fixes it.
-        
-        The crash seems tied to a timer or event handler callback. In such a case,
-        the sole reference to the global object may be in the current call frame,
-        so we can't depend on the global object to mark the call frame area in
-        the register file.
-        
-        The new GC marking rule is: the global object is not responsible for
-        marking the whole register file -- it's just responsible for the globals
-        section it's tied to. The heap is responsible for marking the call frame area.
-
-2008-07-02  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Add the ability to trace JavaScriptCore garabge collections using dtrace.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Generate the dtrace probe header
-        file when building on a new enough version of Mac OS X.
-        * JavaScriptCorePrefix.h: Add our standard Mac OS X version detection macros.
-        * kjs/Tracing.d: Declare three dtrace probes.
-        * kjs/Tracing.h: Include the generated dtrace macros if dtrace is available,
-        otherwise provide versions that do nothing.
-        * kjs/collector.cpp:
-        (KJS::Heap::collect): Fire dtrace probes when starting a collection, after the
-        mark phase has completed, and when the collection is complete.
-        * wtf/Platform.h: Define HAVE_DTRACE when building on a new enough version of Mac OS X.
-
-2008-07-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Rubber stamped by Oliver Hunt.
-        
-        Reduced the max register file size from 8MB to 2MB.
-
-        We still allow about 20,000 levels of recursion.
-
-2008-07-02  Alp Toker  <alp@nuanti.com>
-
-        Build fix for r34960. Add TreeProfile.cpp to build.
-
-        * GNUmakefile.am:
-
-2008-07-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Optimized a[n] get for cases when a is an array or a string. When a is
-        an array, we optimize both get and put. When a is a string, we only
-        optimize get, since you can't put to a string.
-        
-        SunSpider says 3.4% faster.
-
-2008-07-02  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Darin.
-
-        -Small cleanup in preparation for implementing Bottom-up.
-
-        * profiler/CallIdentifier.h: Rename debug function to make it clear of
-        its output and intention to be debug only.
-        (KJS::CallIdentifier::operator const char* ): Implement in terms of
-        c_str.
-        (KJS::CallIdentifier::c_str):
-        * profiler/ProfileNode.cpp: Impelment findChild() which will be needed
-        by the bottom-up implementation.
-        (KJS::ProfileNode::findChild):
-        * profiler/ProfileNode.h: Added comments to make the collections of
-        functions more clear.
-        (KJS::ProfileNode::operator==):
-        (KJS::ProfileNode::c_str):
-
-2008-07-02  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Darin.
-
-        Bug 19776: Number.toExponential() is incorrect for numbers between 0.1 and 1
-        <https://bugs.webkit.org/show_bug.cgi?id=19776>
-
-        Perform the sign check for the exponent on the actual exponent value,
-        which is 1 less than the value of decimalPoint, instead of on the value
-        of decimalPoint itself.
-
-        * kjs/NumberPrototype.cpp:
-        (KJS::exponentialPartToString):
-
-2008-07-02  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5951532> JSProfiler: Implement Bottom-Up view (19228)
-        - Subclass TreeProfile as I prepare for a HeavyProfile to be comming
-        later.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * profiler/Profile.cpp: By default we create a TreeProfile.
-        (KJS::Profile::create):
-        * profiler/Profile.h: Changes to the Profile class to make it amenable
-        to be inherited from.
-        (KJS::Profile::~Profile):
-        * profiler/TreeProfile.cpp: Added.
-        (KJS::TreeProfile::create):
-        (KJS::TreeProfile::TreeProfile):
-        (KJS::TreeProfile::heavyProfile):
-        * profiler/TreeProfile.h: Added.
-        (KJS::TreeProfile::treeProfile):
-
-2008-07-02  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Dan.
-
-        Broke CallIdentifier out into its own file. I did this because it's
-        going to grow a lot soon and I wanted this to be a separate patch.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * profiler/CallIdentifier.h: Added.
-        (KJS::CallIdentifier::CallIdentifier):
-        (KJS::CallIdentifier::operator==):
-        (KJS::CallIdentifier::operator!=):
-        (KJS::CallIdentifier::operator const char* ):
-        (KJS::CallIdentifier::toString):
-        * profiler/ProfileNode.h:
-
-2008-07-02  Simon Hausmann  <hausmann@webkit.org>
-
-        Build fix. Implemented missing functions for single-threaded build.
-
-        * kjs/JSLock.cpp:
-        (KJS::JSLock::JSLock):
-        (KJS::JSLock::lock):
-        (KJS::JSLock::unlock):
-        (KJS::JSLock::DropAllLocks::DropAllLocks):
-
-2008-07-02  Alexey Proskuryakov  <ap@webkit.org>
-
-        Another non-AllInOne build fix.
-
-        * kjs/JSGlobalObject.cpp: Include JSLock.h here, too.
-
-2008-07-02  Alexey Proskuryakov  <ap@webkit.org>
-
-        Non-AllInOne build fix.
-
-        * kjs/interpreter.cpp: Include JSLock.h.
-
-2008-06-30  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Disable JSLock for per-thread contexts.
-
-        No change on SunSpider.
-
-        * kjs/JSGlobalData.h:
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        (KJS::JSGlobalData::sharedInstance):
-        Added isSharedInstance as a better way to tell whether the instance is shared (legacy).
-
-        * kjs/JSLock.cpp:
-        (KJS::createJSLockCount):
-        (KJS::JSLock::lockCount):
-        (KJS::setLockCount):
-        (KJS::JSLock::JSLock):
-        (KJS::JSLock::lock):
-        (KJS::JSLock::unlock):
-        (KJS::JSLock::currentThreadIsHoldingLock):
-        (KJS::JSLock::DropAllLocks::DropAllLocks):
-        (KJS::JSLock::DropAllLocks::~DropAllLocks):
-        * kjs/JSLock.h:
-        (KJS::JSLock::JSLock):
-        (KJS::JSLock::~JSLock):
-        Made JSLock and JSLock::DropAllLocks constructors take a parameter to decide whether to
-        actually lock a mutex, or only to increment recursion count. We cannot turn it into no-op
-        if we want to keep existing assertions working.
-        Made recursion count per-thread, now that locks may not lock.
-
-        * API/JSBase.cpp:
-        (JSEvaluateScript): Take JSLock after casting JSContextRef to ExecState* (which doesn't need
-        locking in any case), so that a decision whether to actually lock can be made.
-        (JSCheckScriptSyntax): Ditto.
-        (JSGarbageCollect): Only lock while collecting the shared heap, not the per-thread one.
-
-        * API/JSObjectRef.cpp:
-        (JSClassCreate): Don't lock, as there is no reason to.
-        (JSClassRetain): Ditto.
-        (JSClassRelease): Ditto.
-        (JSPropertyNameArrayRetain): Ditto.
-        (JSPropertyNameArrayRelease): Only lock while deleting the array, as that may touch
-        identifier table.
-        (JSPropertyNameAccumulatorAddName): Adding a string also involves an identifier table
-        lookup, and possibly modification.
-
-        * API/JSStringRef.cpp:
-        (JSStringCreateWithCharacters):
-        (JSStringCreateWithUTF8CString):
-        (JSStringRetain):
-        (JSStringRelease):
-        (JSStringGetUTF8CString):
-        (JSStringIsEqual):
-        * API/JSStringRefCF.cpp:
-        (JSStringCreateWithCFString):
-        JSStringRef operations other than releasing do not need locking.
-
-        * VM/Machine.cpp: Don't include unused JSLock.h.
-
-        * kjs/CollectorHeapIntrospector.cpp: (KJS::CollectorHeapIntrospector::statistics):
-        Don't take the lock for real, as heap introspection pauses the process anyway. It seems that
-        the existing code could cause deadlocks.
-
-        * kjs/Shell.cpp:
-        (functionGC):
-        (main):
-        (jscmain):
-        The test tool uses a per-thread context, so no real locking is required.
-
-        * kjs/collector.h:
-        (KJS::Heap::setGCProtectNeedsLocking): Optionally protect m_protectedValues access with a
-        per-heap mutex. This is only needed for WebCore Database code, which violates the "no data
-        migration between threads" by using ProtectedPtr on a background thread.
-        (KJS::Heap::isShared): Keep a shared flag here, as well.
-
-        * kjs/protect.h:
-        (KJS::::ProtectedPtr):
-        (KJS::::~ProtectedPtr):
-        (KJS::::operator):
-        (KJS::operator==):
-        (KJS::operator!=):
-        ProtectedPtr is ony used from WebCore, so it doesn't need to take JSLock. An assertion in
-        Heap::protect/unprotect guards agains possible future unlocked uses of ProtectedPtr in JSC.
-
-        * kjs/collector.cpp:
-        (KJS::Heap::Heap): Initialize m_isShared.
-        (KJS::Heap::~Heap): No need to lock for real during destruction, but must keep assertions
-        in sweep() working.
-        (KJS::destroyRegisteredThread): Registered thread list is only accessed for shared heap,
-        so locking is always needed here.
-        (KJS::Heap::registerThread): Ditto.
-        (KJS::Heap::markStackObjectsConservatively): Use m_isShared instead of comparing to a shared
-        instance for a small speedup.
-        (KJS::Heap::setGCProtectNeedsLocking): Create m_protectedValuesMutex. There is currently no
-        way to undo this - and ideally, Database code will be fixed to lo longer require this quirk.
-        (KJS::Heap::protect): Take m_protectedValuesMutex (if it exists) while accessing
-        m_protectedValues.
-        (KJS::Heap::unprotect): Ditto.
-        (KJS::Heap::markProtectedObjects): Ditto.
-        (KJS::Heap::protectedGlobalObjectCount): Ditto.
-        (KJS::Heap::protectedObjectCount): Ditto.
-        (KJS::Heap::protectedObjectTypeCounts): Ditto.
-
-        * kjs/ustring.cpp:
-        * kjs/ustring.h:
-        Don't include JSLock.h, which is no longer used here. As a result, an explicit include had
-        to be added to many files in JavaScriptGlue, WebCore and WebKit.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::init):
-        * API/JSCallbackConstructor.cpp:
-        (KJS::constructJSCallback):
-        * API/JSCallbackFunction.cpp:
-        (KJS::JSCallbackFunction::call):
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::init):
-        (KJS::::getOwnPropertySlot):
-        (KJS::::put):
-        (KJS::::deleteProperty):
-        (KJS::::construct):
-        (KJS::::hasInstance):
-        (KJS::::call):
-        (KJS::::getPropertyNames):
-        (KJS::::toNumber):
-        (KJS::::toString):
-        (KJS::::staticValueGetter):
-        (KJS::::callbackGetter):
-        * API/JSContextRef.cpp:
-        (JSGlobalContextCreate):
-        (JSGlobalContextRetain):
-        (JSGlobalContextRelease):
-        * API/JSValueRef.cpp:
-        (JSValueIsEqual):
-        (JSValueIsStrictEqual):
-        (JSValueIsInstanceOfConstructor):
-        (JSValueMakeNumber):
-        (JSValueMakeString):
-        (JSValueToNumber):
-        (JSValueToStringCopy):
-        (JSValueToObject):
-        (JSValueProtect):
-        (JSValueUnprotect):
-        * JavaScriptCore.exp:
-        * kjs/PropertyNameArray.h:
-        (KJS::PropertyNameArray::globalData):
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::checkSyntax):
-        (KJS::Interpreter::evaluate):
-        Pass a parameter to JSLock/JSLock::DropAllLocks to decide whether the lock needs to be taken.
-
-2008-07-01  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19834
-        Failed assertion in JavaScriptCore/VM/SegmentedVector.h:82
-
-        Creating a global object with a custom prototype resets it twice (wasteful!).
-        So, addStaticGlobals() was called twice, but JSGlobalObject::reset() didn't reset
-        the register array.        
-
-        * kjs/JSGlobalObject.cpp: (KJS::JSGlobalObject::reset): Call setRegisterArray(0, 0).
-
-        * kjs/JSVariableObject.h: Changed registerArray to OwnArrayPtr. Also, added private copy
-        constructor and operator= to ensure that no one attempts to copy this object (for whatever
-        reason, I couldn't make Noncopyable work).
-
-        * kjs/JSGlobalObject.h: (KJS::JSGlobalObject::addStaticGlobals): Allocate registerArray
-        with new[].
-
-        * kjs/JSVariableObject.cpp:
-        (KJS::JSVariableObject::copyRegisterArray): Allocate registerArray with new[].
-        (KJS::JSVariableObject::setRegisterArray): Avoid hitting an assertion in OwnArrayPtr when
-        "changing" the value from 0 to 0.
-
-2008-07-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Removed and/or reordered exception checks in array-style a[n] access.
-        
-        SunSpider says 1.4% faster.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): No need to check for exceptions before
-        calling toString, toNumber and/or get. If the call ends up being observable
-        through toString, valueOf, or a getter, we short-circuit it there, instead.
-        In the op_del_by_val case, I removed the incorrect comment without actually
-        removing the code, since I didn't want to tempt the GCC fates!
-
-        * kjs/JSObject.cpp:
-        (KJS::callDefaultValueFunction): Added exception check to prevent
-        toString and valueOf functions from observing execution after an exception
-        has been thrown. This removes some of the burden of exception checking
-        from the machine.
-
-        (KJS::JSObject::defaultValue): Removed redundant exception check here.
-
-        * kjs/PropertySlot.cpp:
-        (KJS::PropertySlot::functionGetter): Added exception check to prevent
-        getter functions from observing execution after an exception has been
-        thrown. This removes some of the burden of exception checking from the
-        machine.
-
-2008-07-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Optimized a[n] get and put for cases where n is an immediate unsigned
-        value.
-        
-        SunSpider says 3.5% faster.
-
-2008-07-01  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Darin.
-
-        Bug 19844: JavaScript Switch statement modifies "this"
-        <https://bugs.webkit.org/show_bug.cgi?id=19844>
-
-        Use a temporary when generating code for switch clauses to avoid
-        overwriting 'this' or a local variable.
-
-        * kjs/nodes.cpp:
-        (KJS::CaseBlockNode::emitCodeForBlock):
-
-2008-07-01  Christian Dywan  <christian@twotoasts.de>
-
-        Gtk+ build fix.
-
-        * kjs/list.cpp: Include "JSCell.h"
-
-2008-07-01  Kevin McCullough  <kmccullough@apple.com>
-
-        Build fix.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-07-01  Dan Bernstein  <mitz@apple.com>
-
-        Reviewed by Anders Carlsson.
-
-        - Mac release build fix
-
-        * JavaScriptCore.exp:
-
-2008-07-01  Sam Weinig  <sam@webkit.org>
-
-        Try and fix mac builds.
-
-        * JavaScriptCore.exp:
-
-2008-07-01  Sam Weinig  <sam@webkit.org>
-
-        Fix non-AllInOne builds.
-
-        * kjs/DateMath.cpp:
-
-2008-07-01  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Darin Adler.
-
-        Split JSCell and JSNumberCell class declarations out of JSValue.h
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * VM/JSPropertyNameIterator.h:
-        * kjs/AllInOneFile.cpp:
-        * kjs/JSCell.cpp: Copied from JavaScriptCore/kjs/JSValue.cpp.
-        * kjs/JSCell.h: Copied from JavaScriptCore/kjs/JSValue.h.
-        (KJS::JSValue::getJSNumber):
-        * kjs/JSNumberCell.cpp:
-        * kjs/JSNumberCell.h: Copied from JavaScriptCore/kjs/JSValue.h.
-        * kjs/JSObject.h:
-        * kjs/JSString.cpp:
-        (KJS::jsString):
-        (KJS::jsOwnedString):
-        * kjs/JSString.h:
-        (KJS::JSValue::toThisJSString):
-        * kjs/JSValue.cpp:
-        * kjs/JSValue.h:
-
-2008-07-01  Anders Carlsson  <andersca@apple.com>
-
-        Build fixes.
-        
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::addStaticGlobals):
-
-2008-07-01  Simon Hausmann  <hausmann@webkit.org>
-
-        Build fix, include OwnPtr.h.
-
-        * kjs/RegExpConstructor.h:
-
-2008-06-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed a global object leak caused by the switch to one register file.
-        
-        Don't unconditionally mark the register file, since that logically
-        makes all global variables GC roots, even when their global object is
-        no longer reachable.
-        
-        Instead, make the global object associated with the register file
-        responsible for marking the register file.
-
-2008-06-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Removed the "registerBase" abstraction. Since the register file never
-        reallocates, we can keep direct pointers into it, instead of
-        <registerBase, offset> tuples.
-        
-        SunSpider says 0.8% faster.
-        
-2008-06-30  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by NOBODY (build fix).
-
-        Fix build by adding all (hopefully) the missing includes.
-
-        * kjs/BooleanPrototype.cpp:
-        * kjs/DateConstructor.cpp:
-        * kjs/ErrorPrototype.cpp:
-        * kjs/FunctionPrototype.cpp:
-        * kjs/NativeErrorConstructor.cpp:
-        * kjs/NumberPrototype.cpp:
-        * kjs/ObjectPrototype.cpp:
-        * kjs/RegExpConstructor.cpp:
-        * kjs/StringConstructor.cpp:
-        * kjs/StringPrototype.cpp:
-
-2008-06-30  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 19830: REGRESSION (r34883): Google Reader doesn't show up feed list on sidebar
-        <https://bugs.webkit.org/show_bug.cgi?id=19830>
-
-        Ensure that we do not eliminate a write to a local register when doing
-        peephole optimizations.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitJumpIfTrue):
-        (KJS::CodeGenerator::emitJumpIfFalse):
-
-2008-06-30  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Darin Alder.
-
-        Split InternalFunction into its own header file.
-
-        * API/JSCallbackFunction.h:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/ArrayConstructor.h:
-        * kjs/BooleanConstructor.h:
-        * kjs/DateConstructor.h:
-        * kjs/ErrorConstructor.h:
-        * kjs/FunctionConstructor.h:
-        * kjs/FunctionPrototype.h:
-        * kjs/InternalFunction.h: Copied from kjs/JSFunction.h.
-        * kjs/JSFunction.h:
-        * kjs/NativeErrorConstructor.h:
-        * kjs/NumberConstructor.h:
-        * kjs/ObjectConstructor.h:
-        * kjs/RegExpConstructor.h:
-        * kjs/StringConstructor.h:
-        * profiler/Profiler.cpp:
-
-2008-06-30  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Kevin McCullough.
-
-        Remove empty files Instruction.cpp, LabelID.cpp, Register.cpp and RegisterID.cpp.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * VM/Instruction.cpp: Removed.
-        * VM/LabelID.cpp: Removed.
-        * VM/Register.cpp: Removed.
-        * VM/RegisterID.cpp: Removed.
-
-2008-06-30  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped (reluctantly) by Kevin McCullough.
-
-        Rename date_object.h/cpp to DateInstance.h/cpp
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * kjs/AllInOneFile.cpp:
-        * kjs/DateConstructor.cpp:
-        * kjs/DateInstance.cpp: Copied from kjs/date_object.cpp.
-        * kjs/DateInstance.h: Copied from kjs/date_object.h.
-        * kjs/DatePrototype.cpp:
-        * kjs/DatePrototype.h:
-        * kjs/date_object.cpp: Removed.
-        * kjs/date_object.h: Removed.
-
-2008-06-30  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Darin Adler.
-
-        Remove internal.cpp and move its contents to there own .cpp files.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * kjs/AllInOneFile.cpp:
-        * kjs/GetterSetter.cpp: Copied from kjs/internal.cpp.
-        * kjs/InternalFunction.cpp: Copied from kjs/internal.cpp.
-        * kjs/JSNumberCell.cpp: Copied from kjs/internal.cpp.
-        * kjs/JSString.cpp: Copied from kjs/internal.cpp.
-        * kjs/JSString.h:
-        * kjs/LabelStack.cpp: Copied from kjs/internal.cpp.
-        * kjs/NumberConstructor.cpp:
-        * kjs/NumberObject.cpp:
-        (KJS::constructNumber):
-        (KJS::constructNumberFromImmediateNumber):
-        * kjs/internal.cpp: Removed.
-
-2008-06-30  Adam Roben  <aroben@apple.com>
-
-        Fix <rdar://5954749> Assertion failure due to HashTable's use of
-        operator&
-
-        HashTable was passing &value to constructDeletedValue, which in
-        classes like WebCore::COMPtr would cause an assertion. We now pass
-        value by reference instead of by address so that the HashTraits
-        implementations have more flexibility in constructing the deleted
-        value.
-
-        Reviewed by Ada Chan.
-
-        * VM/CodeGenerator.h: Updated for changes to HashTraits.
-        * wtf/HashTable.h:
-        (WTF::::deleteBucket): Changed to pass bucket by reference instead of
-        by address.
-        (WTF::::checkKey): Ditto.
-        * wtf/HashTraits.h:
-        (WTF::): Updated HashTraits for HashTable change.
-
-2008-07-01  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Cameron Zwarich.
-
-        Make RegisterFile really unmap memory on destruction.
-
-        This fixes run-webkit-tests --threaded, which ran out of address space in a few seconds.
-
-        * VM/RegisterFile.cpp: (KJS::RegisterFile::~RegisterFile): Unmap all the memory, not just
-        1/4 of it.
-
-        * kjs/JSGlobalObject.h: Don't include RegisterFile.h, so that changes to it don't make
-        half of WebCore rebuild.
-
-        * VM/Machine.h: Don't forward declare RegisterFile, as RegisterFile.h is included already.
-
-        * VM/RegisterFile.h: (KJS::RegisterFile::RegisterFile): Assert that the allocation succeeded.
-
-2008-06-30  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Rubber-stamped by Oliver.
-
-        Correct the documentation for op_put_by_index.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-06-29  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 19821: Merge the instruction pair (less, jfalse)
-        <https://bugs.webkit.org/show_bug.cgi?id=19821>
-        
-        This is a 2.4% win on SunSpider. I needed to add an ALWAYS_INLINE
-        intrinisc to CodeGenerator::rewindBinaryOp() to avoid a massive
-        regression in regexp-dna.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::rewindBinaryOp):
-        (KJS::CodeGenerator::emitJumpIfFalse):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.cpp:
-        (KJS::):
-        * VM/Opcode.h:
-
-2008-06-29  Sam Weinig  <sam@webkit.org>
-
-        Fix non-AllInOne builds.
-
-        * kjs/JSObject.cpp:
-        * kjs/JSValue.cpp:
-
-2008-06-29  Sam Weinig  <sam@webkit.org>
-
-        Build fix for Qt.
-
-        * kjs/DateMath.cpp:
-        * kjs/DatePrototype.cpp:
-
-2008-06-29  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Cameron Zwarich.
-
-        Splits ErrorConstructor, ErrorPrototype,  NativeErrorConstructor and
-        NativeErrorPrototype out of error_object.h/cpp and renames it ErrorInstance.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * kjs/AllInOneFile.cpp:
-        * kjs/ArrayConstructor.cpp:
-        * kjs/ArrayPrototype.cpp:
-        * kjs/BooleanPrototype.cpp:
-        * kjs/DatePrototype.cpp:
-        * kjs/ErrorConstructor.cpp: Copied from kjs/error_object.cpp.
-        * kjs/ErrorConstructor.h: Copied from kjs/error_object.h.
-        * kjs/ErrorInstance.cpp: Copied from kjs/error_object.cpp.
-        * kjs/ErrorInstance.h: Copied from kjs/error_object.h.
-        * kjs/ErrorPrototype.cpp: Copied from kjs/error_object.cpp.
-        * kjs/ErrorPrototype.h: Copied from kjs/error_object.h.
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSObject.cpp:
-        * kjs/JSValue.cpp:
-        * kjs/NativeErrorConstructor.cpp: Copied from kjs/error_object.cpp.
-        * kjs/NativeErrorConstructor.h: Copied from kjs/error_object.h.
-        * kjs/NativeErrorPrototype.cpp: Copied from kjs/error_object.cpp.
-        * kjs/NativeErrorPrototype.h: Copied from kjs/error_object.h.
-        * kjs/NumberPrototype.cpp:
-        * kjs/RegExpConstructor.cpp:
-        * kjs/RegExpObject.cpp:
-        * kjs/RegExpPrototype.cpp:
-        * kjs/StringPrototype.cpp:
-        * kjs/error_object.cpp: Removed.
-        * kjs/error_object.h: Removed.
-        * kjs/internal.cpp:
-
-2008-06-29  Sam Weinig  <sam@webkit.org>
-
-        Fix non-AllInOne build.
-
-        * kjs/DateConstructor.cpp:
-        * kjs/DateMath.cpp:
-        * kjs/JSObject.cpp:
-
-2008-06-29  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Oliver Hunt.
-
-        Splits DateConstructor and DatePrototype out of date_object.h/cpp
-        Moves shared Date code into DateMath.
-
-        * DerivedSources.make:
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * kjs/AllInOneFile.cpp:
-        * kjs/DateConstructor.cpp: Copied from kjs/date_object.cpp.
-        * kjs/DateConstructor.h: Copied from kjs/date_object.h.
-        * kjs/DateMath.cpp:
-        (KJS::ymdhmsToSeconds):
-        (KJS::):
-        (KJS::skipSpacesAndComments):
-        (KJS::findMonth):
-        (KJS::parseDate):
-        (KJS::timeClip):
-        (KJS::formatDate):
-        (KJS::formatDateUTCVariant):
-        (KJS::formatTime):
-        * kjs/DateMath.h:
-        (KJS::gmtoffset):
-        * kjs/DatePrototype.cpp: Copied from kjs/date_object.cpp.
-        * kjs/DatePrototype.h: Copied from kjs/date_object.h.
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSObject.cpp:
-        * kjs/date_object.cpp:
-        * kjs/date_object.h:
-        * kjs/internal.cpp:
-
-2008-06-29  Jan Michael Alonzo  <jmalonzo@webkit.org>
-
-        Rubber-stamped by Cameron Zwarich
-
-        Fix Gtk non-AllInOne build
-
-        * GNUmakefile.am: include JSVariableObject.cpp
-        * kjs/RegExpConstructor.cpp: include RegExpObject.h
-        * kjs/RegExpObject.h: forward declare RegExpPrototype
-
-2008-06-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam and Cameron.
-
-        - fix https://bugs.webkit.org/show_bug.cgi?id=19805
-          Array.concat turns missing array elements into "undefined"
-
-        Test: fast/js/array-holes.html
-
-        * JavaScriptCore.exp: No longer export JSArray::getItem.
-
-        * kjs/ArrayPrototype.cpp:
-        (KJS::arrayProtoFuncConcat): Changed to use getProperty instead of
-        JSArray::getItem -- need to handle properties from the prototype chain
-        instead of ignoring them.
-
-        * kjs/JSArray.cpp: Removed getItem.
-        * kjs/JSArray.h: Ditto.
-
-2008-06-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Cameron.
-
-        - https://bugs.webkit.org/show_bug.cgi?id=19804
-          optimize access to arrays without "holes"
-
-        SunSpider says 1.8% faster.
-
-        * kjs/JSArray.cpp:
-        (KJS::JSArray::JSArray): Initialize m_fastAccessCutoff when creating
-        arrays. Also updated for new location of m_vectorLength.
-        (KJS::JSArray::getItem): Updated for new location of m_vectorLength.
-        (KJS::JSArray::getSlowCase): Added. Broke out the non-hot parts of
-        getOwnPropertySlot to make the hot part faster.
-        (KJS::JSArray::getOwnPropertySlot): Added a new faster case for
-        indices lower than m_fastAccessCutoff. We can do theese with no
-        additional checks or branches.
-        (KJS::JSArray::put): Added a new faster case for indices lower than
-        m_fastAccessCutoff. We can do theese with no additional checks or
-        branches. Moved the maxArrayIndex handling out of this function.
-        Added code to set m_fastAccessCutoff when the very last hole in
-        an array is filled; this is how the cutoff gets set for most arrays.
-        (KJS::JSArray::putSlowCase): Moved the rest of the put function logic
-        in here, to make the hot part of the put function faster.
-        (KJS::JSArray::deleteProperty): Added code to lower m_fastAccessCutoff
-        when a delete makes a new hole in the array.
-        (KJS::JSArray::getPropertyNames): Updated for new location of
-        m_vectorLength.
-        (KJS::JSArray::increaseVectorLength): Ditto.
-        (KJS::JSArray::setLength): Added code to lower m_fastAccessCutoff
-        when setLength makes the array smaller.
-        (KJS::JSArray::mark): Updated for new location of m_vectorLength.
-        (KJS::JSArray::sort): Ditto. Set m_fastAccessCutoff after moving
-        all the holes to the end of the array.
-        (KJS::JSArray::compactForSorting): Ditto.
-        (KJS::JSArray::checkConsistency): Added consistency checks fro
-        m_fastAccessCutoff and updated for the new location of m_vectorLength.
-
-        * kjs/JSArray.h: Added declarations for slow case functions.
-        Replaced m_vectorLength with m_fastAccessCutoff.
-
-2008-06-28  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Sam.
-
-        When executing a native call, check for an exception before writing the
-        return value.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-06-28  Mark Rowe  <mrowe@apple.com>
-
-        Build fix.  Flag headers as private or public as is appropriate.
-        These settings were accidentally removed during some project file cleanup.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-06-28  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Darin Adler.
-
-        Splits RegExpConstructor and RegExpPrototype out of RegExpObject.h/cpp
-
-        * DerivedSources.make:
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * VM/Machine.cpp:
-        * kjs/AllInOneFile.cpp:
-        * kjs/JSGlobalObject.cpp:
-        * kjs/RegExpConstructor.cpp: Copied from kjs/RegExpObject.cpp.
-        * kjs/RegExpConstructor.h: Copied from kjs/RegExpObject.h.
-        * kjs/RegExpObject.cpp:
-        * kjs/RegExpObject.h:
-        * kjs/RegExpPrototype.cpp: Copied from kjs/RegExpObject.cpp.
-        * kjs/RegExpPrototype.h: Copied from kjs/RegExpObject.h.
-        * kjs/StringPrototype.cpp:
-        * kjs/internal.cpp:
-
-2008-06-28  Sam Weinig  <sam@webkit.org>
-
-        Fix non-AllInOne builds.
-
-        * kjs/StringConstructor.cpp:
-
-2008-06-28  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Darin Adler.
-
-        Rename string_object.h/cpp to StringObject.h/cpp and split out StringObjectThatMasqueradesAsUndefined,
-        StringConstructor and StringPrototype.
-
-        * DerivedSources.make:
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * kjs/AllInOneFile.cpp:
-        * kjs/JSGlobalObject.cpp:
-        * kjs/StringConstructor.cpp: Copied from JavaScriptCore/kjs/string_object.cpp.
-        * kjs/StringConstructor.h: Copied from JavaScriptCore/kjs/string_object.h.
-        * kjs/StringObject.cpp: Copied from JavaScriptCore/kjs/string_object.cpp.
-        * kjs/StringObject.h: Copied from JavaScriptCore/kjs/string_object.h.
-        * kjs/StringObjectThatMasqueradesAsUndefined.h: Copied from JavaScriptCore/kjs/string_object.h.
-        * kjs/StringPrototype.cpp: Copied from JavaScriptCore/kjs/string_object.cpp.
-        * kjs/StringPrototype.h: Copied from JavaScriptCore/kjs/string_object.h.
-        * kjs/internal.cpp:
-        * kjs/string_object.cpp: Removed.
-        * kjs/string_object.h: Removed.
-
-2008-06-28  Jan Michael Alonzo  <jmalonzo@webkit.org>
-
-        Gtk build fix: JSVariableObject is now part of AllInOne
-
-        * GNUmakefile.am:
-
-2008-06-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - https://bugs.webkit.org/show_bug.cgi?id=19801
-          add a feature so we can tell what regular expressions are taking time
-
-        * pcre/pcre_compile.cpp:
-        (jsRegExpCompile): Compile in the string if REGEXP_HISTOGRAM is on.
-
-        * pcre/pcre_exec.cpp:
-        (jsRegExpExecute): Add hook to time execution.
-        (Histogram::~Histogram): Print a sorted list of what took time.
-        (Histogram::add): Accumulate records of what took time.
-        (HistogramTimeLogger::~HistogramTimeLogger): Hook that calls
-        Histogram::add at the right moment and creates the global histogram
-        object.
-
-        * pcre/pcre_internal.h: Define REGEXP_HISTOGRAM.
-
-        * pcre/pcre_tables.cpp: Added missing include of "config.h". Not needed
-        any more, but an omissions an earlier version of this patch detected.
-        * pcre/pcre_ucp_searchfuncs.cpp: Ditto.
-        * pcre/pcre_xclass.cpp: Ditto.
-
-2008-06-28  Sam Weinig  <sam@webkit.org>
-
-        Try and fix the Windows build again.
-
-        * kjs/RegExpObject.cpp:
-        * kjs/date_object.cpp:
-        * kjs/error_object.cpp:
-
-2008-06-28  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Darin Adler.
-
-        Remove unused StringConstructorFunction class.
-
-        * kjs/string_object.h:
-
-2008-06-28  Sam Weinig  <sam@webkit.org>
-
-        Fix windows build.
-
-        * kjs/ArrayPrototype.cpp:
-        * kjs/BooleanPrototype.cpp:
-        * kjs/BooleanPrototype.h:
-        * kjs/FunctionPrototype.cpp:
-        * kjs/JSImmediate.cpp:
-        * kjs/JSObject.cpp:
-        * kjs/MathObject.cpp:
-        * kjs/NumberPrototype.cpp:
-        * kjs/NumberPrototype.h:
-        * kjs/ObjectConstructor.cpp:
-        * kjs/RegExpObject.h:
-        * kjs/error_object.h:
-        * kjs/string_object.cpp:
-
-2008-06-28  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Oliver Hunt.
-
-        Splits FunctionConstructor out of FunctionPrototype.h/cpp
-        Splits NumberConstructor and NumberPrototype out of NumberObject.h/cpp
-        Rename object_object.h/cpp to ObjectPrototype.h/cpp and split out ObjectConstructor.
-
-        * API/JSCallbackConstructor.cpp:
-        * API/JSClassRef.cpp:
-        * API/JSObjectRef.cpp:
-        * DerivedSources.make:
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * VM/Machine.cpp:
-        * kjs/AllInOneFile.cpp:
-        * kjs/ArrayConstructor.cpp:
-        * kjs/ArrayConstructor.h:
-        * kjs/FunctionConstructor.cpp: Copied from JavaScriptCore/kjs/FunctionPrototype.cpp.
-        * kjs/FunctionConstructor.h: Copied from JavaScriptCore/kjs/FunctionPrototype.h.
-        * kjs/FunctionPrototype.cpp:
-        * kjs/FunctionPrototype.h:
-        * kjs/JSFunction.cpp:
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSImmediate.cpp:
-        * kjs/MathObject.h:
-        * kjs/NumberConstructor.cpp: Copied from JavaScriptCore/kjs/NumberObject.cpp.
-        * kjs/NumberConstructor.h: Copied from JavaScriptCore/kjs/NumberObject.h.
-        * kjs/NumberObject.cpp:
-        * kjs/NumberObject.h:
-        * kjs/NumberPrototype.cpp: Copied from JavaScriptCore/kjs/NumberObject.cpp.
-        * kjs/NumberPrototype.h: Copied from JavaScriptCore/kjs/NumberObject.h.
-        * kjs/ObjectConstructor.cpp: Copied from JavaScriptCore/kjs/object_object.cpp.
-        * kjs/ObjectConstructor.h: Copied from JavaScriptCore/kjs/object_object.h.
-        * kjs/ObjectPrototype.cpp: Copied from JavaScriptCore/kjs/object_object.cpp.
-        * kjs/ObjectPrototype.h: Copied from JavaScriptCore/kjs/object_object.h.
-        * kjs/RegExpObject.h:
-        * kjs/Shell.cpp:
-        * kjs/error_object.h:
-        * kjs/internal.cpp:
-        * kjs/nodes.cpp:
-        * kjs/object_object.cpp: Removed.
-        * kjs/object_object.h: Removed.
-        * kjs/string_object.h:
-
-2008-06-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - fix https://bugs.webkit.org/show_bug.cgi?id=19796
-          optimize expressions with ignored results (especially post-increment)
-
-        SunSpider says 0.9% faster.
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::tempDestination): Create a new temporary for
-        ignoredResult() too, just as we would for 0.
-        (KJS::CodeGenerator::finalDestination): Use the temporary if the
-        register passed in is ignoredResult() too, just as we would for 0.
-        (KJS::CodeGenerator::destinationForAssignResult): Return 0 if the
-        passed in register is ignoredResult(), just as we would for 0.
-        (KJS::CodeGenerator::moveToDestinationIfNeeded): Return 0 if the
-        register passed in is ignoredResult(). What matters is that we
-        don't want to emit a move. The return value won't be looked at.
-        (KJS::CodeGenerator::emitNode): Allow ignoredResult() and pass it
-        through to the node's emitCode function.
-
-        * VM/RegisterID.h:
-        (KJS::ignoredResult): Added. Special value to indicate the result of
-        a node will be ignored and need not be put in any register.
-
-        * kjs/nodes.cpp:
-        (KJS::NullNode::emitCode): Do nothing if dst == ignoredResult().
-        (KJS::BooleanNode::emitCode): Ditto.
-        (KJS::NumberNode::emitCode): Ditto.
-        (KJS::StringNode::emitCode): Ditto.
-        (KJS::RegExpNode::emitCode): Ditto.
-        (KJS::ThisNode::emitCode): Ditto.
-        (KJS::ResolveNode::emitCode): Do nothing if dst == ignoredResult() and
-        the identifier resolves to a local variable.
-        (KJS::ObjectLiteralNode::emitCode): Do nothing if dst == ignoredResult()
-        and the object is empty.
-        (KJS::PostIncResolveNode::emitCode): If dst == ignoredResult(), then do
-        nothing for the local constant case, and do a pre-increment in all the
-        other cases.
-        (KJS::PostDecResolveNode::emitCode): Ditto.
-        (KJS::PostIncBracketNode::emitCode): Ditto.
-        (KJS::PostDecBracketNode::emitCode): Ditto.
-        (KJS::PostIncDotNode::emitCode): Ditto.
-        (KJS::PostDecDotNode::emitCode): Ditto.
-        (KJS::DeleteValueNode::emitCode): Pass ignoredResult() when evaluating
-        the expression.
-        (KJS::VoidNode::emitCode): Ditto.
-        (KJS::TypeOfResolveNode::emitCode): If dst == ignoredResult(), do nothing
-        if the identifier resolves to a local variable, and don't bother generating
-        a typeof opcode in the other case.
-        (KJS::TypeOfValueNode::emitCode): Ditto.
-        (KJS::PreIncResolveNode::emitCode): Do nothing if dst == ignoredResult() and
-        the identifier resolves to a local constant.
-        (KJS::PreDecResolveNode::emitCode): Ditto.
-        (KJS::AssignResolveNode::emitCode): Turn ignoredResult() into 0 in a couple
-        places, because we need to put the result into a register so we can assign
-        it. At other sites this is taken care of by functions like finalDestination.
-        (KJS::CommaNode::emitCode): Pass ignoredResult() when evaluating the first
-        expression.
-        (KJS::ForNode::emitCode): Pass ignoredResult() when evaluating the first and
-        third expressions.
-        (KJS::ForInNode::emitCode): Pass ignoredResult() when evaluating the first
-        expression.
-
-2008-06-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - https://bugs.webkit.org/show_bug.cgi?id=19787
-          create most arrays from values in registers rather than with multiple put operations
-
-        SunSpider says 0.8% faster.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump): Added argv and argc parameters to new_array.
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Ditto.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitNewArray): Added.
-        * VM/CodeGenerator.h: Added ElementNode* argument to emitNewArray.
-
-        * kjs/nodes.cpp:
-        (KJS::ArrayNode::emitCode): Pass the ElementNode to emitNewArray so it can be
-        initialized with as many elements as possible. If the array doesn't have any
-        holes in it, that's all that's needed. If there are holes, then emit some separate
-        put operations for the other values in the array and for the length as needed.
-
-        * kjs/nodes.h: Added some accessors to ElementNode so the code generator can
-        iterate through elements and generate code to evaluate them. Now ArrayNode does
-        not need to be a friend. Also took out some unused PlacementNewAdoptType
-        constructors.
-
-2008-06-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        * kjs/nodes.h: Remove obsolete PlacementNewAdopt constructors.
-        We no longer mutate the AST in place.
-
-2008-06-28  Jan Michael Alonzo  <jmalonzo@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Build fix
-
-        * VM/Machine.cpp: include stdio.h for printf
-
-2008-06-27  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Fix platforms that don't use AllInOne.cpp
-
-        * kjs/BooleanConstructor.h:
-        * kjs/BooleanPrototype.h:
-        * kjs/FunctionPrototype.cpp:
-
-2008-06-27  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Oliver Hunt.
-
-        Splits ArrayConstructor out of ArrayPrototype.h/cpp
-        Splits BooleanConstructor and BooleanPrototype out of BooleanObject.h/cpp
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * VM/Machine.cpp:
-        * kjs/AllInOneFile.cpp:
-        * kjs/ArrayConstructor.cpp: Copied from kjs/ArrayPrototype.cpp.
-        * kjs/ArrayConstructor.h: Copied from kjs/ArrayPrototype.h.
-        * kjs/ArrayPrototype.cpp:
-        * kjs/ArrayPrototype.h:
-        * kjs/BooleanConstructor.cpp: Copied from kjs/BooleanObject.cpp.
-        * kjs/BooleanConstructor.h: Copied from kjs/BooleanObject.h.
-        * kjs/BooleanObject.cpp:
-        * kjs/BooleanObject.h:
-        * kjs/BooleanPrototype.cpp: Copied from kjs/BooleanObject.cpp.
-        * kjs/BooleanPrototype.h: Copied from kjs/BooleanObject.h.
-        * kjs/CommonIdentifiers.h:
-        * kjs/FunctionPrototype.cpp:
-        * kjs/JSArray.cpp:
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSImmediate.cpp:
-        * kjs/Shell.cpp:
-        * kjs/internal.cpp:
-        * kjs/nodes.cpp:
-        * kjs/string_object.cpp:
-
-2008-06-27  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Sam.
-
-        Bug 18626: SQUIRRELFISH: support the "slow script" dialog <https://bugs.webkit.org/show_bug.cgi?id=18626>
-        <rdar://problem/5973931> Slow script dialog needs to be reimplemented for squirrelfish
-
-        Adds support for the slow script dialog in squirrelfish.  This requires the addition
-        of three new op codes, op_loop, op_loop_if_true, and op_loop_if_less which have the
-        same behaviour as their simple jump equivalents but have an additional time out check.
-
-        Additional assertions were added to other jump instructions to prevent accidentally
-        creating loops with jump types that do not support time out checks.
-
-        Sunspider does not report a regression, however this appears very sensitive to code
-        layout and hardware, so i would expect up to a 1% regression on other systems.
-
-        Part of this required moving the old timeout logic from JSGlobalObject and into Machine
-        which is the cause of a number of the larger diff blocks.
-
-        * JavaScriptCore.exp:
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitJumpIfTrue):
-        (KJS::CodeGenerator::emitJumpScopes):
-        * VM/ExceptionHelpers.cpp:
-        (KJS::InterruptedExecutionError::isWatchdogException):
-        (KJS::createInterruptedExecutionException):
-        * VM/ExceptionHelpers.h:
-        * VM/LabelID.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::Machine):
-        (KJS::Machine::throwException):
-        (KJS::Machine::resetTimeoutCheck):
-        (KJS::getCurrentTime):
-        (KJS::Machine::checkTimeout):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        (KJS::Machine::setTimeoutTime):
-        (KJS::Machine::startTimeoutCheck):
-        (KJS::Machine::stopTimeoutCheck):
-        (KJS::Machine::initTimeout):
-        * VM/Opcode.cpp:
-        (KJS::):
-        * VM/Opcode.h:
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::init):
-        (KJS::JSGlobalObject::setTimeoutTime):
-        (KJS::JSGlobalObject::startTimeoutCheck):
-        * kjs/JSGlobalObject.h:
-        * kjs/JSObject.h:
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate):
-
-2008-06-27  Jan Michael Alonzo  <jmalonzo@webkit.org>
-
-        Gtk and Qt build fix: Remove RegisterFileStack from the build
-        scripts.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-
-2008-06-27  Adele Peterson  <adele@apple.com>
-
-        Reviewed by Geoff.
-
-        Build fixes. 
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * VM/RegisterFile.h:
-        (KJS::RegisterFile::RegisterFile):
-        * kjs/JSGlobalObject.cpp:
-        * kjs/collector.cpp:
-
-2008-06-27  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        One RegisterFile to rule them all!
-        
-        SunSpider reports a 0.2% speedup.
-
-        This patch removes the RegisterFileStack abstraction and replaces it with
-        a single register file that
-        
-        (a) allocates a fixed storage area, including a fixed area for global
-        vars, so that no operation may cause the register file to reallocate
-        
-        and
-
-        (b) swaps between global storage areas when executing code in different 
-        global objects.
-        
-        This patch also changes the layout of the register file so that all call
-        frames, including call frames for global code, get a header. This is
-        required to support re-entrant global code. It also just makes things simpler.
-        
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addGlobalVar): New function. Differs from addVar in
-        that
-        
-        (a) global vars don't contribute to a CodeBlock's numLocals count, since
-        global storage is fixed and allocated at startup
-        
-        and
-        
-        (b) references to global vars get shifted to elide intermediate stack
-        between "r" and the global storage area.
-        
-        * VM/Machine.cpp:
-        (KJS::Machine::dumpRegisters): Updated this function to match the new
-        register file layout, and added the ability to dump exact identifiers
-        for the different parts of a call frame.
-        
-        (KJS::Machine::unwindCallFrame): Updated this function to match the new
-        register file layout.
-         
-        (KJS::Machine::execute): Updated this function to initialize a call frame
-        header for global code, and to swap global storage areas when switching
-        to execution in a new global object.
-        
-        (KJS::Machine::privateExecute): Got rid of "safeForReentry" and re-reading
-        of registerBase because the register file is always safe for reentry now,
-        and registerBase never changes.
-        
-        * VM/Machine.h: Moved the call frame header enum from Machine to RegisterFile,
-        to resolve a header dependency problem (a good sign that the enum belonged
-        in RegisterFile all along!)
-
-        * VM/RegisterFile.cpp:
-        * VM/RegisterFile.h: Changed RegisterFile to mmap a fixed size register
-        area. This allows us to avoid re-allocting the register file later on.
-        Instead, we rely on the OS to allocate physical pages to the register
-        file as necessary.
-
-        * VM/RegisterFileStack.cpp: Removed. Tada!
-        * VM/RegisterFileStack.h: Removed. Tada!
-
-        * kjs/DebuggerCallFrame.cpp: Updated this class to match the new
-        register file layout, greatly simplifying it in the process.
-
-        * kjs/JSActivation.h:
-        * kjs/JSActivation.cpp: Moved some of this logic up to JSVariableObject,
-        since the global object now needs to be able to tear off its registers
-        just like the activation object.
-
-        * kjs/JSFunction.cpp: No need to fiddle with the register file anymore.
-
-        * kjs/JSGlobalObject.h:
-        * kjs/JSGlobalObject.cpp: Updated JSGlobalObject to support moving its
-        global storage area into and out of the register file.
-
-        * kjs/PropertySlot.cpp: No need to fiddle with the register file anymore.
-
-        * kjs/collector.cpp: Renamed markStackObjectConservatively to
-        markConservatively, since we don't just mark stack objects this way.
-        
-        Also, added code to mark the machine's register file.
-
-        * kjs/config.h: Moved some platforms #defines from here...
-        * wtf/Platform.h: ...to here, to support mmap/VirtualAlloc detection
-        in RegisterFile.h.
-
-2008-06-26  Mark Rowe  <mrowe@apple.com>
-
-        Speculative fix for the Windows build.
-
-        * kjs/JSImmediate.cpp:
-
-2008-06-26  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Darin Adler and Geoff Garen.
-
-        Fix the malloc zone introspection functions so that malloc_zone_statistics does not give
-        bogus output in an application that uses JavaScriptCore.
-
-        * kjs/CollectorHeapIntrospector.cpp:
-        (KJS::CollectorHeapIntrospector::statistics): Return statistics about memory allocated by the collector.
-        * kjs/CollectorHeapIntrospector.h:
-        * wtf/FastMalloc.cpp: Zero out the statistics.  FastMalloc doesn't track this information at present.
-        Returning zero for all values is preferable to returning bogus data.
-
-2008-06-26  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - https://bugs.webkit.org/show_bug.cgi?id=19721
-          speed up JavaScriptCore by not wrapping strings in objects just
-          to call functions on them
-
-        - optimize UString append and the replace function a bit
-
-        SunSpider says 1.8% faster.
-
-        * JavaScriptCore.exp: Updated.
-
-        * VM/JSPropertyNameIterator.cpp: Added include of JSString.h, now needed
-        because jsString returns a JSString*.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Removed the toObject call from native
-        function calls. Also removed code to put the this value into a register.
-
-        * kjs/BooleanObject.cpp:
-        (KJS::booleanProtoFuncToString): Rewrite to handle false and true
-        separately.
-
-        * kjs/FunctionPrototype.cpp:
-        (KJS::constructFunction): Use single-character append rather than building
-        a string for each character.
-        * kjs/JSFunction.cpp:
-        (KJS::globalFuncUnescape): Ditto.
-
-        * kjs/JSImmediate.cpp:
-        (KJS::JSImmediate::prototype): Added. Gets the appropriate prototype for
-        use with an immediate value. To be used instead of toObject when doing a
-        get on an immediate value.
-        * kjs/JSImmediate.h: Added prototype.
-
-        * kjs/JSObject.cpp:
-        (KJS::JSObject::toString): Tweaked formatting.
-
-        * kjs/JSObject.h:
-        (KJS::JSValue::get): Use prototype instead of toObject to avoid creating
-        an object wrapper just to search for properties. This also saves an
-        unnecessary hash table lookup since the object wrappers themselves don't
-        have any properties.
-
-        * kjs/JSString.h: Added toThisString and toThisJSString.
-
-        * kjs/JSValue.cpp:
-        (KJS::JSCell::toThisString): Added.
-        (KJS::JSCell::toThisJSString): Added.
-        (KJS::JSCell::getJSNumber): Added.
-        (KJS::jsString): Changed return type to JSString*.
-        (KJS::jsOwnedString): Ditto.
-
-        * kjs/JSValue.h:
-        (KJS::JSValue::toThisString): Added.
-        (KJS::JSValue::toThisJSString): Added.
-        (KJS::JSValue::getJSNumber): Added.
-
-        * kjs/NumberObject.cpp:
-        (KJS::NumberObject::getJSNumber): Added.
-        (KJS::integer_part_noexp): Append C string directly rather than first
-        turning it into a UString.
-        (KJS::numberProtoFuncToString): Use getJSNumber to check if the value
-        is a number rather than isObject(&NumberObject::info). This works for
-        immediate numbers, number cells, and NumberObject instances.
-        (KJS::numberProtoFuncToLocaleString): Ditto.
-        (KJS::numberProtoFuncValueOf): Ditto.
-        (KJS::numberProtoFuncToFixed): Ditto.
-        (KJS::numberProtoFuncToExponential): Ditto.
-        (KJS::numberProtoFuncToPrecision): Ditto.
-        * kjs/NumberObject.h: Added getJSNumber.
-
-        * kjs/PropertySlot.cpp: Tweaked comment.
-
-        * kjs/internal.cpp:
-        (KJS::JSString::toThisString): Added.
-        (KJS::JSString::toThisJSString): Added.
-        (KJS::JSString::getOwnPropertySlot): Changed code that searches the
-        prototype chain to start with the string prototype and not create a
-        string object.
-        (KJS::JSNumberCell::toThisString): Added.
-        (KJS::JSNumberCell::getJSNumber): Added.
-
-        * kjs/lookup.cpp:
-        (KJS::staticFunctionGetter): Moved here, because there's no point in
-        having a function that's only used for a function pointer be inline.
-        (KJS::setUpStaticFunctionSlot): New function for getStaticFunctionSlot.
-
-        * kjs/lookup.h:
-        (KJS::staticValueGetter): Don't mark this inline. It doesn't make sense
-        to have a function that's only used for a function pointer be inline.
-        (KJS::getStaticFunctionSlot): Changed to get properties from the parent
-        first before doing any handling of functions. This is the fastest way
-        to return the function once the initial setup is done.
-
-        * kjs/string_object.cpp:
-        (KJS::StringObject::getPropertyNames): Call value() instead of getString(),
-        avoiding an unnecessary virtual function call (the call to the type()
-        function in the implementation of the isString() function).
-        (KJS::StringObject::toString): Added.
-        (KJS::StringObject::toThisString): Added.
-        (KJS::StringObject::toThisJSString): Added.
-        (KJS::substituteBackreferences): Rewrote to use a appending algorithm
-        instead of a the old one that tried to replace in place.
-        (KJS::stringProtoFuncReplace): Merged this function and the replace function.
-        Replaced the hand-rolled dynamic arrays for source ranges and replacements
-        with Vector.
-        (KJS::stringProtoFuncToString): Handle JSString as well as StringObject.
-        Removed the separate valueOf implementation, since it can just share this.
-        (KJS::stringProtoFuncCharAt): Use toThisString, which handles JSString as
-        well as StringObject, and is slightly more efficient than the old code too.
-        (KJS::stringProtoFuncCharCodeAt): Ditto.
-        (KJS::stringProtoFuncConcat): Ditto.
-        (KJS::stringProtoFuncIndexOf): Ditto.
-        (KJS::stringProtoFuncLastIndexOf): Ditto.
-        (KJS::stringProtoFuncMatch): Ditto.
-        (KJS::stringProtoFuncSearch): Ditto.
-        (KJS::stringProtoFuncSlice): Ditto.
-        (KJS::stringProtoFuncSplit): Ditto.
-        (KJS::stringProtoFuncSubstr): Ditto.
-        (KJS::stringProtoFuncSubstring): Ditto.
-        (KJS::stringProtoFuncToLowerCase): Use toThisJSString.
-        (KJS::stringProtoFuncToUpperCase): Ditto.
-        (KJS::stringProtoFuncToLocaleLowerCase): Ditto.
-        (KJS::stringProtoFuncToLocaleUpperCase): Ditto.
-        (KJS::stringProtoFuncLocaleCompare): Ditto.
-        (KJS::stringProtoFuncBig): Use toThisString.
-        (KJS::stringProtoFuncSmall): Ditto.
-        (KJS::stringProtoFuncBlink): Ditto.
-        (KJS::stringProtoFuncBold): Ditto.
-        (KJS::stringProtoFuncFixed): Ditto.
-        (KJS::stringProtoFuncItalics): Ditto.
-        (KJS::stringProtoFuncStrike): Ditto.
-        (KJS::stringProtoFuncSub): Ditto.
-        (KJS::stringProtoFuncSup): Ditto.
-        (KJS::stringProtoFuncFontcolor): Ditto.
-        (KJS::stringProtoFuncFontsize): Ditto.
-        (KJS::stringProtoFuncAnchor): Ditto.
-        (KJS::stringProtoFuncLink): Ditto.
-
-        * kjs/string_object.h: Added toString, toThisString, and toThisJSString.
-
-        * kjs/ustring.cpp:
-        (KJS::UString::append): Added a version that takes a character pointer and
-        size, so we don't have to create a UString just to append to another UString.
-        * kjs/ustring.h:
-
-2008-06-26  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Maciej.
-
-        Make JSGlobalData per-thread.
-
-        No change on SunSpider total.
-
-        * wtf/ThreadSpecific.h: Re-enabled the actual implementation.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::~JSGlobalObject): Re-added a JSLock-related assertion. We'll probably
-        want to preserve these somehow to keep legacy behavior in working condition.
-        (KJS::JSGlobalObject::init): Initialize globalData pointer earlier, so that it is ready
-        when updating JSGlobalObject linked list.
-
-        * kjs/JSGlobalObject.h: (KJS::JSGlobalObject::head): Changed head() to be non-static, and
-        to use JSGlobalData associated with the current object.
-
-        * kjs/InitializeThreading.cpp: (KJS::initializeThreadingOnce): Removed a no longer needed
-        Heap::registerAsMainThread() call.
-
-        * kjs/JSGlobalData.h: Removed a lying lie comment - parserObjectExtraRefCounts is not
-        transient, and while newParserObjects may conceptually be such, there is still some node
-        manipulation going on outside Parser::parse which touches it.
-
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::~JSGlobalData): Delete recently added members.
-        (KJS::JSGlobalData::sharedInstance): Actually use a separate instance.
-
-        * kjs/collector.cpp:
-        (KJS::Heap::Heap):
-        (KJS::Heap::~Heap): Added a destructor, which unconditionally deletes everything.
-        (KJS::Heap::sweep): Removed code related to "collect on main thread only" logic.
-        (KJS::Heap::collect): Ditto.
-        (KJS::Heap::globalObjectCount): Explicitly use per-thread instance of JSGlobalObject linked
-        list now that JSGlobalObject::head() is not static. Curently, WebCoreStatistics methods only
-        work with the main thread currently anyway.
-        (KJS::Heap::protectedGlobalObjectCount): Ditto.
-
-        * kjs/collector.h: Removed code related to "collect on main thread only" logic.
-
-        * JavaScriptCore.exp: Removed Heap::collectOnMainThreadOnly.
-
-2008-06-26  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19767
-        REGRESSION: Crash in sort() when visiting http://www.onnyturf.com/subway/
-
-        * kjs/JSArray.cpp: (KJS::AVLTreeAbstractorForArrayCompare::set_balance_factor):
-        Made changing balance factor from -1 to +1 work correctly.
-
-        * wtf/AVLTree.h: (KJS::AVLTreeDefaultBSet::operator[]): Added an assertion that catches
-        this slightly earlier.
-
-2008-06-25  Timothy Hatcher  <timothy@apple.com>
-
-        Fixes an ASSERT in the profiler when starting multiple profiles
-        with the same name inside the same function/program.
-
-        Reviewed by Kevin McCullough.
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::Profile): Initialize m_stoppedCallDepth to zero.
-        (KJS::Profile::stopProfiling): Set the current node to the parent,
-        because we are in a call that will not get a didExecute call.
-        (KJS::Profile::removeProfile): Increment m_stoppedCallDepth to
-        account for didExecute not being called for profile.
-        (KJS::Profile::willExecute): Increment m_stoppedCallDepth if stopped.
-        (KJS::Profile::didExecute): Decrement m_stoppedCallDepth if stopped and
-        greater than zero, and return early.
-        * profiler/Profile.h: Added stoppedProfiling().
-        * profiler/Profiler.cpp:
-        (KJS::Profiler::findProfile): Removed.
-        (KJS::Profiler::startProfiling): Don't return early for stopped profiles.
-        (KJS::Profiler::stopProfiling): Skipp stopped profiles.
-        (KJS::Profiler::didFinishAllExecution): Code clean-up.
-        * profiler/Profiler.h: Removed findProfile.
-
-2008-06-25  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Alexey Proskuryakov.
-
-        Attempt to fix Windows debug build. The compiler gives a warning when
-        Structured Exception Handling and destructors are used in the same
-        function. Using manual locking and unlocking instead of constructors
-        and destructors should fix the warning.
-
-        * kjs/Shell.cpp:
-        (main):
-
-2008-06-25  Alexey Proskuryakov  <ap@webkit.org>
-
-        Forgot to address a review comment about better names for tracked objects, doing it now.
-
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        * kjs/JSGlobalData.h:
-        * kjs/nodes.cpp:
-        (KJS::ParserRefCounted::ParserRefCounted):
-        (KJS::ParserRefCounted::ref):
-        (KJS::ParserRefCounted::deref):
-        (KJS::ParserRefCounted::hasOneRef):
-        (KJS::ParserRefCounted::deleteNewObjects):
-
-2008-06-25  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff.
-
-        Remove more threadInstance() calls.
-
-        * kjs/JSFunction.cpp:
-        (KJS::JSFunction::getParameterName):
-        (KJS::IndexToNameMap::unMap):
-        (KJS::Arguments::deleteProperty):
-        * kjs/JSFunction.h:
-        Access nullIdentifier without going to thread specific storage.
-
-        * JavaScriptCore.exp:
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        * kjs/JSGlobalData.h:
-        * kjs/Parser.cpp:
-        (KJS::Parser::parse):
-        * kjs/Parser.h:
-        (KJS::ParserRefCountedData::ParserRefCountedData):
-        (KJS::Parser::parse):
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::ParserRefCounted::ParserRefCounted):
-        (KJS::ParserRefCounted::ref):
-        (KJS::ParserRefCounted::deref):
-        (KJS::ParserRefCounted::hasOneRef):
-        (KJS::ParserRefCounted::deleteNewObjects):
-        (KJS::Node::Node):
-        (KJS::StatementNode::StatementNode):
-        (KJS::BreakpointCheckStatement::BreakpointCheckStatement):
-        (KJS::ConstDeclNode::ConstDeclNode):
-        (KJS::BlockNode::BlockNode):
-        (KJS::ForInNode::ForInNode):
-        (KJS::ScopeNode::ScopeNode):
-        (KJS::ProgramNode::ProgramNode):
-        (KJS::ProgramNode::create):
-        (KJS::EvalNode::EvalNode):
-        (KJS::EvalNode::create):
-        (KJS::FunctionBodyNode::FunctionBodyNode):
-        (KJS::FunctionBodyNode::create):
-        * kjs/nodes.h:
-        (KJS::ExpressionNode::):
-        (KJS::NullNode::):
-        (KJS::BooleanNode::):
-        (KJS::NumberNode::):
-        (KJS::ImmediateNumberNode::):
-        (KJS::StringNode::):
-        (KJS::RegExpNode::):
-        (KJS::ThisNode::):
-        (KJS::ResolveNode::):
-        (KJS::ElementNode::):
-        (KJS::ArrayNode::):
-        (KJS::PropertyNode::):
-        (KJS::PropertyListNode::):
-        (KJS::ObjectLiteralNode::):
-        (KJS::BracketAccessorNode::):
-        (KJS::DotAccessorNode::):
-        (KJS::ArgumentListNode::):
-        (KJS::ArgumentsNode::):
-        (KJS::NewExprNode::):
-        (KJS::EvalFunctionCallNode::):
-        (KJS::FunctionCallValueNode::):
-        (KJS::FunctionCallResolveNode::):
-        (KJS::FunctionCallBracketNode::):
-        (KJS::FunctionCallDotNode::):
-        (KJS::PrePostResolveNode::):
-        (KJS::PostIncResolveNode::):
-        (KJS::PostDecResolveNode::):
-        (KJS::PostfixBracketNode::):
-        (KJS::PostIncBracketNode::):
-        (KJS::PostDecBracketNode::):
-        (KJS::PostfixDotNode::):
-        (KJS::PostIncDotNode::):
-        (KJS::PostDecDotNode::):
-        (KJS::PostfixErrorNode::):
-        (KJS::DeleteResolveNode::):
-        (KJS::DeleteBracketNode::):
-        (KJS::DeleteDotNode::):
-        (KJS::DeleteValueNode::):
-        (KJS::VoidNode::):
-        (KJS::TypeOfResolveNode::):
-        (KJS::TypeOfValueNode::):
-        (KJS::PreIncResolveNode::):
-        (KJS::PreDecResolveNode::):
-        (KJS::PrefixBracketNode::):
-        (KJS::PreIncBracketNode::):
-        (KJS::PreDecBracketNode::):
-        (KJS::PrefixDotNode::):
-        (KJS::PreIncDotNode::):
-        (KJS::PreDecDotNode::):
-        (KJS::PrefixErrorNode::):
-        (KJS::UnaryOpNode::UnaryOpNode):
-        (KJS::UnaryPlusNode::):
-        (KJS::NegateNode::):
-        (KJS::BitwiseNotNode::):
-        (KJS::LogicalNotNode::):
-        (KJS::BinaryOpNode::BinaryOpNode):
-        (KJS::ReverseBinaryOpNode::ReverseBinaryOpNode):
-        (KJS::MultNode::):
-        (KJS::DivNode::):
-        (KJS::ModNode::):
-        (KJS::AddNode::):
-        (KJS::SubNode::):
-        (KJS::LeftShiftNode::):
-        (KJS::RightShiftNode::):
-        (KJS::UnsignedRightShiftNode::):
-        (KJS::LessNode::):
-        (KJS::GreaterNode::):
-        (KJS::LessEqNode::):
-        (KJS::GreaterEqNode::):
-        (KJS::InstanceOfNode::):
-        (KJS::InNode::):
-        (KJS::EqualNode::):
-        (KJS::NotEqualNode::):
-        (KJS::StrictEqualNode::):
-        (KJS::NotStrictEqualNode::):
-        (KJS::BitAndNode::):
-        (KJS::BitOrNode::):
-        (KJS::BitXOrNode::):
-        (KJS::LogicalAndNode::):
-        (KJS::LogicalOrNode::):
-        (KJS::ConditionalNode::):
-        (KJS::ReadModifyResolveNode::):
-        (KJS::AssignResolveNode::):
-        (KJS::ReadModifyBracketNode::):
-        (KJS::AssignBracketNode::):
-        (KJS::AssignDotNode::):
-        (KJS::ReadModifyDotNode::):
-        (KJS::AssignErrorNode::):
-        (KJS::CommaNode::):
-        (KJS::VarDeclCommaNode::):
-        (KJS::ConstStatementNode::):
-        (KJS::SourceElements::SourceElements):
-        (KJS::EmptyStatementNode::):
-        (KJS::DebuggerStatementNode::):
-        (KJS::ExprStatementNode::):
-        (KJS::VarStatementNode::):
-        (KJS::IfNode::):
-        (KJS::IfElseNode::):
-        (KJS::DoWhileNode::):
-        (KJS::WhileNode::):
-        (KJS::ForNode::):
-        (KJS::ContinueNode::):
-        (KJS::BreakNode::):
-        (KJS::ReturnNode::):
-        (KJS::WithNode::):
-        (KJS::LabelNode::):
-        (KJS::ThrowNode::):
-        (KJS::TryNode::):
-        (KJS::ParameterNode::):
-        (KJS::FuncExprNode::):
-        (KJS::FuncDeclNode::):
-        (KJS::CaseClauseNode::):
-        (KJS::ClauseListNode::):
-        (KJS::CaseBlockNode::):
-        (KJS::SwitchNode::):
-        Changed ParserRefCounted to hold a JSGlobalData pointer, and used it to replace
-        threadInstance calls.
-
-2008-06-24  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Alexey Proskuryakov.
-
-        Make the JavaScript shell collect the heap from main() instead of
-        jscmain() to suppress leak messages in debug builds.
-
-        * kjs/Shell.cpp:
-        (main):
-        (jscmain):
-
-2008-06-24  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Make the conversion of the pair (less, jtrue) to jless use register
-        reference counting information for safety instead of requiring callers
-        to decide whether it is safe.
-
-        No changes on SunSpider codegen.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitJumpIfTrue):
-        * VM/CodeGenerator.h:
-        * kjs/nodes.cpp:
-        (KJS::DoWhileNode::emitCode):
-        (KJS::WhileNode::emitCode):
-        (KJS::ForNode::emitCode):
-        (KJS::CaseBlockNode::emitCodeForBlock):
-
-2008-06-24  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/6031594> JSProfiler: Profiler goes into an infinite
-        loop sometimes.
-        <rdar://problem/6031603> JSProfiler: Profiler asserts in debug and
-        give the wrong times in release
-
-        Fixed two issues found by Tim in the same test.
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::removeProfileStart): No longer take profile's time from
-        all ancestors, but instead attribute it to its parent.  Also add an
-        Assert to ensure we only delete the child we mean to.
-        (KJS::Profile::removeProfileEnd): Ditto for profileEnd.
-        (KJS::Profile::didExecute): Cleaned up the execution order and correctly
-        attribute all of the parent's time to the new node.
-        * profiler/ProfileNode.cpp: If this node does not have a startTime it
-        should not get a giant total time, but instead be 0.
-        (KJS::ProfileNode::endAndRecordCall):
-        * profiler/ProfileNode.h:
-        (KJS::ProfileNode::removeChild): Should reset the sibling pointers since
-        one of them has been removed.
-
-2008-06-24  Darin Adler  <darin@apple.com>
-
-        Reviewed by Cameron.
-
-        - fix https://bugs.webkit.org/show_bug.cgi?id=19739
-          REGRESSION: fast/js/property-getters-and-setters.html fails
-
-        * kjs/JSObject.cpp:
-        (KJS::JSObject::put): Remove an untested optimization I checked in by accident.
-        The two loops up the prototype chain both need to start from this; instead the
-        second loop was starting where the first loop left off.
-
-2008-06-24  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-
-        * kjs/nodes.cpp:
-
-2008-06-24  Joerg Bornemann  <joerg.bornemann@trolltech.com>
-
-        Reviewed by Simon.
-
-        For the Qt build on Windows don't depend on the presence of GNU CPP
-        but use MSVC's preprocessor instead.
-        dftables accepts a --preprocessor option which is set in pcre.pri for MSVC platforms.
-
-        * pcre/dftables: Added support for specifying the preprocessor command
-        to use via --preprocessor, similar to
-        WebCore/bindings/scripts/generate-bindings.pl.
-        * pcre/pcre.pri: Pass --preprocessor='cl /e' to dftables, or more
-        generally speaking QMAKE_CC /E for the win32-msvc buildspecs.
-
-2008-06-24  Simon Hausmann  <hausmann@webkit.org>
-
-        Fix the Qt build, added missing include.
-
-        * kjs/PropertySlot.cpp:
-
-2008-06-24  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Cameron Zwarich.
-
-        Make ParserRefCountedCounter actually perform a leak check.
-
-        * kjs/nodes.cpp:
-        (KJS::ParserRefCountedCounter::~ParserRefCountedCounter): Check for leaks in destructor,
-        not in constructor.
-        (KJS::ParserRefCountedCounter::increment):
-        (KJS::ParserRefCountedCounter::decrement):
-        (KJS::ParserRefCounted::ParserRefCounted):
-        (KJS::ParserRefCounted::~ParserRefCounted):
-        While at it, also made counting thread-safe.
-
-2008-06-24  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 19730: REGRESSION (r34497): Text in alerts in "Leisure suit Larry" is not wrapped
-        <https://bugs.webkit.org/show_bug.cgi?id=19730>
-
-        Do not convert the pair (less, jtrue) to jless when jtrue is a jump
-        target. An example of this is when the condition of a while loop is a
-        LogicalOrNode.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitLabel):
-
-2008-06-20  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Reviewed by Adam Roben.
-
-        Fix compile with MinGW.
-
-        * kjs/Shell.cpp:
-        * wtf/Threading.h:
-        (WTF::atomicIncrement):
-        (WTF::atomicDecrement):
-
-2008-06-23  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Prepration for returning memory to the OS on Windows.  Track whether a portion of a span of memory was returned to the OS.
-        If it was, ask that it be recommitted before returning it to the application as an allocated region.
-
-        * wtf/FastMalloc.cpp:
-        (WTF::TCMalloc_PageHeap::New):  If the span was decommitted, ask that it be recommitted before returning it.
-        (WTF::TCMalloc_PageHeap::AllocLarge):  Ditto.
-        (WTF::TCMalloc_PageHeap::Carve):  When splitting a span, ensure that the decommitted state propogates to the two new spans.
-        (WTF::TCMalloc_PageHeap::Delete):  When merging a span, ensure that the resulting span is marked as decommitted if any of the
-        spans being merged were marked as decommitted.
-        (WTF::TCMalloc_PageHeap::IncrementalScavenge):  Mark as decommitted after releasing the span.
-        (WTF::TCMalloc_Central_FreeList::FetchFromSpans): Add an assertion to catch a decommitted span being returned to the application
-        without first being recommitted.
-        (WTF::TCMalloc_Central_FreeList::Populate): Ditto.
-        * wtf/TCSystemAlloc.cpp: Stub out TCMalloc_SystemCommit.
-        * wtf/TCSystemAlloc.h:
-
-2008-06-23  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Remove the sample member of Span when NO_TCMALLOC_SAMPLES is defined.
-
-        * wtf/FastMalloc.cpp:
-        (WTF::TCMalloc_PageHeap::Delete): Only update Span::sample if NO_TCMALLOC_SAMPLES is not defined.
-        (WTF::TCMallocStats::do_free):  Ditto.
-
-2008-06-23  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - work toward https://bugs.webkit.org/show_bug.cgi?id=19721
-
-        More preparation toward making functions work on primitive types without
-        creating wrapper objects. No speedup this time, but prepares for a future
-        speedup without slowing things down.
-
-        SunSpider reports no change.
-
-        - Eliminated the implementsCall, callAsFunction and construct virtual
-          functions from JSObject. Instead, the CallData and ConstructData for
-          a native function includes a function pointer that the caller can use
-          directly. Changed all call sites to use CallData and ConstructData.
-
-        - Changed the "this" argument to native functions to be a JSValue rather
-          than a JSObject. This prepares us for passing primitives into these
-          functions. The conversion to an object now must be done inside the
-          function. Critically, if it's a function that can be called on a DOM
-          window object, then we have to be sure to call toThisObject on the
-          argument before we use it for anything even if it's already an object.
-
-        - Eliminated the practice of using constructor objects in the global
-          object to make objects of the various basic types. Since these
-          constructors can't be replaced by script, there's no reason to involve
-          a constructor object at all. Added functions to do the construction
-          directly.
-
-        - Made some more class members private and protected, including virtual
-          function overrides. This can catch code using unnecessarily slow virtual
-          function code paths when the type of an object is known statically. If we
-          later find a new reason use the members outside the class it's easy to
-          make them public again.
-
-        - Moved the declarations of the native implementations for functions out
-          of header files. These can have internal linkage and be declared inside
-          the source file.
-
-        - Changed PrototypeFunction to take function pointers with the right
-          arguments to be put directly into CallData. This eliminates the
-          need to have a separate PrototypeReflexiveFunction, and reveals that the
-          real purpose of that class included something else specific to eval --
-          storage of a cached global object. So renamed PrototypeReflexiveFunction
-          to GlobalEvalFunction.
-
-        * API/JSCallbackConstructor.cpp:
-        (KJS::constructJSCallback):
-        (KJS::JSCallbackConstructor::getConstructData):
-        * API/JSCallbackConstructor.h:
-        * API/JSCallbackFunction.cpp:
-        (KJS::JSCallbackFunction::implementsHasInstance):
-        (KJS::JSCallbackFunction::call):
-        (KJS::JSCallbackFunction::getCallData):
-        * API/JSCallbackFunction.h:
-        (KJS::JSCallbackFunction::classInfo):
-        * API/JSCallbackObject.h:
-        (KJS::JSCallbackObject::classRef):
-        (KJS::JSCallbackObject::classInfo):
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::getConstructData):
-        (KJS::::construct):
-        (KJS::::getCallData):
-        (KJS::::call):
-        * API/JSObjectRef.cpp:
-        (JSObjectMakeFunction):
-        (JSObjectIsFunction):
-        (JSObjectCallAsFunction):
-        (JSObjectCallAsConstructor):
-        * JavaScriptCore.exp:
-        * VM/Machine.cpp:
-        (KJS::jsTypeStringForValue):
-        (KJS::Machine::privateExecute):
-        * kjs/ArrayPrototype.cpp:
-        (KJS::arrayProtoFuncToString):
-        (KJS::arrayProtoFuncToLocaleString):
-        (KJS::arrayProtoFuncJoin):
-        (KJS::arrayProtoFuncConcat):
-        (KJS::arrayProtoFuncPop):
-        (KJS::arrayProtoFuncPush):
-        (KJS::arrayProtoFuncReverse):
-        (KJS::arrayProtoFuncShift):
-        (KJS::arrayProtoFuncSlice):
-        (KJS::arrayProtoFuncSort):
-        (KJS::arrayProtoFuncSplice):
-        (KJS::arrayProtoFuncUnShift):
-        (KJS::arrayProtoFuncFilter):
-        (KJS::arrayProtoFuncMap):
-        (KJS::arrayProtoFuncEvery):
-        (KJS::arrayProtoFuncForEach):
-        (KJS::arrayProtoFuncSome):
-        (KJS::arrayProtoFuncIndexOf):
-        (KJS::arrayProtoFuncLastIndexOf):
-        (KJS::ArrayConstructor::ArrayConstructor):
-        (KJS::constructArrayWithSizeQuirk):
-        (KJS::constructWithArrayConstructor):
-        (KJS::ArrayConstructor::getConstructData):
-        (KJS::callArrayConstructor):
-        (KJS::ArrayConstructor::getCallData):
-        * kjs/ArrayPrototype.h:
-        * kjs/BooleanObject.cpp:
-        (KJS::booleanProtoFuncToString):
-        (KJS::booleanProtoFuncValueOf):
-        (KJS::constructBoolean):
-        (KJS::constructWithBooleanConstructor):
-        (KJS::BooleanConstructor::getConstructData):
-        (KJS::callBooleanConstructor):
-        (KJS::BooleanConstructor::getCallData):
-        (KJS::constructBooleanFromImmediateBoolean):
-        * kjs/BooleanObject.h:
-        * kjs/CallData.h:
-        (KJS::):
-        * kjs/ConstructData.h:
-        (KJS::):
-        * kjs/FunctionPrototype.cpp:
-        (KJS::callFunctionPrototype):
-        (KJS::FunctionPrototype::getCallData):
-        (KJS::functionProtoFuncToString):
-        (KJS::functionProtoFuncApply):
-        (KJS::functionProtoFuncCall):
-        (KJS::constructWithFunctionConstructor):
-        (KJS::FunctionConstructor::getConstructData):
-        (KJS::callFunctionConstructor):
-        (KJS::FunctionConstructor::getCallData):
-        (KJS::constructFunction):
-        * kjs/FunctionPrototype.h:
-        * kjs/JSArray.cpp:
-        (KJS::AVLTreeAbstractorForArrayCompare::compare_key_key):
-        (KJS::JSArray::sort):
-        (KJS::constructEmptyArray):
-        (KJS::constructArray):
-        * kjs/JSArray.h:
-        (KJS::JSArray::classInfo):
-        * kjs/JSFunction.cpp:
-        (KJS::JSFunction::call):
-        (KJS::globalFuncEval):
-        (KJS::globalFuncParseInt):
-        (KJS::globalFuncParseFloat):
-        (KJS::globalFuncIsNaN):
-        (KJS::globalFuncIsFinite):
-        (KJS::globalFuncDecodeURI):
-        (KJS::globalFuncDecodeURIComponent):
-        (KJS::globalFuncEncodeURI):
-        (KJS::globalFuncEncodeURIComponent):
-        (KJS::globalFuncEscape):
-        (KJS::globalFuncUnescape):
-        (KJS::globalFuncKJSPrint):
-        (KJS::PrototypeFunction::PrototypeFunction):
-        (KJS::PrototypeFunction::getCallData):
-        (KJS::GlobalEvalFunction::GlobalEvalFunction):
-        (KJS::GlobalEvalFunction::mark):
-        * kjs/JSFunction.h:
-        (KJS::InternalFunction::classInfo):
-        (KJS::InternalFunction::functionName):
-        (KJS::JSFunction::classInfo):
-        (KJS::GlobalEvalFunction::cachedGlobalObject):
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset):
-        (KJS::JSGlobalObject::mark):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::JSGlobalObject):
-        (KJS::JSGlobalObject::evalFunction):
-        * kjs/JSImmediate.cpp:
-        (KJS::JSImmediate::toObject):
-        * kjs/JSNotAnObject.cpp:
-        * kjs/JSNotAnObject.h:
-        * kjs/JSObject.cpp:
-        (KJS::JSObject::put):
-        (KJS::callDefaultValueFunction):
-        (KJS::JSObject::defaultValue):
-        (KJS::JSObject::lookupGetter):
-        (KJS::JSObject::lookupSetter):
-        (KJS::JSObject::hasInstance):
-        (KJS::JSObject::fillGetterPropertySlot):
-        (KJS::Error::create):
-        (KJS::constructEmptyObject):
-        * kjs/JSObject.h:
-        (KJS::GetterSetter::GetterSetter):
-        (KJS::GetterSetter::getter):
-        (KJS::GetterSetter::setGetter):
-        (KJS::GetterSetter::setter):
-        (KJS::GetterSetter::setSetter):
-        * kjs/JSValue.cpp:
-        (KJS::JSCell::deleteProperty):
-        (KJS::call):
-        (KJS::construct):
-        * kjs/JSValue.h:
-        * kjs/MathObject.cpp:
-        (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/MathObject.h:
-        * kjs/NumberObject.cpp:
-        (KJS::numberProtoFuncToString):
-        (KJS::numberProtoFuncToLocaleString):
-        (KJS::numberProtoFuncValueOf):
-        (KJS::numberProtoFuncToFixed):
-        (KJS::numberProtoFuncToExponential):
-        (KJS::numberProtoFuncToPrecision):
-        (KJS::NumberConstructor::NumberConstructor):
-        (KJS::constructWithNumberConstructor):
-        (KJS::NumberConstructor::getConstructData):
-        (KJS::callNumberConstructor):
-        (KJS::NumberConstructor::getCallData):
-        (KJS::constructNumber):
-        (KJS::constructNumberFromImmediateNumber):
-        * kjs/NumberObject.h:
-        (KJS::NumberObject::classInfo):
-        (KJS::NumberConstructor::classInfo):
-        * kjs/PropertySlot.cpp:
-        (KJS::PropertySlot::functionGetter):
-        * kjs/RegExpObject.cpp:
-        (KJS::regExpProtoFuncTest):
-        (KJS::regExpProtoFuncExec):
-        (KJS::regExpProtoFuncCompile):
-        (KJS::regExpProtoFuncToString):
-        (KJS::callRegExpObject):
-        (KJS::RegExpObject::getCallData):
-        (KJS::constructRegExp):
-        (KJS::constructWithRegExpConstructor):
-        (KJS::RegExpConstructor::getConstructData):
-        (KJS::callRegExpConstructor):
-        (KJS::RegExpConstructor::getCallData):
-        * kjs/RegExpObject.h:
-        (KJS::RegExpConstructor::classInfo):
-        * kjs/Shell.cpp:
-        (GlobalObject::GlobalObject):
-        (functionPrint):
-        (functionDebug):
-        (functionGC):
-        (functionVersion):
-        (functionRun):
-        (functionLoad):
-        (functionReadline):
-        (functionQuit):
-        * kjs/date_object.cpp:
-        (KJS::gmtoffset):
-        (KJS::formatLocaleDate):
-        (KJS::fillStructuresUsingDateArgs):
-        (KJS::DateInstance::getTime):
-        (KJS::DateInstance::getUTCTime):
-        (KJS::DateConstructor::DateConstructor):
-        (KJS::constructDate):
-        (KJS::DateConstructor::getConstructData):
-        (KJS::callDate):
-        (KJS::DateConstructor::getCallData):
-        (KJS::dateParse):
-        (KJS::dateNow):
-        (KJS::dateUTC):
-        (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::dateProtoFuncSetMilliSeconds):
-        (KJS::dateProtoFuncSetUTCMilliseconds):
-        (KJS::dateProtoFuncSetSeconds):
-        (KJS::dateProtoFuncSetUTCSeconds):
-        (KJS::dateProtoFuncSetMinutes):
-        (KJS::dateProtoFuncSetUTCMinutes):
-        (KJS::dateProtoFuncSetHours):
-        (KJS::dateProtoFuncSetUTCHours):
-        (KJS::dateProtoFuncSetDate):
-        (KJS::dateProtoFuncSetUTCDate):
-        (KJS::dateProtoFuncSetMonth):
-        (KJS::dateProtoFuncSetUTCMonth):
-        (KJS::dateProtoFuncSetFullYear):
-        (KJS::dateProtoFuncSetUTCFullYear):
-        (KJS::dateProtoFuncSetYear):
-        (KJS::dateProtoFuncGetYear):
-        * kjs/date_object.h:
-        (KJS::DateInstance::internalNumber):
-        (KJS::DateInstance::classInfo):
-        * kjs/error_object.cpp:
-        (KJS::errorProtoFuncToString):
-        (KJS::constructError):
-        (KJS::constructWithErrorConstructor):
-        (KJS::ErrorConstructor::getConstructData):
-        (KJS::callErrorConstructor):
-        (KJS::ErrorConstructor::getCallData):
-        (KJS::NativeErrorConstructor::construct):
-        (KJS::constructWithNativeErrorConstructor):
-        (KJS::NativeErrorConstructor::getConstructData):
-        (KJS::callNativeErrorConstructor):
-        (KJS::NativeErrorConstructor::getCallData):
-        * kjs/error_object.h:
-        (KJS::NativeErrorConstructor::classInfo):
-        * kjs/internal.cpp:
-        (KJS::JSNumberCell::toObject):
-        (KJS::JSNumberCell::toThisObject):
-        (KJS::GetterSetter::mark):
-        (KJS::GetterSetter::toPrimitive):
-        (KJS::GetterSetter::toBoolean):
-        (KJS::GetterSetter::toNumber):
-        (KJS::GetterSetter::toString):
-        (KJS::GetterSetter::toObject):
-        (KJS::InternalFunction::InternalFunction):
-        (KJS::InternalFunction::implementsHasInstance):
-        * kjs/lookup.h:
-        (KJS::HashEntry::):
-        * kjs/nodes.cpp:
-        (KJS::FuncDeclNode::makeFunction):
-        (KJS::FuncExprNode::makeFunction):
-        * kjs/object_object.cpp:
-        (KJS::objectProtoFuncValueOf):
-        (KJS::objectProtoFuncHasOwnProperty):
-        (KJS::objectProtoFuncIsPrototypeOf):
-        (KJS::objectProtoFuncDefineGetter):
-        (KJS::objectProtoFuncDefineSetter):
-        (KJS::objectProtoFuncLookupGetter):
-        (KJS::objectProtoFuncLookupSetter):
-        (KJS::objectProtoFuncPropertyIsEnumerable):
-        (KJS::objectProtoFuncToLocaleString):
-        (KJS::objectProtoFuncToString):
-        (KJS::ObjectConstructor::ObjectConstructor):
-        (KJS::constructObject):
-        (KJS::constructWithObjectConstructor):
-        (KJS::ObjectConstructor::getConstructData):
-        (KJS::callObjectConstructor):
-        (KJS::ObjectConstructor::getCallData):
-        * kjs/object_object.h:
-        * kjs/string_object.cpp:
-        (KJS::replace):
-        (KJS::stringProtoFuncToString):
-        (KJS::stringProtoFuncValueOf):
-        (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::stringFromCharCode):
-        (KJS::StringConstructor::StringConstructor):
-        (KJS::constructWithStringConstructor):
-        (KJS::StringConstructor::getConstructData):
-        (KJS::callStringConstructor):
-        (KJS::StringConstructor::getCallData):
-        * kjs/string_object.h:
-
-2008-06-23  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 19716: REGRESSION (SquirrelFish): Reproducible crash after entering a username at mint.com
-        <https://bugs.webkit.org/show_bug.cgi?id=19716>
-
-        When unwinding callframes for exceptions, check whether the callframe
-        was created by a reentrant native call to JavaScript after tearing off
-        the local variables instead of before.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::unwindCallFrame):
-
-2008-06-23  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Get testapi passing again in a debug build.
-
-        * API/testapi.c:
-        (main): Update the expected output of calling JSValueMakeString on a function object.
-
-2008-06-21  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Print a blank line when exiting the jsc interactive mode to ensure that the shell
-        prompt will start on a new line.
-
-        * kjs/Shell.cpp:
-        (runInteractive):
-
-2008-06-21  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Sam Weinig.
-
-        Tweak the paths of the items in the "tests" group to clean things up a little.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-06-21  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Sam Weinig.
-
-        Fix jsc to link against libedit.dylib rather than libedit.2.dylib.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-06-21  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Copy the JavaScriptCore shell (jsc) into JavaScriptCore.framework so that it will
-        be included in nightly builds.
-        https://bugs.webkit.org/show_bug.cgi?id=19691
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-06-21  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Mark Rowe.
-
-        Fix the build for non-Mac Darwin platforms by disabling their support
-        for readline in the JavaScript shell.
-
-        * kjs/config.h:
-
-2008-06-20  Timothy Hatcher  <timothy@apple.com>
-
-        Use member function pointers for the Profile::forEach function.
-        Eliminating a few static functions and simplified things a little.
-
-        Reviewed by Alexey Proskuryakov.
-
-        * JavaScriptCore.exp: Change the symbol for forEach.
-        * profiler/Profile.cpp:
-        (KJS::Profile::forEach): Use a member function pointer.
-        * profiler/Profile.h:
-        (KJS::Profile::sortTotalTimeDescending): Pass a function pointer.
-        (KJS::Profile::sortTotalTimeAscending): Ditto.
-        (KJS::Profile::sortSelfTimeDescending): Ditto.
-        (KJS::Profile::sortSelfTimeAscending): Ditto.
-        (KJS::Profile::sortCallsDescending): Ditto.
-        * profiler/ProfileNode.h:
-        (KJS::ProfileNode::sortTotalTimeDescending): No longer static.
-        (KJS::ProfileNode::sortTotalTimeAscending): Ditto.
-        (KJS::ProfileNode::sortSelfTimeDescending): Ditto.
-        (KJS::ProfileNode::sortSelfTimeAscending): Ditto.
-        (KJS::ProfileNode::sortCallsDescending): Ditto.
-
-2008-06-20  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Remove unused destructors.
-
-        * kjs/nodes.cpp:
-        * kjs/nodes.h:
-
-2008-06-20  Timothy Hatcher  <timothy@apple.com>
-
-        Fixed an ASSERT(m_actualSelfTime <= m_actualTotalTime) when starting
-        and stopping a profile from the Develop menu. Also prevents
-        inserting an incorrect parent node as the new head after profiling
-        is stopped from the Develop menu.
-
-        Reviewed by Dan Bernstein.
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::stopProfiling): If the current node is already the head
-        then there is no more need to record future nodes in didExecute.
-        (KJS::Profile::didExecute): Move the code of setupCurrentNodeAsStopped
-        into here since this was the only caller. When setting the total time
-        keep any current total time while adding the self time of the head.
-        (KJS::Profile::setupCurrentNodeAsStopped): Removed.
-        * profiler/Profile.h: Removed setupCurrentNodeAsStopped.
-
-2008-06-20  Kevin Ollivier  <kevino@theolliviers.com>
-
-        !USE(MULTIPLE_THREADS) on Darwin build fix
-
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreading):
-        * kjs/collector.h:
-
-2008-06-20  Kevin McCullough  <kmccullough@apple.com>
-
-        -Leopard Build Fix.
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::removeProfileStart):
-        (KJS::Profile::removeProfileEnd):
-
-2008-06-20  Kevin McCullough  <kmccullough@apple.com>
-
-        Just giving credit.
-
-        * ChangeLog:
-
-2008-06-20  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim and Dan.
-
-        <rdar://problem/6024846> JSProfiler: ASSERT hit in Profiler.
-        - Because InspectorController can call startProfiling() and
-        stopProfiling() we cannot assert that console.profile() and
-        console.profileEnd() will be in the profile tree.
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::removeProfileStart):
-        (KJS::Profile::removeProfileEnd):
-
-2008-06-20  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5958770> JSProfiler: Time incorrectly given to (idle)
-        if profiling is started and finished within the same function. (19230)
-        - Now we profile one more stack frame up from the last frame to allocate
-        the time spent in it, if it exists.
-
-        * JavaScriptCore.exp:
-        * VM/Machine.cpp: We need to let the profiler know when the JS program 
-        has finished since that is what will actually stop the profiler instead
-        of just calling stopProfiling().
-        (KJS::Machine::execute):
-        * profiler/Profile.cpp:
-        (KJS::Profile::create): Moved from Profile.h since it was getting pretty
-        long.
-        (KJS::Profile::Profile): We now have a client, which is a listener who
-        we will return this profile to, once it has actually finished.
-        (KJS::Profile::stopProfiling): Instead of fully stopping the profiler
-        here, we set the flag and keep it profiling in the background.
-        (KJS::Profile::didFinishAllExecution): This is where the profiler
-        actually finishes and creates the (idle) node if one should be made.
-        (KJS::Profile::removeProfileStart): Don't use m_currentNode since it is
-        needed by the profiler as it runs silently in the background.
-        (KJS::Profile::removeProfileEnd): Ditto.
-        (KJS::Profile::willExecute): Don't profile new functions if we have
-        stopped profiling.
-        (KJS::Profile::didExecute): Only record one more return as all the
-        remaining time will be attributed to that function.
-        (KJS::Profile::setupCurrentNodeAsStopped): Sets the current node's time.
-        * profiler/Profile.h: Added functions and variables for the above
-        changes.
-        (KJS::Profile::client):
-        * profiler/ProfileNode.h:
-        (KJS::CallIdentifier::toString): Debug method.
-        * profiler/Profiler.cpp: Added support for the ProfilerClient.
-        (KJS::Profiler::startProfiling):
-        (KJS::Profiler::stopProfiling): No longer return sthe profile.
-        (KJS::Profiler::didFinishAllExecution): Now returns the profile to the
-        client instead of stopProfiling.
-        * profiler/Profiler.h:
-        (KJS::ProfilerClient::~ProfilerClient): Clients will implement this
-        interface.
-
-2008-06-19  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Reviewed by Simon.
-
-        Surpress compiler warning (int vs unsigned comparison).
-
-        * wtf/unicode/qt4/UnicodeQt4.h:
-        (WTF::Unicode::toLower):
-
-2008-06-19  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Reviewed by Timothy Hatcher.
-
-        Introduce compiler define for MinGW, to have COMPILER(MINGW).
-
-        * wtf/Platform.h:
-
-2008-06-19  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff.
-
-        Make Machine per-JSGlobalData.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitOpcode):
-        * VM/Machine.cpp:
-        (KJS::callEval):
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::throwException):
-        (KJS::Machine::execute):
-        (KJS::Machine::debug):
-        * VM/Machine.h:
-        * kjs/DebuggerCallFrame.cpp:
-        (KJS::DebuggerCallFrame::evaluate):
-        * kjs/DebuggerCallFrame.h:
-        (KJS::DebuggerCallFrame::DebuggerCallFrame):
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        * kjs/ExecState.h:
-        (KJS::ExecState::machine):
-        * kjs/JSFunction.cpp:
-        (KJS::JSFunction::callAsFunction):
-        (KJS::JSFunction::argumentsGetter):
-        (KJS::JSFunction::callerGetter):
-        (KJS::JSFunction::construct):
-        (KJS::globalFuncEval):
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        * kjs/JSGlobalData.h:
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate):
-
-2008-06-19  Alp Toker  <alp@nuanti.com>
-
-        GTK+/autotools build fix. JSGlobalObject.cpp in now in
-        AllInOneFile.cpp and shouldn't be built separately.
-
-        * GNUmakefile.am:
-
-2008-06-19  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Get rid of some threadInstance calls.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::init):
-        * kjs/Parser.cpp:
-        (KJS::Parser::parse):
-        * kjs/Shell.cpp:
-        (jscmain):
-
-2008-06-19  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Sam.
-
-        Fix an assertion failure at startup.
-
-        * kjs/JSObject.h: (KJS::JSObject::JSObject): Allow jsNull prototype in an assertion (I had
-        it fixed in a wrong copy of the file, so I wasn't getting the failure).
-
-2008-06-19  Alexey Proskuryakov  <ap@webkit.org>
-
-        Build fix.
-
-        * kjs/collector.cpp:
-        (KJS::Heap::Heap):
-        (KJS::allocateBlock):
-        * kjs/collector.h:
-        No, #if PLATFORM(UNIX) was not right. I've just moved the unsafe initialization back for now,
-        as the platforms that use that code path do not use multiple threads yet.
-
-2008-06-19  Alexey Proskuryakov  <ap@webkit.org>
-
-        Windows and Qt build fixes.
-
-        * kjs/collector.h: 
-        * kjs/collector.cpp:
-        (KJS::Heap::Heap):
-        Wrapped m_pagesize in #if PLATFORM(UNIX), which should better match the sequence of #elifs
-        in allocateBlock(). Changed MIN_ARRAY_SIZE to be explicitly size_t, as this type is different
-        on different platforms.
-
-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
-        distinguish anonymous functions and program call frames.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19585
-
-        Reviewed by Geoff Garen.
-
-        * JavaScriptCore.exp: Export the DebuggerCallFrame::type symbol.
-        * kjs/DebuggerCallFrame.cpp:
-        (KJS::DebuggerCallFrame::type): Added.
-        * kjs/DebuggerCallFrame.h:
-
-2008-06-17  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Tim H.
-        
-        Remove bogus ASSERT which tripped every time for those who use PAC files.
-
-        * kjs/Parser.cpp:
-        (KJS::Parser::parse):
-
-2008-06-17  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Geoff.
-
-        <rdar://problem/5951534> JSProfiler: Don't profile console.profile()
-        or console.profileEnd()
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::stopProfiling): Moved the creation of the (idle) node to
-        the Profile (not ProfileNode).  This makes sense since the Profile
-        should be the one to modify the profile tree.  Also each stopProfiling()
-        does not need to check if it's the head node anymore.  Also fixed an
-        oddity where I was using willExecute to create the node.
-        (KJS::Profile::removeProfileStart): Removes the call to console.profile
-        that started this profile.
-        (KJS::Profile::removeProfileEnd): Removes the call to console.profileEnd
-        that ended this profile.
-        * profiler/Profile.h:
-        * profiler/ProfileNode.cpp: Moved the creation of the (idle) node to
-        the Profile object.
-        (KJS::ProfileNode::stopProfiling):
-        * profiler/ProfileNode.h: Added some helper functions and whitespace to
-        facilitate readability and the removal of profile() and profileEnd()
-        from the Profile tree.
-        (KJS::CallIdentifier::operator const char* ):
-        (KJS::ProfileNode::firstChild):
-        (KJS::ProfileNode::lastChild):
-        (KJS::ProfileNode::removeChild):
-        (KJS::ProfileNode::toString):
-
-2008-06-17  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Rubber stamped by Adam Roben.
-
-        Include JSGlobalObject.h to fix the build.
-
-        * kjs/ScopeChain.cpp:
-
-2008-06-17  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Reduce code duplication in emitReadModifyAssignment().
-
-        * kjs/nodes.cpp:
-        (KJS::emitReadModifyAssignment):
-
-2008-06-17  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Sort includes alphabetically.
-
-        * kjs/nodes.cpp:
-
-2008-06-16  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 19596: LEAK: Gmail leaks SegmentedVector<RegisterID>
-        <https://bugs.webkit.org/show_bug.cgi?id=19596>
-
-        When growing SegmentedVector, we start adding segments at the position
-        of the last segment, overwriting it. The destructor frees allocated
-        segments starting at the segment of index 1, because the segment of
-        index 0 is assumed to be the initial inline segment. This causes a leak
-        of the segment that is referenced by index 0. Modifying grow() so that
-        it starts adding segments at the position after the last segment fixes
-        the leak.
-
-        Since the initial segment is a special case in the lookup code, this
-        bug never manifested itself via incorrect results.
-
-        * VM/SegmentedVector.h:
-        (KJS::SegmentedVector::grow):
-
-2008-06-16  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Alexey.
-        
-        - removed nearly unused types.h and LocalStorageEntry.h headers
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/ExecState.h:
-        * kjs/LocalStorageEntry.h: Removed.
-        * kjs/RegExpObject.cpp:
-        * kjs/error_object.cpp:
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        * kjs/types.h: Removed.
-
-2008-06-16  Alp Toker  <alp@nuanti.com>
-
-        Rubber-stamped by Geoff.
-
-        Change c++ to c in minidom and testapi emacs mode line comments.
-
-        * API/Node.h:
-        * API/NodeList.c:
-        * API/NodeList.h:
-        * API/testapi.c:
-
-2008-06-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Trying to fix Windows build.
-
-        * kjs/PropertyNameArray.h:
-        * kjs/identifier.cpp:
-        Include ExecState.h
-
-2008-06-16  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Slight cleanup to the SymbolTableEntry class.
-        
-        Renamed isEmpty to isNull, since we usually use "empty" to mean "holds
-        the valid, empty value", and "null" to mean "holds no value".
-        
-        Changed an "== 0" to a "!", to match our style guidelines.
-        
-        Added some ASSERTs to verify the (possibly questionable) assumption that
-        all register indexes will have their high two bits set. Also clarified a
-        comment to make that assumption clear.
-
-2008-06-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Initialize functionQueueMutex in a safe manner.
-
-        * wtf/MainThread.cpp:
-        (WTF::functionQueueMutex): Made it an AtomicallyInitializedStatic.
-
-        (WTF::dispatchFunctionsFromMainThread):
-        (WTF::setMainThreadCallbacksPaused):
-        Assert that the current thread is main, meaning that the callbacksPaused static can be
-        accessed.
-
-2008-06-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff Garen.
-
-        Make Identifier construction use an explicitly passed IdentifierTable.
-
-        No change on SunSpider total.
-
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::getOwnPropertySlot):
-        (KJS::::put):
-        (KJS::::deleteProperty):
-        (KJS::::getPropertyNames):
-        * API/JSObjectRef.cpp:
-        (JSObjectMakeFunctionWithCallback):
-        (JSObjectMakeFunction):
-        (JSObjectHasProperty):
-        (JSObjectGetProperty):
-        (JSObjectSetProperty):
-        (JSObjectDeleteProperty):
-        (OpaqueJSPropertyNameArray::OpaqueJSPropertyNameArray):
-        (JSObjectCopyPropertyNames):
-        * JavaScriptCore.exp:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::registerForLocal):
-        (KJS::CodeGenerator::isLocal):
-        (KJS::CodeGenerator::addConstant):
-        (KJS::CodeGenerator::findScopedProperty):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::globalData):
-        (KJS::CodeGenerator::propertyNames):
-        * VM/JSPropertyNameIterator.cpp:
-        (KJS::JSPropertyNameIterator::create):
-        * VM/Machine.cpp:
-        (KJS::Machine::throwException):
-        (KJS::Machine::privateExecute):
-        * kjs/ArrayPrototype.cpp:
-        (KJS::ArrayConstructor::ArrayConstructor):
-        * kjs/BooleanObject.cpp:
-        (KJS::BooleanConstructor::BooleanConstructor):
-        * kjs/FunctionPrototype.cpp:
-        (KJS::FunctionConstructor::FunctionConstructor):
-        (KJS::FunctionConstructor::construct):
-        * kjs/JSArray.cpp:
-        (KJS::JSArray::inlineGetOwnPropertySlot):
-        (KJS::JSArray::put):
-        (KJS::JSArray::deleteProperty):
-        (KJS::JSArray::getPropertyNames):
-        * kjs/JSFunction.cpp:
-        (KJS::Arguments::Arguments):
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset):
-        * kjs/JSObject.cpp:
-        (KJS::JSObject::getOwnPropertySlot):
-        (KJS::JSObject::put):
-        (KJS::JSObject::putWithAttributes):
-        (KJS::JSObject::deleteProperty):
-        (KJS::JSObject::findPropertyHashEntry):
-        (KJS::JSObject::getPropertyNames):
-        (KJS::Error::create):
-        * kjs/JSVariableObject.cpp:
-        (KJS::JSVariableObject::getPropertyNames):
-        * kjs/NumberObject.cpp:
-        (KJS::NumberConstructor::NumberConstructor):
-        * kjs/PropertyNameArray.cpp:
-        (KJS::PropertyNameArray::add):
-        * kjs/PropertyNameArray.h:
-        (KJS::PropertyNameArray::PropertyNameArray):
-        (KJS::PropertyNameArray::addKnownUnique):
-        * kjs/PropertySlot.h:
-        (KJS::PropertySlot::getValue):
-        * kjs/RegExpObject.cpp:
-        (KJS::RegExpConstructor::RegExpConstructor):
-        * kjs/ScopeChain.cpp:
-        (KJS::ScopeChainNode::print):
-        * kjs/Shell.cpp:
-        (GlobalObject::GlobalObject):
-        * kjs/date_object.cpp:
-        (KJS::DateConstructor::DateConstructor):
-        * kjs/error_object.cpp:
-        (KJS::ErrorConstructor::ErrorConstructor):
-        (KJS::NativeErrorConstructor::NativeErrorConstructor):
-        * kjs/grammar.y:
-        * kjs/identifier.cpp:
-        (KJS::Identifier::add):
-        (KJS::Identifier::addSlowCase):
-        * kjs/identifier.h:
-        (KJS::Identifier::Identifier):
-        (KJS::Identifier::from):
-        (KJS::Identifier::equal):
-        (KJS::Identifier::add):
-        (KJS::operator==):
-        (KJS::operator!=):
-        * kjs/internal.cpp:
-        (KJS::JSString::getOwnPropertySlot):
-        * kjs/lexer.cpp:
-        (KJS::Lexer::Lexer):
-        (KJS::Lexer::lex):
-        (KJS::Lexer::makeIdentifier):
-        * kjs/lexer.h:
-        * kjs/lookup.cpp:
-        (KJS::HashTable::createTable):
-        * kjs/lookup.h:
-        (KJS::HashTable::initializeIfNeeded):
-        (KJS::HashTable::entry):
-        (KJS::getStaticPropertySlot):
-        (KJS::getStaticFunctionSlot):
-        (KJS::getStaticValueSlot):
-        (KJS::lookupPut):
-        * kjs/object_object.cpp:
-        (KJS::objectProtoFuncHasOwnProperty):
-        (KJS::objectProtoFuncDefineGetter):
-        (KJS::objectProtoFuncDefineSetter):
-        (KJS::objectProtoFuncLookupGetter):
-        (KJS::objectProtoFuncLookupSetter):
-        (KJS::objectProtoFuncPropertyIsEnumerable):
-        (KJS::ObjectConstructor::ObjectConstructor):
-        * kjs/string_object.cpp:
-        (KJS::StringObject::getOwnPropertySlot):
-        (KJS::StringObject::getPropertyNames):
-        (KJS::StringConstructor::StringConstructor):
-        Just pass ExecState or JSGlobalData everywhere. Identifier construction is now always
-        explicit.
-
-        * kjs/nodes.cpp: (KJS::RegExpNode::emitCode): Here, Identifier was created from a non-literal
-        char*, which was incorrect, as that uses the pointer value as a key.
-
-2008-06-16  Thiago Macieira  <tjmaciei@trolltech.com>
-
-        Reviewed by Darin.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19577
-
-        Fix compilation in C++ environments where C99 headers are not present
-
-        The stdbool.h header is a C99 feature, defining the "_Bool" type as well as the
-        "true" and "false" constants. But it's completely unnecessary in C++ as the
-        language already defines the "bool" type and its two values.
-
-        * API/JSBase.h:
-        * API/JSContextRef.h:
-        * API/JSObjectRef.h:
-        * API/JSStringRef.h:
-        * API/JSValueRef.h:
-
-2008-06-16  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by John.
-
-        <rdar://problem/6012509> JSProfiler: %s are incorrect if you exclude a
-        top level node like (idle)
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::focus):
-        (KJS::Profile::exclude): Subtract the selfTime from the totalTime of the
-        head since its self time will only be non-zero when one of its children
-        were excluded. Since the head's totalTime is used to calculate %s when
-        its totalTime is the same as the sum of all its visible childrens' times
-        their %s will sum to 100%.
-
-2008-06-16  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        <rdar://problem/5969992> JSProfiler: Remove the recursion limit in the profiler.
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::willExecute):
-
-2008-06-16  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam.
-
-        <rdar://problem/5969992> JSProfiler: Remove the recursion limit in the
-        profiler.
-        - Remove the last of the uses of recursion in the profiler.
-
-        * JavaScriptCore.exp: Export the new function's signature.
-        * profiler/Profile.cpp: 
-        (KJS::calculateVisibleTotalTime): Added a new static method for
-        recalculating the visibleTotalTime of methods after focus has changed
-        which are visible.
-        (KJS::stopProfiling): 
-        (KJS::Profile::focus): Implemented focus without recursion.
-        * profiler/Profile.h: Moved implementation into the definition file.
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::traverseNextNodePreOrder): Added an argument for
-        whether or not to process the children nodes, this allows focus to skip
-        sub trees which have been set as not visible.
-        (KJS::ProfileNode::calculateVisibleTotalTime): This function set's a
-        node's total visible time to the sum of its self time and its children's
-        total times.
-        (KJS::ProfileNode::focus): Implemented focus without recursion.
-        * profiler/ProfileNode.h:
-        (KJS::CallIdentifier::operator!= ):
-        (KJS::ProfileNode::setActualTotalTime): Expanded setting the total time
-        so that focus could modify only the visible total time.
-        (KJS::ProfileNode::setVisibleTotalTime):
-
-2008-06-16  Christian Dywan  <christian@twotoasts.de>
-
-        Reviewed by Sam.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19552
-        JavaScriptCore headers use C++ style comments
-
-        Replace all C++ style comments with C style multiline
-        comments and remove all "mode" lines.
-
-        * API/JSBase.h:
-        * API/JSClassRef.h:
-        * API/JSContextRef.h:
-        * API/JSObjectRef.h:
-        * API/JSStringRef.h:
-        * API/JSStringRefBSTR.h:
-        * API/JSStringRefCF.h:
-        * API/JSValueRef.h:
-        * API/JavaScript.h:
-        * API/JavaScriptCore.h:
-
-2008-06-16  Christian Dywan  <christian@twotoasts.de>
-
-        Reviewed by Sam.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19557
-        (JavaScriptCore) minidom uses C++ style comments
-
-        Use only C style comments in minidom sources
-
-        * API/JSNode.c:
-        (JSNode_appendChild):
-        (JSNode_removeChild):
-        * API/JSNode.h:
-        * API/JSNodeList.c:
-        (JSNodeList_getProperty):
-        * API/JSNodeList.h:
-        * API/Node.c:
-        * API/Node.h:
-        * API/NodeList.c:
-        (NodeList_new):
-        (NodeList_item):
-        * API/NodeList.h:
-        * API/minidom.c:
-        (createStringWithContentsOfFile):
-        * wtf/Assertions.h:
-        * wtf/UnusedParam.h:
-
-2008-06-16  Adriaan de Groot  <groot@kde.org>
-
-        Reviewed by Simon.
-
-        Fix compilation on Solaris
-
-        On some systems, munmap takes a char* instead of a void* (contrary to POSIX and
-        Single Unix Specification). Since you can always convert from char* to void*
-        but not vice-versa, do the casting to char*.
-
-        * kjs/collector.cpp:
-        (KJS::allocateBlock):
-        (KJS::freeBlock):
-
-2008-06-16  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Make a UnaryOpNode class to reduce boilerplate code for UnaryPlusNode,
-        NegateNode, BitwiseNotNode, and LogicalNotNode.
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::emitToJSNumber):
-        * kjs/nodes.cpp:
-        (KJS::UnaryOpNode::emitCode):
-        * kjs/nodes.h:
-        (KJS::UnaryOpNode::UnaryOpNode):
-        (KJS::UnaryPlusNode::):
-        (KJS::NegateNode::):
-        (KJS::NegateNode::precedence):
-        (KJS::BitwiseNotNode::):
-        (KJS::BitwiseNotNode::precedence):
-        (KJS::LogicalNotNode::):
-        (KJS::LogicalNotNode::precedence):
-
-2008-06-16  Jan Michael Alonzo  <jmalonzo@webkit.org>
-
-        Gtk build fix
-
-        * GNUmakefile.am:
-
-2008-06-15  Darin Adler  <darin@apple.com>
-
-        - rename KJS::List to KJS::ArgList
-
-        * API/JSCallbackConstructor.cpp:
-        (KJS::JSCallbackConstructor::construct):
-        * API/JSCallbackConstructor.h:
-        * API/JSCallbackFunction.cpp:
-        (KJS::JSCallbackFunction::callAsFunction):
-        * API/JSCallbackFunction.h:
-        * API/JSCallbackObject.h:
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::construct):
-        (KJS::::callAsFunction):
-        * API/JSObjectRef.cpp:
-        (JSObjectMakeFunction):
-        (JSObjectCallAsFunction):
-        (JSObjectCallAsConstructor):
-        * JavaScriptCore.exp:
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        * kjs/ArrayPrototype.cpp:
-        (KJS::arrayProtoFuncToString):
-        (KJS::arrayProtoFuncToLocaleString):
-        (KJS::arrayProtoFuncJoin):
-        (KJS::arrayProtoFuncConcat):
-        (KJS::arrayProtoFuncPop):
-        (KJS::arrayProtoFuncPush):
-        (KJS::arrayProtoFuncReverse):
-        (KJS::arrayProtoFuncShift):
-        (KJS::arrayProtoFuncSlice):
-        (KJS::arrayProtoFuncSort):
-        (KJS::arrayProtoFuncSplice):
-        (KJS::arrayProtoFuncUnShift):
-        (KJS::arrayProtoFuncFilter):
-        (KJS::arrayProtoFuncMap):
-        (KJS::arrayProtoFuncEvery):
-        (KJS::arrayProtoFuncForEach):
-        (KJS::arrayProtoFuncSome):
-        (KJS::arrayProtoFuncIndexOf):
-        (KJS::arrayProtoFuncLastIndexOf):
-        (KJS::ArrayConstructor::construct):
-        (KJS::ArrayConstructor::callAsFunction):
-        * kjs/ArrayPrototype.h:
-        * kjs/BooleanObject.cpp:
-        (KJS::booleanProtoFuncToString):
-        (KJS::booleanProtoFuncValueOf):
-        (KJS::BooleanConstructor::construct):
-        (KJS::BooleanConstructor::callAsFunction):
-        * kjs/BooleanObject.h:
-        * kjs/CommonIdentifiers.h:
-        * kjs/ExecState.h:
-        (KJS::ExecState::emptyList):
-        * kjs/FunctionPrototype.cpp:
-        (KJS::FunctionPrototype::callAsFunction):
-        (KJS::functionProtoFuncToString):
-        (KJS::functionProtoFuncApply):
-        (KJS::functionProtoFuncCall):
-        (KJS::FunctionConstructor::construct):
-        (KJS::FunctionConstructor::callAsFunction):
-        * kjs/FunctionPrototype.h:
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::createArgumentsObject):
-        * kjs/JSArray.cpp:
-        (KJS::JSArray::JSArray):
-        (KJS::AVLTreeAbstractorForArrayCompare::compare_key_key):
-        * kjs/JSArray.h:
-        * kjs/JSFunction.cpp:
-        (KJS::JSFunction::callAsFunction):
-        (KJS::JSFunction::construct):
-        (KJS::IndexToNameMap::IndexToNameMap):
-        (KJS::Arguments::Arguments):
-        (KJS::encode):
-        (KJS::decode):
-        (KJS::globalFuncEval):
-        (KJS::globalFuncParseInt):
-        (KJS::globalFuncParseFloat):
-        (KJS::globalFuncIsNaN):
-        (KJS::globalFuncIsFinite):
-        (KJS::globalFuncDecodeURI):
-        (KJS::globalFuncDecodeURIComponent):
-        (KJS::globalFuncEncodeURI):
-        (KJS::globalFuncEncodeURIComponent):
-        (KJS::globalFuncEscape):
-        (KJS::globalFuncUnescape):
-        (KJS::globalFuncKJSPrint):
-        (KJS::PrototypeFunction::callAsFunction):
-        (KJS::PrototypeReflexiveFunction::callAsFunction):
-        * kjs/JSFunction.h:
-        * kjs/JSGlobalData.h:
-        * kjs/JSImmediate.cpp:
-        (KJS::JSImmediate::toObject):
-        * kjs/JSNotAnObject.cpp:
-        (KJS::JSNotAnObject::construct):
-        (KJS::JSNotAnObject::callAsFunction):
-        * kjs/JSNotAnObject.h:
-        * kjs/JSObject.cpp:
-        (KJS::JSObject::put):
-        (KJS::JSObject::construct):
-        (KJS::JSObject::callAsFunction):
-        (KJS::Error::create):
-        * kjs/JSObject.h:
-        * kjs/MathObject.cpp:
-        (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/MathObject.h:
-        * kjs/NumberObject.cpp:
-        (KJS::numberProtoFuncToString):
-        (KJS::numberProtoFuncToLocaleString):
-        (KJS::numberProtoFuncValueOf):
-        (KJS::numberProtoFuncToFixed):
-        (KJS::numberProtoFuncToExponential):
-        (KJS::numberProtoFuncToPrecision):
-        (KJS::NumberConstructor::construct):
-        (KJS::NumberConstructor::callAsFunction):
-        * kjs/NumberObject.h:
-        * kjs/RegExpObject.cpp:
-        (KJS::regExpProtoFuncTest):
-        (KJS::regExpProtoFuncExec):
-        (KJS::regExpProtoFuncCompile):
-        (KJS::regExpProtoFuncToString):
-        (KJS::RegExpObject::match):
-        (KJS::RegExpObject::test):
-        (KJS::RegExpObject::exec):
-        (KJS::RegExpObject::callAsFunction):
-        (KJS::RegExpConstructor::construct):
-        (KJS::RegExpConstructor::callAsFunction):
-        * kjs/RegExpObject.h:
-        * kjs/Shell.cpp:
-        (functionPrint):
-        (functionDebug):
-        (functionGC):
-        (functionVersion):
-        (functionRun):
-        (functionLoad):
-        (functionReadline):
-        (functionQuit):
-        * kjs/collector.cpp:
-        (KJS::Collector::collect):
-        * kjs/collector.h:
-        (KJS::Collector::markListSet):
-        * kjs/date_object.cpp:
-        (KJS::formatLocaleDate):
-        (KJS::fillStructuresUsingTimeArgs):
-        (KJS::fillStructuresUsingDateArgs):
-        (KJS::DateConstructor::construct):
-        (KJS::DateConstructor::callAsFunction):
-        (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::dateProtoFuncSetMilliSeconds):
-        (KJS::dateProtoFuncSetUTCMilliseconds):
-        (KJS::dateProtoFuncSetSeconds):
-        (KJS::dateProtoFuncSetUTCSeconds):
-        (KJS::dateProtoFuncSetMinutes):
-        (KJS::dateProtoFuncSetUTCMinutes):
-        (KJS::dateProtoFuncSetHours):
-        (KJS::dateProtoFuncSetUTCHours):
-        (KJS::dateProtoFuncSetDate):
-        (KJS::dateProtoFuncSetUTCDate):
-        (KJS::dateProtoFuncSetMonth):
-        (KJS::dateProtoFuncSetUTCMonth):
-        (KJS::dateProtoFuncSetFullYear):
-        (KJS::dateProtoFuncSetUTCFullYear):
-        (KJS::dateProtoFuncSetYear):
-        (KJS::dateProtoFuncGetYear):
-        * kjs/date_object.h:
-        * kjs/debugger.h:
-        * kjs/error_object.cpp:
-        (KJS::errorProtoFuncToString):
-        (KJS::ErrorConstructor::construct):
-        (KJS::ErrorConstructor::callAsFunction):
-        (KJS::NativeErrorConstructor::construct):
-        (KJS::NativeErrorConstructor::callAsFunction):
-        * kjs/error_object.h:
-        * kjs/internal.cpp:
-        (KJS::JSNumberCell::toObject):
-        (KJS::JSNumberCell::toThisObject):
-        * kjs/list.cpp:
-        (KJS::ArgList::getSlice):
-        (KJS::ArgList::markLists):
-        (KJS::ArgList::slowAppend):
-        * kjs/list.h:
-        (KJS::ArgList::ArgList):
-        (KJS::ArgList::~ArgList):
-        * kjs/object_object.cpp:
-        (KJS::objectProtoFuncValueOf):
-        (KJS::objectProtoFuncHasOwnProperty):
-        (KJS::objectProtoFuncIsPrototypeOf):
-        (KJS::objectProtoFuncDefineGetter):
-        (KJS::objectProtoFuncDefineSetter):
-        (KJS::objectProtoFuncLookupGetter):
-        (KJS::objectProtoFuncLookupSetter):
-        (KJS::objectProtoFuncPropertyIsEnumerable):
-        (KJS::objectProtoFuncToLocaleString):
-        (KJS::objectProtoFuncToString):
-        (KJS::ObjectConstructor::construct):
-        (KJS::ObjectConstructor::callAsFunction):
-        * kjs/object_object.h:
-        * kjs/string_object.cpp:
-        (KJS::replace):
-        (KJS::stringProtoFuncToString):
-        (KJS::stringProtoFuncValueOf):
-        (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::construct):
-        (KJS::StringConstructor::callAsFunction):
-        (KJS::StringConstructorFunction::callAsFunction):
-        * kjs/string_object.h:
-
-2008-06-15  Darin Adler  <darin@apple.com>
-
-        - new names for more JavaScriptCore files
-
-        * API/JSCallbackFunction.cpp:
-        * API/JSObjectRef.cpp:
-        * DerivedSources.make:
-        * GNUmakefile.am:
-        * JavaScriptCore.exp:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * VM/Machine.cpp:
-        * kjs/AllInOneFile.cpp:
-        * kjs/ArrayPrototype.cpp: Copied from JavaScriptCore/kjs/array_object.cpp.
-        * kjs/ArrayPrototype.h: Copied from JavaScriptCore/kjs/array_object.h.
-        * kjs/BooleanObject.cpp: Copied from JavaScriptCore/kjs/bool_object.cpp.
-        * kjs/BooleanObject.h: Copied from JavaScriptCore/kjs/bool_object.h.
-        * kjs/ExecState.cpp:
-        * kjs/ExecState.h:
-        * kjs/FunctionPrototype.cpp: Copied from JavaScriptCore/kjs/function_object.cpp.
-        * kjs/FunctionPrototype.h: Copied from JavaScriptCore/kjs/function_object.h.
-        * kjs/JSArray.cpp: Copied from JavaScriptCore/kjs/array_instance.cpp.
-        * kjs/JSArray.h: Copied from JavaScriptCore/kjs/array_instance.h.
-        * kjs/JSFunction.cpp:
-        * kjs/JSFunction.h:
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSImmediate.cpp:
-        * kjs/JSObject.h:
-        * kjs/JSString.h:
-        * kjs/JSValue.h:
-        * kjs/JSVariableObject.cpp:
-        * kjs/MathObject.cpp: Copied from JavaScriptCore/kjs/math_object.cpp.
-        * kjs/MathObject.h: Copied from JavaScriptCore/kjs/math_object.h.
-        * kjs/NumberObject.cpp: Copied from JavaScriptCore/kjs/number_object.cpp.
-        * kjs/NumberObject.h: Copied from JavaScriptCore/kjs/number_object.h.
-        * kjs/PropertyMap.cpp: Copied from JavaScriptCore/kjs/property_map.cpp.
-        * kjs/PropertyMap.h: Copied from JavaScriptCore/kjs/property_map.h.
-        * kjs/PropertySlot.cpp: Copied from JavaScriptCore/kjs/property_slot.cpp.
-        * kjs/PropertySlot.h: Copied from JavaScriptCore/kjs/property_slot.h.
-        * kjs/RegExpObject.cpp: Copied from JavaScriptCore/kjs/regexp_object.cpp.
-        * kjs/RegExpObject.h: Copied from JavaScriptCore/kjs/regexp_object.h.
-        * kjs/ScopeChain.cpp: Copied from JavaScriptCore/kjs/scope_chain.cpp.
-        * kjs/ScopeChain.h: Copied from JavaScriptCore/kjs/scope_chain.h.
-        * kjs/ScopeChainMark.h: Copied from JavaScriptCore/kjs/scope_chain_mark.h.
-        * kjs/Shell.cpp:
-        * kjs/array_instance.cpp: Removed.
-        * kjs/array_instance.h: Removed.
-        * kjs/array_object.cpp: Removed.
-        * kjs/array_object.h: Removed.
-        * kjs/bool_object.cpp: Removed.
-        * kjs/bool_object.h: Removed.
-        * kjs/error_object.h:
-        * kjs/function_object.cpp: Removed.
-        * kjs/function_object.h: Removed.
-        * kjs/internal.cpp:
-        * kjs/math_object.cpp: Removed.
-        * kjs/math_object.h: Removed.
-        * kjs/nodes.cpp:
-        * kjs/number_object.cpp: Removed.
-        * kjs/number_object.h: Removed.
-        * kjs/object_object.cpp:
-        * kjs/property_map.cpp: Removed.
-        * kjs/property_map.h: Removed.
-        * kjs/property_slot.cpp: Removed.
-        * kjs/property_slot.h: Removed.
-        * kjs/regexp_object.cpp: Removed.
-        * kjs/regexp_object.h: Removed.
-        * kjs/scope_chain.cpp: Removed.
-        * kjs/scope_chain.h: Removed.
-        * kjs/scope_chain_mark.h: Removed.
-        * kjs/string_object.cpp:
-        * kjs/string_object.h:
-
-2008-06-15  Darin Adler  <darin@apple.com>
-
-        - new names for a few key JavaScriptCore files
-
-        * API/JSBase.cpp:
-        * API/JSCallbackConstructor.h:
-        * API/JSCallbackFunction.cpp:
-        * API/JSCallbackFunction.h:
-        * API/JSCallbackObject.h:
-        * API/JSCallbackObjectFunctions.h:
-        * API/JSClassRef.h:
-        * API/JSContextRef.cpp:
-        * API/JSObjectRef.cpp:
-        * API/JSStringRef.cpp:
-        * API/JSStringRefCF.cpp:
-        * API/JSValueRef.cpp:
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * VM/CodeBlock.cpp:
-        * VM/CodeGenerator.cpp:
-        * VM/ExceptionHelpers.cpp:
-        * VM/ExceptionHelpers.h:
-        * VM/JSPropertyNameIterator.cpp:
-        * VM/JSPropertyNameIterator.h:
-        * VM/Machine.cpp:
-        * kjs/AllInOneFile.cpp:
-        * kjs/DateMath.cpp:
-        * kjs/DebuggerCallFrame.cpp:
-        * kjs/ExecState.cpp:
-        * kjs/JSActivation.cpp:
-        * kjs/JSFunction.cpp: Copied from JavaScriptCore/kjs/function.cpp.
-        * kjs/JSFunction.h: Copied from JavaScriptCore/kjs/function.h.
-        * kjs/JSImmediate.cpp:
-        * kjs/JSNotAnObject.h:
-        * kjs/JSObject.cpp: Copied from JavaScriptCore/kjs/object.cpp.
-        * kjs/JSObject.h: Copied from JavaScriptCore/kjs/object.h.
-        * kjs/JSString.h: Copied from JavaScriptCore/kjs/internal.h.
-        * kjs/JSValue.cpp: Copied from JavaScriptCore/kjs/value.cpp.
-        * kjs/JSValue.h: Copied from JavaScriptCore/kjs/value.h.
-        * kjs/JSVariableObject.h:
-        * kjs/JSWrapperObject.h:
-        * kjs/Shell.cpp:
-        * kjs/SymbolTable.h:
-        * kjs/array_instance.h:
-        * kjs/collector.cpp:
-        * kjs/date_object.cpp:
-        * kjs/date_object.h:
-        * kjs/error_object.cpp:
-        * kjs/function.cpp: Removed.
-        * kjs/function.h: Removed.
-        * kjs/function_object.cpp:
-        * kjs/function_object.h:
-        * kjs/grammar.y:
-        * kjs/internal.cpp:
-        * kjs/internal.h: Removed.
-        * kjs/lexer.cpp:
-        * kjs/list.h:
-        * kjs/lookup.h:
-        * kjs/nodes.h:
-        * kjs/object.cpp: Removed.
-        * kjs/object.h: Removed.
-        * kjs/object_object.h:
-        * kjs/operations.cpp:
-        * kjs/property_map.cpp:
-        * kjs/property_slot.cpp:
-        * kjs/property_slot.h:
-        * kjs/protect.h:
-        * kjs/regexp_object.cpp:
-        * kjs/scope_chain.cpp:
-        * kjs/string_object.h:
-        * kjs/ustring.cpp:
-        * kjs/value.cpp: Removed.
-        * kjs/value.h: Removed.
-        * profiler/Profile.cpp:
-        * profiler/Profiler.cpp:
-
-2008-06-15  Darin Adler  <darin@apple.com>
-
-        Rubber stamped by Sam.
-
-        - cut down on confusing uses of "Object" and "Imp" in
-          JavaScriptCore class names
-
-        * API/JSCallbackFunction.cpp:
-        (KJS::JSCallbackFunction::JSCallbackFunction):
-        * API/JSCallbackFunction.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/ExecState.h:
-        (KJS::ExecState::regExpTable):
-        (KJS::ExecState::regExpConstructorTable):
-        * kjs/JSGlobalData.cpp:
-        (KJS::JSGlobalData::JSGlobalData):
-        (KJS::JSGlobalData::~JSGlobalData):
-        * kjs/JSGlobalData.h:
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::objectConstructor):
-        (KJS::JSGlobalObject::functionConstructor):
-        (KJS::JSGlobalObject::arrayConstructor):
-        (KJS::JSGlobalObject::booleanConstructor):
-        (KJS::JSGlobalObject::stringConstructor):
-        (KJS::JSGlobalObject::numberConstructor):
-        (KJS::JSGlobalObject::dateConstructor):
-        (KJS::JSGlobalObject::regExpConstructor):
-        (KJS::JSGlobalObject::errorConstructor):
-        (KJS::JSGlobalObject::evalErrorConstructor):
-        (KJS::JSGlobalObject::rangeErrorConstructor):
-        (KJS::JSGlobalObject::referenceErrorConstructor):
-        (KJS::JSGlobalObject::syntaxErrorConstructor):
-        (KJS::JSGlobalObject::typeErrorConstructor):
-        (KJS::JSGlobalObject::URIErrorConstructor):
-        * kjs/array_object.cpp:
-        (KJS::ArrayConstructor::ArrayConstructor):
-        (KJS::ArrayConstructor::getConstructData):
-        (KJS::ArrayConstructor::construct):
-        (KJS::ArrayConstructor::callAsFunction):
-        * kjs/array_object.h:
-        * kjs/bool_object.cpp:
-        (KJS::BooleanObject::BooleanObject):
-        (KJS::BooleanPrototype::BooleanPrototype):
-        (KJS::booleanProtoFuncToString):
-        (KJS::booleanProtoFuncValueOf):
-        (KJS::BooleanConstructor::BooleanConstructor):
-        (KJS::BooleanConstructor::getConstructData):
-        (KJS::BooleanConstructor::construct):
-        (KJS::BooleanConstructor::callAsFunction):
-        * kjs/bool_object.h:
-        * kjs/date_object.cpp:
-        (KJS::DatePrototype::DatePrototype):
-        (KJS::DateConstructor::DateConstructor):
-        (KJS::DateConstructor::getConstructData):
-        (KJS::DateConstructor::construct):
-        (KJS::DateConstructor::callAsFunction):
-        (KJS::DateFunction::DateFunction):
-        (KJS::DateFunction::callAsFunction):
-        * kjs/date_object.h:
-        * kjs/error_object.cpp:
-        (KJS::ErrorPrototype::ErrorPrototype):
-        (KJS::ErrorConstructor::ErrorConstructor):
-        (KJS::ErrorConstructor::getConstructData):
-        (KJS::ErrorConstructor::construct):
-        (KJS::ErrorConstructor::callAsFunction):
-        (KJS::NativeErrorConstructor::NativeErrorConstructor):
-        (KJS::NativeErrorConstructor::getConstructData):
-        (KJS::NativeErrorConstructor::construct):
-        (KJS::NativeErrorConstructor::callAsFunction):
-        (KJS::NativeErrorConstructor::mark):
-        * kjs/error_object.h:
-        * kjs/function.cpp:
-        (KJS::JSFunction::JSFunction):
-        (KJS::JSFunction::mark):
-        (KJS::JSFunction::getOwnPropertySlot):
-        (KJS::JSFunction::put):
-        (KJS::JSFunction::deleteProperty):
-        (KJS::PrototypeFunction::PrototypeFunction):
-        (KJS::PrototypeReflexiveFunction::PrototypeReflexiveFunction):
-        (KJS::PrototypeReflexiveFunction::mark):
-        * kjs/function.h:
-        * kjs/function_object.cpp:
-        (KJS::functionProtoFuncToString):
-        (KJS::FunctionConstructor::FunctionConstructor):
-        (KJS::FunctionConstructor::getConstructData):
-        (KJS::FunctionConstructor::construct):
-        (KJS::FunctionConstructor::callAsFunction):
-        * kjs/function_object.h:
-        * kjs/internal.cpp:
-        (KJS::StringObject::create):
-        (KJS::JSString::toObject):
-        (KJS::JSString::toThisObject):
-        (KJS::JSString::getOwnPropertySlot):
-        (KJS::InternalFunction::InternalFunction):
-        (KJS::InternalFunction::getCallData):
-        (KJS::InternalFunction::implementsHasInstance):
-        * kjs/math_object.cpp:
-        (KJS::MathObject::MathObject):
-        (KJS::MathObject::getOwnPropertySlot):
-        (KJS::MathObject::getValueProperty):
-        * kjs/math_object.h:
-        * kjs/number_object.cpp:
-        (KJS::NumberObject::NumberObject):
-        (KJS::NumberPrototype::NumberPrototype):
-        (KJS::numberProtoFuncToString):
-        (KJS::numberProtoFuncToLocaleString):
-        (KJS::numberProtoFuncValueOf):
-        (KJS::numberProtoFuncToFixed):
-        (KJS::numberProtoFuncToExponential):
-        (KJS::numberProtoFuncToPrecision):
-        (KJS::NumberConstructor::NumberConstructor):
-        (KJS::NumberConstructor::getOwnPropertySlot):
-        (KJS::NumberConstructor::getValueProperty):
-        (KJS::NumberConstructor::getConstructData):
-        (KJS::NumberConstructor::construct):
-        (KJS::NumberConstructor::callAsFunction):
-        * kjs/number_object.h:
-        * kjs/object.cpp:
-        (KJS::JSObject::putDirectFunction):
-        * kjs/object.h:
-        * kjs/object_object.cpp:
-        (KJS::ObjectConstructor::ObjectConstructor):
-        (KJS::ObjectConstructor::getConstructData):
-        (KJS::ObjectConstructor::construct):
-        (KJS::ObjectConstructor::callAsFunction):
-        * kjs/object_object.h:
-        * kjs/regexp.cpp:
-        (KJS::RegExp::RegExp):
-        * kjs/regexp_object.cpp:
-        (KJS::regExpProtoFuncTest):
-        (KJS::regExpProtoFuncExec):
-        (KJS::regExpProtoFuncCompile):
-        (KJS::regExpProtoFuncToString):
-        (KJS::RegExpObject::RegExpObject):
-        (KJS::RegExpObject::~RegExpObject):
-        (KJS::RegExpObject::getOwnPropertySlot):
-        (KJS::RegExpObject::getValueProperty):
-        (KJS::RegExpObject::put):
-        (KJS::RegExpObject::putValueProperty):
-        (KJS::RegExpObject::match):
-        (KJS::RegExpObject::test):
-        (KJS::RegExpObject::exec):
-        (KJS::RegExpObject::getCallData):
-        (KJS::RegExpObject::callAsFunction):
-        (KJS::RegExpConstructorPrivate::RegExpConstructorPrivate):
-        (KJS::RegExpConstructor::RegExpConstructor):
-        (KJS::RegExpConstructor::performMatch):
-        (KJS::RegExpMatchesArray::RegExpMatchesArray):
-        (KJS::RegExpMatchesArray::~RegExpMatchesArray):
-        (KJS::RegExpMatchesArray::fillArrayInstance):
-        (KJS::RegExpConstructor::arrayOfMatches):
-        (KJS::RegExpConstructor::getBackref):
-        (KJS::RegExpConstructor::getLastParen):
-        (KJS::RegExpConstructor::getLeftContext):
-        (KJS::RegExpConstructor::getRightContext):
-        (KJS::RegExpConstructor::getOwnPropertySlot):
-        (KJS::RegExpConstructor::getValueProperty):
-        (KJS::RegExpConstructor::put):
-        (KJS::RegExpConstructor::putValueProperty):
-        (KJS::RegExpConstructor::getConstructData):
-        (KJS::RegExpConstructor::construct):
-        (KJS::RegExpConstructor::callAsFunction):
-        (KJS::RegExpConstructor::input):
-        * kjs/regexp_object.h:
-        * kjs/string_object.cpp:
-        (KJS::StringObject::StringObject):
-        (KJS::StringObject::getOwnPropertySlot):
-        (KJS::StringObject::put):
-        (KJS::StringObject::deleteProperty):
-        (KJS::StringObject::getPropertyNames):
-        (KJS::StringPrototype::StringPrototype):
-        (KJS::StringPrototype::getOwnPropertySlot):
-        (KJS::replace):
-        (KJS::stringProtoFuncToString):
-        (KJS::stringProtoFuncValueOf):
-        (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::getConstructData):
-        (KJS::StringConstructor::construct):
-        (KJS::StringConstructor::callAsFunction):
-        (KJS::StringConstructorFunction::StringConstructorFunction):
-        (KJS::StringConstructorFunction::callAsFunction):
-        * kjs/string_object.h:
-        (KJS::StringObjectThatMasqueradesAsUndefined::StringObjectThatMasqueradesAsUndefined):
-        * profiler/Profiler.cpp:
-        (KJS::createCallIdentifier):
-
-2008-06-15  Darin Adler  <darin@apple.com>
-
-        Rubber stamped by Sam.
-
-        - use JS prefix and simpler names for basic JavaScriptCore types,
-          to complement JSValue and JSObject
-
-        * JavaScriptCore.exp:
-        * VM/Machine.cpp:
-        (KJS::jsLess):
-        (KJS::jsLessEq):
-        (KJS::jsAdd):
-        (KJS::callEval):
-        (KJS::Machine::execute):
-        (KJS::Machine::retrieveArguments):
-        (KJS::Machine::retrieveCaller):
-        (KJS::Machine::getCallFrame):
-        (KJS::Machine::getFunctionAndArguments):
-        * VM/Machine.h:
-        * VM/Register.h:
-        * kjs/DebuggerCallFrame.cpp:
-        (KJS::DebuggerCallFrame::functionName):
-        * kjs/ExecState.h:
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::createArgumentsObject):
-        * kjs/array_instance.cpp:
-        (KJS::JSArray::checkConsistency):
-        (KJS::JSArray::JSArray):
-        (KJS::JSArray::~JSArray):
-        (KJS::JSArray::getItem):
-        (KJS::JSArray::lengthGetter):
-        (KJS::JSArray::inlineGetOwnPropertySlot):
-        (KJS::JSArray::getOwnPropertySlot):
-        (KJS::JSArray::put):
-        (KJS::JSArray::deleteProperty):
-        (KJS::JSArray::getPropertyNames):
-        (KJS::JSArray::increaseVectorLength):
-        (KJS::JSArray::setLength):
-        (KJS::JSArray::mark):
-        (KJS::JSArray::sort):
-        (KJS::JSArray::compactForSorting):
-        (KJS::JSArray::lazyCreationData):
-        (KJS::JSArray::setLazyCreationData):
-        * kjs/array_instance.h:
-        * kjs/array_object.cpp:
-        (KJS::ArrayPrototype::ArrayPrototype):
-        (KJS::ArrayPrototype::getOwnPropertySlot):
-        (KJS::arrayProtoFuncToString):
-        (KJS::arrayProtoFuncToLocaleString):
-        (KJS::arrayProtoFuncConcat):
-        (KJS::arrayProtoFuncSort):
-        (KJS::ArrayObjectImp::construct):
-        * kjs/array_object.h:
-        * kjs/completion.h:
-        * kjs/function.cpp:
-        (KJS::JSFunction::JSFunction):
-        (KJS::JSFunction::mark):
-        (KJS::JSFunction::getCallData):
-        (KJS::JSFunction::callAsFunction):
-        (KJS::JSFunction::argumentsGetter):
-        (KJS::JSFunction::callerGetter):
-        (KJS::JSFunction::lengthGetter):
-        (KJS::JSFunction::getOwnPropertySlot):
-        (KJS::JSFunction::put):
-        (KJS::JSFunction::deleteProperty):
-        (KJS::JSFunction::getParameterName):
-        (KJS::JSFunction::getConstructData):
-        (KJS::JSFunction::construct):
-        (KJS::IndexToNameMap::IndexToNameMap):
-        (KJS::Arguments::Arguments):
-        * kjs/function.h:
-        * kjs/function_object.cpp:
-        (KJS::functionProtoFuncToString):
-        (KJS::functionProtoFuncApply):
-        (KJS::FunctionObjectImp::construct):
-        * kjs/internal.cpp:
-        (KJS::JSString::toPrimitive):
-        (KJS::JSString::getPrimitiveNumber):
-        (KJS::JSString::toBoolean):
-        (KJS::JSString::toNumber):
-        (KJS::JSString::toString):
-        (KJS::StringInstance::create):
-        (KJS::JSString::toObject):
-        (KJS::JSString::toThisObject):
-        (KJS::JSString::lengthGetter):
-        (KJS::JSString::indexGetter):
-        (KJS::JSString::indexNumericPropertyGetter):
-        (KJS::JSString::getOwnPropertySlot):
-        (KJS::JSNumberCell::type):
-        (KJS::JSNumberCell::toPrimitive):
-        (KJS::JSNumberCell::getPrimitiveNumber):
-        (KJS::JSNumberCell::toBoolean):
-        (KJS::JSNumberCell::toNumber):
-        (KJS::JSNumberCell::toString):
-        (KJS::JSNumberCell::toObject):
-        (KJS::JSNumberCell::toThisObject):
-        (KJS::JSNumberCell::getUInt32):
-        (KJS::JSNumberCell::getTruncatedInt32):
-        (KJS::JSNumberCell::getTruncatedUInt32):
-        (KJS::GetterSetter::mark):
-        (KJS::GetterSetter::toPrimitive):
-        (KJS::GetterSetter::getPrimitiveNumber):
-        (KJS::GetterSetter::toBoolean):
-        (KJS::GetterSetter::toNumber):
-        (KJS::GetterSetter::toString):
-        (KJS::GetterSetter::toObject):
-        (KJS::GetterSetter::getOwnPropertySlot):
-        (KJS::GetterSetter::put):
-        (KJS::GetterSetter::toThisObject):
-        * kjs/internal.h:
-        (KJS::JSString::JSString):
-        (KJS::JSString::getStringPropertySlot):
-        * kjs/nodes.cpp:
-        (KJS::FuncDeclNode::makeFunction):
-        (KJS::FuncExprNode::makeFunction):
-        * kjs/nodes.h:
-        * kjs/object.cpp:
-        (KJS::JSObject::put):
-        (KJS::JSObject::deleteProperty):
-        (KJS::JSObject::defineGetter):
-        (KJS::JSObject::defineSetter):
-        (KJS::JSObject::lookupGetter):
-        (KJS::JSObject::lookupSetter):
-        (KJS::JSObject::fillGetterPropertySlot):
-        * kjs/object.h:
-        (KJS::GetterSetter::GetterSetter):
-        * kjs/operations.cpp:
-        (KJS::equal):
-        (KJS::strictEqual):
-        * kjs/property_map.cpp:
-        (KJS::PropertyMap::containsGettersOrSetters):
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpMatchesArray::getOwnPropertySlot):
-        (KJS::RegExpMatchesArray::put):
-        (KJS::RegExpMatchesArray::deleteProperty):
-        (KJS::RegExpMatchesArray::getPropertyNames):
-        (KJS::RegExpMatchesArray::RegExpMatchesArray):
-        (KJS::RegExpMatchesArray::fillArrayInstance):
-        * kjs/string_object.cpp:
-        (KJS::StringInstance::StringInstance):
-        (KJS::replace):
-        (KJS::stringProtoFuncReplace):
-        (KJS::stringProtoFuncToLowerCase):
-        (KJS::stringProtoFuncToUpperCase):
-        (KJS::stringProtoFuncToLocaleLowerCase):
-        (KJS::stringProtoFuncToLocaleUpperCase):
-        * kjs/string_object.h:
-        (KJS::StringInstance::internalValue):
-        * kjs/value.cpp:
-        (KJS::JSCell::getNumber):
-        (KJS::JSCell::getString):
-        (KJS::JSCell::getObject):
-        (KJS::jsString):
-        (KJS::jsOwnedString):
-        * kjs/value.h:
-        (KJS::JSNumberCell::JSNumberCell):
-        (KJS::jsNumberCell):
-        (KJS::JSValue::uncheckedGetNumber):
-        * profiler/Profiler.cpp:
-        (KJS::createCallIdentifier):
-        (KJS::createCallIdentifierFromFunctionImp):
-
-2008-06-15  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Alexey.
-        
-        - add emitUnaryOp, emitNullaryOp and emitUnaryOpNoDst; use them
-        
-        This removes some boilerplate code and also reduces the number of
-        places that will need to be changed to do on-demand emit of
-        loads (and thus support k operands).
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitUnaryOp):
-        (KJS::CodeGenerator::emitNullaryOp):
-        (KJS::CodeGenerator::emitUnaryOpNoDst):
-        (KJS::CodeGenerator::emitPushScope):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::emitNewObject):
-        (KJS::CodeGenerator::emitNewArray):
-        (KJS::CodeGenerator::emitNot):
-        (KJS::CodeGenerator::emitBitNot):
-        (KJS::CodeGenerator::emitToJSNumber):
-        (KJS::CodeGenerator::emitNegate):
-        (KJS::CodeGenerator::emitInstanceOf):
-        (KJS::CodeGenerator::emitTypeOf):
-        (KJS::CodeGenerator::emitIn):
-        (KJS::CodeGenerator::emitReturn):
-        (KJS::CodeGenerator::emitEnd):
-        (KJS::CodeGenerator::emitGetPropertyNames):
-
-2008-06-15  Alp Toker  <alp@nuanti.com>
-
-        Rubber-stamped by Maciej.
-
-        Install 'jsc' application by default.
-
-        * GNUmakefile.am:
-
-2008-06-15  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - rename testkjs to jsc
-
-        * GNUmakefile.am:
-        * JavaScriptCore.vcproj/JavaScriptCore.sln:
-        * JavaScriptCore.vcproj/jsc: Added.
-        * JavaScriptCore.vcproj/jsc/jsc.vcproj: Copied from JavaScriptCore.vcproj/testkjs/testkjs.vcproj.
-        * JavaScriptCore.vcproj/testkjs: Removed.
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj: Removed.
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * jscore.bkl:
-        * kjs/Shell.cpp: Copied from kjs/testkjs.cpp.
-        (main):
-        (printUsageStatement):
-        (jscmain):
-        * kjs/jsc.pro: Copied from kjs/testkjs.pro.
-        * kjs/testkjs.cpp: Removed.
-        * kjs/testkjs.pro: Removed.
-        * tests/mozilla/expected.html:
-        * tests/mozilla/js1_2/Array/tostring_1.js:
-        * tests/mozilla/js1_2/Array/tostring_2.js:
-        * tests/mozilla/jsDriver.pl:
-
-2008-06-15  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Mac build fix.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/nodes.h:
-
-2008-06-15  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Change the spelling of PrecMultiplicitave to PrecMultiplicative.
-
-        * kjs/nodes.h:
-        (KJS::MultNode::precedence):
-        (KJS::DivNode::precedence):
-        (KJS::ModNode::precedence):
-
-2008-06-15  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Remove unused preprocessor macros related to exceptions in the old
-        interpreter.
-
-        * kjs/nodes.cpp:
-
-2008-06-15  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 19484: More instructions needs to use temporary registers
-        <https://bugs.webkit.org/show_bug.cgi?id=19484>
-
-        Fix codegen for all binary operations so that temporaries are used if
-        necessary. This was done by making BinaryOpNode and ReverseBinaryOpNode
-        subclasses of ExpressionNode, and eliminating the custom emitCode()
-        methods for the individual node classes.
-
-        This only adds 3 new instructions to SunSpider code, and there is no
-        difference in SunSpider execution time.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitBitNot):
-        (KJS::CodeGenerator::emitBinaryOp):
-        * VM/CodeGenerator.h:
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::PreIncResolveNode::emitCode):
-        (KJS::PreDecResolveNode::emitCode):
-        (KJS::BinaryOpNode::emitCode):
-        (KJS::ReverseBinaryOpNode::emitCode):
-        (KJS::emitReadModifyAssignment):
-        (KJS::CaseBlockNode::emitCodeForBlock):
-        * kjs/nodes.h:
-        (KJS::BinaryOpNode::BinaryOpNode):
-        (KJS::ReverseBinaryOpNode::ReverseBinaryOpNode):
-        (KJS::MultNode::):
-        (KJS::DivNode::):
-        (KJS::DivNode::precedence):
-        (KJS::ModNode::):
-        (KJS::ModNode::precedence):
-        (KJS::AddNode::):
-        (KJS::AddNode::precedence):
-        (KJS::SubNode::):
-        (KJS::SubNode::precedence):
-        (KJS::LeftShiftNode::):
-        (KJS::LeftShiftNode::precedence):
-        (KJS::RightShiftNode::):
-        (KJS::RightShiftNode::precedence):
-        (KJS::UnsignedRightShiftNode::):
-        (KJS::UnsignedRightShiftNode::precedence):
-        (KJS::LessNode::):
-        (KJS::LessNode::precedence):
-        (KJS::GreaterNode::):
-        (KJS::GreaterNode::precedence):
-        (KJS::LessEqNode::):
-        (KJS::LessEqNode::precedence):
-        (KJS::GreaterEqNode::):
-        (KJS::GreaterEqNode::precedence):
-        (KJS::InstanceOfNode::):
-        (KJS::InstanceOfNode::precedence):
-        (KJS::InNode::):
-        (KJS::InNode::precedence):
-        (KJS::EqualNode::):
-        (KJS::EqualNode::precedence):
-        (KJS::NotEqualNode::):
-        (KJS::NotEqualNode::precedence):
-        (KJS::StrictEqualNode::):
-        (KJS::StrictEqualNode::precedence):
-        (KJS::NotStrictEqualNode::):
-        (KJS::NotStrictEqualNode::precedence):
-        (KJS::BitAndNode::):
-        (KJS::BitAndNode::precedence):
-        (KJS::BitOrNode::):
-        (KJS::BitOrNode::precedence):
-        (KJS::BitXOrNode::):
-        (KJS::BitXOrNode::precedence):
-        * kjs/nodes2string.cpp:
-        (KJS::LessNode::streamTo):
-        (KJS::GreaterNode::streamTo):
-        (KJS::LessEqNode::streamTo):
-        (KJS::GreaterEqNode::streamTo):
-        (KJS::InstanceOfNode::streamTo):
-        (KJS::InNode::streamTo):
-        (KJS::EqualNode::streamTo):
-        (KJS::NotEqualNode::streamTo):
-        (KJS::StrictEqualNode::streamTo):
-        (KJS::NotStrictEqualNode::streamTo):
-        (KJS::BitAndNode::streamTo):
-        (KJS::BitXOrNode::streamTo):
-        (KJS::BitOrNode::streamTo):
-
-2008-06-14  Darin Adler  <darin@apple.com>
-
-        Rubber stamped by Sam.
-
-        - rename a bunch of local symbols within the regular expression code to
-          follow our usual coding style, and do a few other name tweaks
-
-        * pcre/pcre_compile.cpp:
-        (CompileData::CompileData):
-        (checkEscape):
-        (readRepeatCounts):
-        (compileBranch):
-        (compileBracket):
-        (calculateCompiledPatternLength):
-        (returnError):
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (MatchStack::MatchStack):
-        (MatchStack::canUseStackBufferForNextFrame):
-        (MatchStack::popCurrentFrame):
-        (match):
-        (tryFirstByteOptimization):
-        (tryRequiredByteOptimization):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2008-06-14  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Darin.
-
-        Remove redundant uses of get().
-
-        * kjs/nodes.cpp:
-        (KJS::BracketAccessorNode::emitCode):
-        (KJS::AddNode::emitCode):
-        (KJS::SubNode::emitCode):
-        (KJS::ReadModifyResolveNode::emitCode):
-        (KJS::AssignDotNode::emitCode):
-        (KJS::ReadModifyDotNode::emitCode):
-        (KJS::AssignBracketNode::emitCode):
-        (KJS::ReadModifyBracketNode::emitCode):
-
-2008-06-14  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Make code generation not use a temporary for the left-hand side of an
-        expression if the right-hand side is a local variable.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::isLocal):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::leftHandSideNeedsCopy):
-        (KJS::CodeGenerator::emitNodeForLeftHandSide):
-        * kjs/nodes.cpp:
-        (KJS::ResolveNode::isPure):
-        (KJS::BracketAccessorNode::emitCode):
-        (KJS::AddNode::emitCode):
-        (KJS::SubNode::emitCode):
-        (KJS::ReadModifyResolveNode::emitCode):
-        (KJS::AssignDotNode::emitCode):
-        (KJS::ReadModifyDotNode::emitCode):
-        (KJS::AssignBracketNode::emitCode):
-        (KJS::ReadModifyBracketNode::emitCode):
-        * kjs/nodes.h:
-        (KJS::ExpressionNode::):
-        (KJS::BooleanNode::):
-        (KJS::NumberNode::):
-        (KJS::StringNode::):
-
-2008-06-14  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        - more of https://bugs.webkit.org/show_bug.cgi?id=17257
-          start ref counts at 1 instead of 0 for speed
-
-        * kjs/nodes.cpp:
-        (KJS::ParserRefCounted::hasOneRef): Added. Replaces refcount.
-        * kjs/nodes.h: Replaced refcount with hasOneRef.
-
-        * wtf/ListRefPtr.h:
-        (WTF::ListRefPtr::~ListRefPtr): Changed to use hasOneRef instead of
-        refcount, so this class can be used with the RefCounted template.
-
-        * wtf/RefCounted.h:
-        (WTF::RefCounted::hasOneRef): Made const, since there's no reason for
-        it to be non-const.
-
-2008-06-14  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - initialize local vars as side effect of call instead of in bytecode
-        1.004x speedup on SunSpider.
-
-        This removes just the dispatch overhead for these loads - in the
-        future, dead store elimination might be able to eliminate them
-        entirely.
-        
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator): For function blocks, don't
-        emit loads of undefined for var initialization.
-        * VM/Machine.cpp:
-        (KJS::slideRegisterWindowForCall): Instead, initialize locals
-        as part of the call.
-
-2008-06-14  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Remove helper functions in the parser that are no longer needed.
-
-        * kjs/grammar.y:
-
-2008-06-14  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 19484: More instructions needs to use temporary registers
-        <https://bugs.webkit.org/show_bug.cgi?id=19484>
-
-        Make code generation for AddNode and SubNode use temporaries when
-        necessary.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::AddNode::emitCode):
-        (KJS::SubNode::emitCode):
-        * kjs/nodes.h:
-        (KJS::AddNode::):
-        (KJS::SubNode::):
-
-2008-06-13  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Combine TrueNode and FalseNode to make BooleanNode, and remove the
-        unused class PlaceholderTrueNode.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::BooleanNode::emitCode):
-        * kjs/nodes.h:
-        (KJS::BooleanNode::):
-        (KJS::BooleanNode::precedence):
-        * kjs/nodes2string.cpp:
-        (KJS::BooleanNode::streamTo):
-
-2008-06-13  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Eliminate the use of temporaries to store the left hand side of an
-        expression when the right hand side is a constant. This slightly
-        improves the generated bytecode for a few SunSpider tests, but it is
-        mostly in preparation for fixing
-
-        Bug 19484: More instructions needs to use temporary registers
-        <https://bugs.webkit.org/show_bug.cgi?id=19484>
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::leftHandSideNeedsCopy):
-        (KJS::CodeGenerator::emitNodeForLeftHandSide):
-        * kjs/nodes.cpp:
-        (KJS::BracketAccessorNode::emitCode):
-        (KJS::ReadModifyResolveNode::emitCode):
-        (KJS::AssignDotNode::emitCode):
-        (KJS::ReadModifyDotNode::emitCode):
-        (KJS::AssignBracketNode::emitCode):
-        (KJS::ReadModifyBracketNode::emitCode):
-        * kjs/nodes.h:
-        (KJS::ExpressionNode::):
-        (KJS::FalseNode::):
-        (KJS::TrueNode::):
-        (KJS::NumberNode::):
-        (KJS::StringNode::):
-
-2008-06-13  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - prettify opcode stats output
-        
-        I changed things to be a bit more aligned, also there is a new
-        section listing most common opcodes and most common sequences that
-        include them.
-
-        * VM/Opcode.cpp:
-        (KJS::OpcodeStats::~OpcodeStats):
-        * VM/Opcode.h:
-
-2008-06-13  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Geoff.
-
-        <rdar://problem/5969992> JSProfiler: Remove the recursion limit in the
-        profiler.
-        - Remove recursion from exclude().  This leaves only focus() to fix.
-
-        * JavaScriptCore.exp: Change the signatures of the exported functions.
-        * profiler/Profile.cpp:
-        (KJS::Profile::forEach): I added a traverseNextNodePreOrder() function
-        and so needed to distinguish the other function by labeling it
-        traverseNextNodePostOrder().
-        (KJS::Profile::exclude): All new exclude that iteratively walks the tree
-        * profiler/Profile.h:
-        (KJS::Profile::focus): Add a null check for m_head.
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::traverseNextNodePostOrder): Renamed
-        (KJS::ProfileNode::traverseNextNodePreOrder): Walks the tree in pre-
-        order, where the parent is processed before the children.
-        (KJS::ProfileNode::setTreeVisible): Iterate over the sub-tree and set
-        all of the nodes visible value.  This changes another function that used
-        recursion.
-        (KJS::ProfileNode::exclude): Remove recursion from this function.
-        Because we now check for m_visible and we are walking the tree in pre-
-        order we do not need to check if an excluded node is in an excluded
-        sub-tree.
-        * profiler/ProfileNode.h: Added specific selfTime functions to
-        facilitate exclude().
-        (KJS::ProfileNode::setSelfTime):
-        (KJS::ProfileNode::setActualSelfTime):
-        (KJS::ProfileNode::setVisibleSelfTime):
-
-2008-06-12  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - https://bugs.webkit.org/show_bug.cgi?id=19434
-          speed up SunSpider by avoiding some string boxing
-
-        Speeds up SunSpider by 1.1%.
-
-        Optimized code path for getting built-in properties from strings -- avoid
-        boxing with a string object in that case. We can make further changes to avoid
-        even more boxing, but this change alone is a win.
-
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::JSCallbackObject::staticValueGetter): Use isObject instead of inherits
-        in asssert, since the type of slotBase() is now JSValue, not JSObject.
-        (KJS::JSCallbackObject::staticFunctionGetter): Ditto.
-        (KJS::JSCallbackObject::callbackGetter): Ditto.
-
-        * kjs/internal.cpp:
-        (KJS::StringImp::getPrimitiveNumber): Updated for change of data member name.
-        (KJS::StringImp::toBoolean): Ditto.
-        (KJS::StringImp::toNumber): Ditto.
-        (KJS::StringImp::toString): Ditto.
-        (KJS::StringInstance::create): Added; avoids a bit of cut and paste code.
-        (KJS::StringImp::toObject): Use StringInstance::create.
-        (KJS::StringImp::toThisObject): Ditto.
-        (KJS::StringImp::lengthGetter): Added. Replaces the getter that used to live in
-        the StringInstance class.
-        (KJS::StringImp::indexGetter): Ditto.
-        (KJS::StringImp::indexNumericPropertyGetter): Ditto.
-        (KJS::StringImp::getOwnPropertySlot): Added. Deals with built in properties of
-        the string class without creating a StringInstance.
-
-        * kjs/internal.h:
-        (KJS::StringImp::getStringPropertySlot): Added. To be used by both the string
-        and string object getOwnPropertySlot function.
-
-        * kjs/lookup.h:
-        (KJS::staticFunctionGetter): Updated since slotBase() is now a JSValue rather
-        than a JSObject.
-
-        * kjs/object.h: Removed PropertySlot::slotBase() function, which can now move
-        back into property_slot.h where it belongs since it doesn't have to cast to
-        JSObject*.
-
-        * kjs/property_slot.cpp:
-        (KJS::PropertySlot::functionGetter): Updated since slot.slotBase() is now a JSValue*
-        instead of JSObject*. setGetterSlot still guarantees the base is a JSObject*.
-        * kjs/property_slot.h:
-        (KJS::PropertySlot::PropertySlot): Changed base to JSValue* intead of JSCell*.
-        (KJS::PropertySlot::setStaticEntry): Ditto.
-        (KJS::PropertySlot::setCustom): Ditto.
-        (KJS::PropertySlot::setCustomIndex): Ditto.
-        (KJS::PropertySlot::setCustomNumeric): Ditto.
-        (KJS::PropertySlot::slotBase): Moved inline here since it no longer involves a
-        downcast to JSObject*.
-        (KJS::PropertySlot::setBase): Changed to JSValue*.
-
-        * kjs/string_object.cpp:
-        (KJS::StringInstance::getOwnPropertySlot): Changed to use getStringPropertySlot
-        instead of coding the properties here. This allows sharing the code with StringImp.
-
-        * kjs/string_object.h: Removed inlineGetOwnPropertySlot, lengthGetter, and indexGetter.
-        Made one of the constructors protected.
-
-        * kjs/value.h: Made getOwnPropertySlot private in the JSCell class -- this is better
-        since it's not the real JSObject getOwnPropertySlot semantic and most callers shouldn't
-        use it.
-
-2008-06-12  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Maciej.
-
-        Preparation to making JavaScript heap per-thread.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::collect):
-        * kjs/collector.h:
-        (KJS::Collector::markListSet):
-        The collector now holds the list of protected lists itself, to be made per-instance.
-
-        * kjs/list.h: Changed to hold a pointer to a mark set this list is in, if any.
-        (KJS::List::List): Explicitly initialize m_size with zero, as m_vector.size() is
-        guaranteed to be such anyway.
-        (KJS::List::append): Changed the fast case to only be executed as long as inline buffer
-        is used, because otherwise, we now do more expensive checks.
-
-        * kjs/list.cpp:
-        (KJS::List::markLists): Renamed from markProtectedListsSlowCase, made it take the list set
-        as a parameter.
-        (KJS::List::slowAppend): If a non-immediate value is appended, the list needs to be added
-        to an appropriate Heap's protected list. For now, a static Collector::markListSet() is
-        used, but the code is layed out in preparation to making the switch to multiple heaps.
-
-        * JavaScriptCore.exp: Updated export list.
-
-2008-06-12  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 19510: CodeBlock::needsFullScopeChain not always set for global code
-        <https://bugs.webkit.org/show_bug.cgi?id=19510>
-
-        This fixes the symptoms by using CodeGenerator::m_codeType to determine
-        when to use temporaries instead of CodeBlock::needsFullScopeChain, but
-        it does not fix the problem itself.
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::leftHandSideNeedsCopy):
-
-2008-06-11  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 19498: REGRESSION (r34497): crash while loading GMail
-        <https://bugs.webkit.org/show_bug.cgi?id=19498>
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitJumpIfTrueMayCombine):
-        (KJS::CodeGenerator::emitJumpIfTrue):
-        * VM/CodeGenerator.h:
-        * kjs/nodes.cpp:
-        (KJS::DoWhileNode::emitCode):
-        (KJS::WhileNode::emitCode):
-        (KJS::ForNode::emitCode):
-        (KJS::CaseBlockNode::emitCodeForBlock):
-
-2008-06-11  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - a little bit of cleanup and prep for some upcoming optimizations
-
-        * JavaScriptCore.exp: Re-sorted this file (with sort command line tool).
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump): Fixed printf to avoid warnings -- to use %lu we
-        need to make sure the type is unsigned long.
-        * kjs/object.cpp:
-        (KJS::Error::create): Eliminated unused error names array, and also put
-        the strings into the code since there was already a switch statment.
-        This also avoids having to contemplate a hypothetical access past the
-        end of the array.
-        * kjs/object.h: Got rid of errorNames.
-        * kjs/property_slot.cpp: Deleted unused ungettableGetter.
-        * kjs/property_slot.h: Ditto.
-        * wtf/AlwaysInline.h: Added LIKELY alongside UNLIKELY.
-
-2008-06-11  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Darin.
-
-        Bug 19457: Create fused opcodes for tests and conditional jumps
-        <https://bugs.webkit.org/show_bug.cgi?id=19457>
-
-        Add a new jless instruction, and modify the code generator to emit it
-        instead of the pair (less, jtrue).
-
-        Gives a 3.6% improvement on SunSpider.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::emitOpcode):
-        (KJS::CodeGenerator::retrieveLastBinaryOp):
-        (KJS::CodeGenerator::rewindBinaryOp):
-        (KJS::CodeGenerator::emitJump):
-        (KJS::CodeGenerator::emitJumpIfTrue):
-        (KJS::CodeGenerator::emitJumpIfFalse):
-        (KJS::CodeGenerator::emitMove):
-        (KJS::CodeGenerator::emitNot):
-        (KJS::CodeGenerator::emitEqual):
-        (KJS::CodeGenerator::emitNotEqual):
-        (KJS::CodeGenerator::emitStrictEqual):
-        (KJS::CodeGenerator::emitNotStrictEqual):
-        (KJS::CodeGenerator::emitLess):
-        (KJS::CodeGenerator::emitLessEq):
-        (KJS::CodeGenerator::emitPreInc):
-        (KJS::CodeGenerator::emitPreDec):
-        (KJS::CodeGenerator::emitPostInc):
-        (KJS::CodeGenerator::emitPostDec):
-        (KJS::CodeGenerator::emitToJSNumber):
-        (KJS::CodeGenerator::emitNegate):
-        (KJS::CodeGenerator::emitAdd):
-        (KJS::CodeGenerator::emitMul):
-        (KJS::CodeGenerator::emitDiv):
-        (KJS::CodeGenerator::emitMod):
-        (KJS::CodeGenerator::emitSub):
-        (KJS::CodeGenerator::emitLeftShift):
-        (KJS::CodeGenerator::emitRightShift):
-        (KJS::CodeGenerator::emitUnsignedRightShift):
-        (KJS::CodeGenerator::emitBitAnd):
-        (KJS::CodeGenerator::emitBitXOr):
-        (KJS::CodeGenerator::emitBitOr):
-        (KJS::CodeGenerator::emitBitNot):
-        (KJS::CodeGenerator::emitInstanceOf):
-        (KJS::CodeGenerator::emitTypeOf):
-        (KJS::CodeGenerator::emitIn):
-        (KJS::CodeGenerator::emitLoad):
-        (KJS::CodeGenerator::emitNewObject):
-        (KJS::CodeGenerator::emitNewArray):
-        (KJS::CodeGenerator::emitResolve):
-        (KJS::CodeGenerator::emitGetScopedVar):
-        (KJS::CodeGenerator::emitPutScopedVar):
-        (KJS::CodeGenerator::emitResolveBase):
-        (KJS::CodeGenerator::emitResolveWithBase):
-        (KJS::CodeGenerator::emitResolveFunction):
-        (KJS::CodeGenerator::emitGetById):
-        (KJS::CodeGenerator::emitPutById):
-        (KJS::CodeGenerator::emitPutGetter):
-        (KJS::CodeGenerator::emitPutSetter):
-        (KJS::CodeGenerator::emitDeleteById):
-        (KJS::CodeGenerator::emitGetByVal):
-        (KJS::CodeGenerator::emitPutByVal):
-        (KJS::CodeGenerator::emitDeleteByVal):
-        (KJS::CodeGenerator::emitPutByIndex):
-        (KJS::CodeGenerator::emitNewFunction):
-        (KJS::CodeGenerator::emitNewRegExp):
-        (KJS::CodeGenerator::emitNewFunctionExpression):
-        (KJS::CodeGenerator::emitCall):
-        (KJS::CodeGenerator::emitReturn):
-        (KJS::CodeGenerator::emitEnd):
-        (KJS::CodeGenerator::emitConstruct):
-        (KJS::CodeGenerator::emitPushScope):
-        (KJS::CodeGenerator::emitPopScope):
-        (KJS::CodeGenerator::emitDebugHook):
-        (KJS::CodeGenerator::emitComplexJumpScopes):
-        (KJS::CodeGenerator::emitJumpScopes):
-        (KJS::CodeGenerator::emitNextPropertyName):
-        (KJS::CodeGenerator::emitGetPropertyNames):
-        (KJS::CodeGenerator::emitCatch):
-        (KJS::CodeGenerator::emitThrow):
-        (KJS::CodeGenerator::emitNewError):
-        (KJS::CodeGenerator::emitJumpSubroutine):
-        (KJS::CodeGenerator::emitSubroutineReturn):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.cpp:
-        * VM/Opcode.h:
-
-2008-06-11  Darin Adler  <darin@apple.com>
-
-        Reviewed by Alexey.
-
-        - fix https://bugs.webkit.org/show_bug.cgi?id=19442
-          JavaScript array implementation doesn't maintain m_numValuesInVector when sorting
-
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::checkConsistency): Added. Empty inline version for when
-        consistency checks are turned off.
-        (KJS::ArrayInstance::ArrayInstance): Check consistency after construction.
-        (KJS::ArrayInstance::~ArrayInstance): Check consistency before destruction.
-        (KJS::ArrayInstance::put): Check consistency before and after.
-        (KJS::ArrayInstance::deleteProperty): Ditto.
-        (KJS::ArrayInstance::setLength): Ditto.
-        (KJS::compareByStringPairForQSort): Use typedef for clarity.
-        (KJS::ArrayInstance::sort): Check consistency before and after. Also broke the loop
-        to set up sorting into two separate passes. Added FIXMEs about various exception
-        safety issues. Added code to set m_numValuesInVector after sorting.
-        (KJS::ArrayInstance::compactForSorting): Ditto.
-
-        * kjs/array_instance.h: Added a definition of an enum for the types of consistency
-        check and a declaration of the consistency checking function.
-
-2008-06-10  Kevin Ollivier  <kevino@theolliviers.com>
-
-        wx build fix. Link against libedit on Mac since HAVE(READLINE) is defined there.
-
-        * jscore.bkl:
-
-2008-06-10  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        https://bugs.webkit.org/show_bug.cgi?id=16503
-        match limit takes at least 13% of the time on the SunSpider regexp-dna test
-
-        Make the limit test slightly more efficient. It is not clear how much of a win it is,
-        as the improvement on regexp-dna varies from 2.3% to 0.6% depending on what revision I
-        apply the patch to. Today, the win on regexp-dna was minimal, but the total win was whopping
-        0.5%, due to random code generation changes.
-
-        * pcre/pcre_exec.cpp: (match): Avoid loading a constant on each iteration.
-
-2008-06-09  Alp Toker  <alp@nuanti.com>
-
-        gcc3/autotools build fix. Add explicit -O2 -fno-strict-aliasing to
-        each of the tools since these are no longer set globally.
-
-        * GNUmakefile.am:
-
-2008-06-09  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Sam.
-
-        Add an include for readline/history.h to fix the build for Darwin users
-        with the GNU readline library installed. Also, clean up the style of
-        the HAVE(READLINE) check.
-
-        * kjs/testkjs.cpp:
-        (runInteractive):
-
-2008-06-09  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Darin.
-
-        Bug 17531: Add interactive mode to testkjs
-        <https://bugs.webkit.org/show_bug.cgi?id=17531>
-
-        This is a cleaned up version of Sam's earlier patch to add an
-        interactive mode to testkjs.
-
-        Readline support is only enabled on Darwin platforms for now, but
-        other ports can enable it by defining HAVE_READLINE in kjs/config.h.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/config.h:
-        * kjs/testkjs.cpp:
-        (Options::Options):
-        (runWithScripts):
-        (runInteractive):
-        (printUsageStatement):
-        (parseArguments):
-        (kjsmain):
-
-2008-06-08  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Darin.
-
-        Bug 19346: REGRESSION: Mootools 1.2 Class inheritance broken in post-SquirrelFish merge
-        <https://bugs.webkit.org/show_bug.cgi?id=19346>
-
-        A check for whether a function's caller is eval code accidentally included
-        the case where the caller's caller is native code. Add a CodeType field to
-        CodeBlock and use this for the eval caller test instead.
-
-        * VM/CodeBlock.h:
-        (KJS::CodeBlock::CodeBlock):
-        (KJS::ProgramCodeBlock::ProgramCodeBlock):
-        (KJS::EvalCodeBlock::EvalCodeBlock):
-        * VM/Machine.cpp:
-        (KJS::getCallerFunctionOffset):
-        * kjs/nodes.cpp:
-        (KJS::FunctionBodyNode::generateCode):
-        (KJS::ProgramNode::generateCode):
-
-2008-06-07  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Dan Bernstein.
-
-        Bug 17928: testkjs shouldn't require "-f"
-        <https://bugs.webkit.org/show_bug.cgi?id=17928>
-
-        * kjs/testkjs.cpp:
-        (printUsageStatement):
-        (parseArguments):
-
-2008-06-07  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Eric.
-
-        Bug 17548: JavaScriptCore print(a, b) differs from Spidermonkey Behavior
-        <https://bugs.webkit.org/show_bug.cgi?id=17548>
-
-        * kjs/testkjs.cpp:
-        (functionPrint):
-
-2008-06-07  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Sam.
-
-        Bug 17547: JavaScriptCore print() differs from Spidermonkey Behavior
-        <https://bugs.webkit.org/show_bug.cgi?id=17547>
-
-        * kjs/testkjs.cpp:
-        (functionPrint):
-
-2008-06-07  Alexey Proskuryakov  <ap@webkit.org>
-
-        More build fixes.
-
-        * kjs/JSGlobalData.cpp: Fixed an included file name for case-sensitive file systems, fixed
-        JSGlobalData::threadInstance() for non-multithreaded builds.
-
-2008-06-07  Alexey Proskuryakov  <ap@webkit.org>
-
-        Build fix - actually adding JSGlobalData.cpp to non-Mac builds!
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCoreSources.bkl:
-
-2008-06-07  Alexey Proskuryakov  <ap@webkit.org>
-
-        Try to fix Gtk/gcc 4.3 build.
-
-        * kjs/JSGlobalData.h: Include ustring.h instead of forward-declaring UString::Rep.
-
-2008-06-06  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Combine per-thread objects into one, to make it easier to support legacy clients (for
-        which they shouldn't be really per-thread).
-
-        No change on SunSpider total.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Added JSGlobalData.{h,cpp}
-
-        * kjs/JSGlobalData.cpp: Added.
-        (KJS::JSGlobalData::JSGlobalData):
-        (KJS::JSGlobalData::~JSGlobalData):
-        (KJS::JSGlobalData::threadInstance):
-        * kjs/JSGlobalData.h: Added.
-        This class encapsulates all data that should be per-thread (or shared between legacy clients).
-        It will also keep a Heap pointer, but right now, Heap (Collector) methods are all static.
-
-        * kjs/identifier.h:
-        (KJS::Identifier::Identifier):
-        Added a constructor explicitly taking JSGlobalData to access IdentifierTable. Actually,
-        all of them should, but this will be a separate patch.
-
-        * kjs/identifier.cpp:
-        (KJS::IdentifierTable::literalTable):
-        (KJS::createIdentifierTable):
-        (KJS::deleteIdentifierTable):
-        (KJS::Identifier::add):
-        (KJS::Identifier::addSlowCase):
-        Combined IdentifierTable and LiteralIdentifierTable into a single class for simplicity.
-
-        * kjs/grammar.y: kjsyyparse now takes JSGlobalData, not just a Lexer.
-
-        * kjs/nodes.cpp:
-        (KJS::Node::Node):
-        (KJS::EvalFunctionCallNode::emitCode):
-        (KJS::ScopeNode::ScopeNode):
-        Changed to access Lexer and Parser via JSGlobalData::threadInstance(). This is also a
-        temporary measure, they will need to use JSGlobalData explicitly.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::callEval):
-        * kjs/CommonIdentifiers.cpp:
-        (KJS::CommonIdentifiers::CommonIdentifiers):
-        * kjs/CommonIdentifiers.h:
-        * kjs/DebuggerCallFrame.cpp:
-        (KJS::DebuggerCallFrame::evaluate):
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        * kjs/ExecState.h:
-        (KJS::ExecState::globalData):
-        (KJS::ExecState::identifierTable):
-        (KJS::ExecState::propertyNames):
-        (KJS::ExecState::emptyList):
-        (KJS::ExecState::lexer):
-        (KJS::ExecState::parser):
-        (KJS::ExecState::arrayTable):
-        (KJS::ExecState::dateTable):
-        (KJS::ExecState::mathTable):
-        (KJS::ExecState::numberTable):
-        (KJS::ExecState::RegExpImpTable):
-        (KJS::ExecState::RegExpObjectImpTable):
-        (KJS::ExecState::stringTable):
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreadingOnce):
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::init):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData):
-        (KJS::JSGlobalObject::head):
-        (KJS::JSGlobalObject::globalData):
-        * kjs/Parser.cpp:
-        (KJS::Parser::parse):
-        * kjs/Parser.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::getParameterName):
-        (KJS::IndexToNameMap::unMap):
-        (KJS::globalFuncEval):
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct):
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::checkSyntax):
-        (KJS::Interpreter::evaluate):
-        * kjs/lexer.cpp:
-        (kjsyylex):
-        * kjs/lexer.h:
-        * kjs/testkjs.cpp:
-        (prettyPrintScript):
-        Updated for the above changes. Most of threadInstance uses here will need to be replaced with
-        explicitly passed pointers to support legacy JSC clients.
-
-        * JavaScriptCore.exp: Removed KJS::parser().
-
-2008-06-06  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 19424: Add support for logging opcode pair counts
-        <https://bugs.webkit.org/show_bug.cgi?id=19424>
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.cpp:
-        (KJS::OpcodeStats::OpcodeStats):
-        (KJS::compareOpcodeIndices):
-        (KJS::compareOpcodePairIndices):
-        (KJS::OpcodeStats::~OpcodeStats):
-        (KJS::OpcodeStats::recordInstruction):
-        (KJS::OpcodeStats::resetLastInstruction):
-        * VM/Opcode.h:
-
-2008-06-06  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Adam.
-
-        <rdar://problem/5969992> JSProfiler: Remove the recursion limit in the
-        profiler.
-        - Change the remaining functions that do not take arguments, from using
-        recursion to using iteration.
-
-        * JavaScriptCore.exp:
-        * profiler/Profile.cpp:
-        (KJS::stopProfiling):
-        (KJS::restoreAll):
-        (KJS::Profile::stopProfiling): Use foreach instead of recursion.
-        (KJS::Profile::restoreAll): Ditto.
-        * profiler/Profile.h:
-        * profiler/ProfileNode.cpp: Remove recursion.
-        (KJS::ProfileNode::stopProfiling):
-        (KJS::ProfileNode::restore):
-        * profiler/ProfileNode.h:
-
-2008-06-05  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Alexey.
-
-        Fix Greater and GreaterEq nodes to emit code for the left
-        and right sub-expressions in the correct order.
-
-        * kjs/nodes.cpp:
-        (KJS::GreaterNode::emitCode):
-        (KJS::GreaterEqNode::emitCode):
-
-2008-06-05  Antti Koivisto  <antti@apple.com>
-
-        Reviewed by Alp Toker.
-        
-        Fix whitespaces.
-
-        * kjs/collector.cpp:
-        (KJS::getPlatformThreadRegisters):
-
-2008-06-05  Antti Koivisto  <antti@apple.com>
-
-        Reviewed by Darin.
-        
-        Support compiling JavaScriptCore for ARM.
-
-        * kjs/collector.cpp:
-        (KJS::getPlatformThreadRegisters):
-        (KJS::otherThreadStackPointer):
-
-2008-06-05  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Jon.
-
-        - Name changes.
-
-        * JavaScriptCore.exp:
-        * profiler/Profile.cpp:
-        (KJS::Profile::Profile):
-        (KJS::Profile::stopProfiling):
-        (KJS::Profile::didExecute):
-        (KJS::Profile::forEach):
-        (KJS::Profile::debugPrintData):
-        (KJS::Profile::debugPrintDataSampleStyle):
-        * profiler/Profile.h:
-        (KJS::Profile::callTree):
-        (KJS::Profile::totalTime):
-        (KJS::Profile::sortTotalTimeDescending):
-        (KJS::Profile::sortTotalTimeAscending):
-        (KJS::Profile::sortSelfTimeDescending):
-        (KJS::Profile::sortSelfTimeAscending):
-        (KJS::Profile::sortCallsDescending):
-        (KJS::Profile::sortCallsAscending):
-        (KJS::Profile::sortFunctionNameDescending):
-        (KJS::Profile::sortFunctionNameAscending):
-        (KJS::Profile::focus):
-        (KJS::Profile::exclude):
-        (KJS::Profile::restoreAll):
-
-2008-06-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Stephanie Lewis.
-
-        Added the -fno-move-loop-invariants flag to the pcre_exec.cpp build, to
-        tell GCC not to perform loop invariant motion, since GCC's loop
-        invariant motion doesn't do very well with computed goto code.
-        
-        SunSpider reports no change.
-
-2008-06-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Stephanie Lewis.
-        
-        Added the -fno-tree-pre flag to the Machine.cpp build, to tell GCC not
-        to perform Partial Redundancy Elimination (PRE) on trees in Machine.cpp,
-        since GCC's PRE doesn't do very well with computed goto code.
-        
-        SunSpider reports a .7% speedup.
-        
-2008-06-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Stephanie Lewis (or maybe the other way around).
-        
-        Minor change to PCRE to help out certain compilers.
-        
-        SunSpider reports no change, maybe a small speedup.
-
-        * pcre/pcre_exec.cpp:
-        (match): Use instructionPtr++ a little less, to avoid confusing the
-        optimizer.
-
-2008-06-05  Alexey Proskuryakov  <ap@webkit.org>
-
-        Re-landing an independent part of a previously rolled out threading patch.
-
-        * wtf/ThreadSpecific.h: Make sure to initialize POD thread-specific varaibles, too
-        (replaced "new T" with "new T()").
-
-2008-06-05  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Hyatt.
-        
-        - force inlining of a template function that only has one call site per specialization
-        1.3% speedup on SunSpider
-
-        * kjs/collector.cpp:
-        (KJS::Collector::heapAllocate): This template function is only
-        called from allocate() and allocateNumber() (once per
-        specialization) and the extra call overhead for GC allocation
-        shows up, so force inlining.
-
-2008-06-05  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Alexey and Oliver.
-        
-        - remove profiler fetch hack
-        I measure an 0.5% progression from this, others show a wash. It seems not needed any more.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-06-05  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 19400: subscript operator does not protect base when necessary
-        <https://bugs.webkit.org/show_bug.cgi?id=19400>
-
-        Use a temporary for the base in BracketAccessorNode if the subscript
-        might possibly modify it.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::BracketAccessorNode::emitCode):
-        * kjs/nodes.h:
-        (KJS::BracketAccessorNode::):
-
-2008-06-04  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Maciej Stachowiak.
-
-        Big cleanup of formatting and whitespace.
-
-2008-06-04  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Add an option to dump statistics on executed instructions.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.cpp:
-        (KJS::OpcodeStats::~OpcodeStats):
-        (KJS::OpcodeStats::recordInstruction):
-        * VM/Opcode.h:
-
-2008-06-04  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Geoff.
-
-        <rdar://problem/5969992> JSProfiler: Remove the recursion limit in the
-        profiler.
-        - This patch removes the use of recursion for the sort functions.
-
-        * JavaScriptCore.exp: Change the signatures of the functions being
-        exported.
-        * profiler/Profile.cpp:
-        (KJS::Profile::sort): This generic function will accept any of the
-        static sort functions and apply them to the whole tree.
-        * profiler/Profile.h: All of the sorting functions now call the new
-        sort() function.
-        (KJS::Profile::sortTotalTimeDescending):
-        (KJS::Profile::sortTotalTimeAscending):
-        (KJS::Profile::sortSelfTimeDescending):
-        (KJS::Profile::sortSelfTimeAscending):
-        (KJS::Profile::sortCallsDescending):
-        (KJS::Profile::sortCallsAscending):
-        (KJS::Profile::sortFunctionNameDescending):
-        (KJS::Profile::sortFunctionNameAscending):
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::ProfileNode): m_head used to point to the head node
-        if this was the head node.  It now points to null to make iteration easy
-        (KJS::ProfileNode::willExecute): Now must check if m_head is null, this
-        check used to happend in the constructor.
-        (KJS::ProfileNode::stopProfiling): Again the check is slightly different
-        to determine if this is the head.
-        (KJS::ProfileNode::traverseNextNode): This function returns the next
-        node in post order.
-        (KJS::ProfileNode::sort): This generic function will sort according to
-        the comparator passed in, then reset the children pointers to macth the
-        new order.
-        * profiler/ProfileNode.h: The sorting function were removed from the
-        definition file and instead use the new generic sort() function
-        (KJS::ProfileNode::totalPercent): because the head can now be empty we
-        need to check here too for the head node.
-        (KJS::ProfileNode::selfPercent): Ditto
-        (KJS::ProfileNode::firstChild): This function is necessary for the 
-        iterative algorithm in Profile.cpp.
-        (KJS::ProfileNode::sortTotalTimeDescending):
-        (KJS::ProfileNode::sortTotalTimeAscending):
-        (KJS::ProfileNode::sortSelfTimeDescending):
-        (KJS::ProfileNode::sortSelfTimeAscending):
-        (KJS::ProfileNode::sortCallsDescending):
-        (KJS::ProfileNode::sortCallsAscending):
-        (KJS::ProfileNode::sortFunctionNameDescending):
-        (KJS::ProfileNode::sortFunctionNameAscending):
-        (KJS::ProfileNode::childrenBegin):
-        (KJS::ProfileNode::childrenEnd):
-        (KJS::ProfileNode::totalTimeDescendingComparator):
-        (KJS::ProfileNode::totalTimeAscendingComparator):
-        (KJS::ProfileNode::selfTimeDescendingComparator):
-        (KJS::ProfileNode::selfTimeAscendingComparator):
-        (KJS::ProfileNode::callsDescendingComparator):
-        (KJS::ProfileNode::callsAscendingComparator):
-        (KJS::ProfileNode::functionNameDescendingComparator):
-        (KJS::ProfileNode::functionNameAscendingComparator):
-
-2008-06-04  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Fix JSClassCreate to work with old JSCore API threading model.
-
-        No change on SunSpider.
-
-        * API/JSClassRef.cpp: (OpaqueJSClass::OpaqueJSClass): Since JSClass is constructed without
-        a context, there is no way for it to create Identifiers.
-        Also, added initializeThreading(), just for good measure.
-
-        * API/JSCallbackObjectFunctions.h: (KJS::::getPropertyNames): Make an Identifier out of the
-        string here, because propertyNames.add() needs that.
-
-        * kjs/identifier.cpp:
-        * kjs/identifier.h:
-        (KJS::Identifier::equal):
-        * kjs/ustring.cpp:
-        (KJS::equal):
-        Moved equal() from identifier.h to ustring.h, because it's not really about Identifiers,
-        and to make it possible to use it from StrHash.
-        Include StrHash.h from ustring.h to avoid having the behavior depend on headers that happen
-        to be included.
-
-        * wtf/StrHash.h: Removed.
-        * kjs/ustring.h: Made RefPtr<UString::Rep> use the same default hash as UString::Rep* (it
-        used to default to pointer equality). Moved the whole StrHash header into ustring.h.
-
-        * JavaScriptCore.exp: Export equal() for WebCore use (this StrHash is used in c_class.cpp,
-        jni_class.cpp, and npruntime.cpp).
-
-2008-06-04  Alexey Proskuryakov  <ap@webkit.org>
-
-        Rubber-stamped by Darin.
-
-        Fix spacing in collector.{h,cpp}.
-
-        * kjs/collector.cpp:
-        * kjs/collector.h:
-
-2008-06-03  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Build fix. The cleanup in r34355 missed a method.
-
-        * kjs/nodes.cpp:
-        * kjs/nodes.h:
-
-2008-06-03  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - https://bugs.webkit.org/show_bug.cgi?id=19269
-          speed up SunSpider by eliminating the toObject call for most get/put/delete
-
-        Makes standalone SunSpider 1.025x as fast as before.
-
-        The getOwnPropertySlot virtual function now takes care of the toObject call
-        for get. Similarly, the put function (and later deleteProperty) does the
-        same for those operations. To do this, the virtual functions were moved from
-        the JSObject class to the JSCell class. Also, since the caller no longer knows
-        the identity of the "original object", which is used by JavaScript-function
-        based getters, changed the PropertySlot class so the original object is
-        already stored in the slot when getOwnPropertySlot is called, if the caller
-        intends to call getValue.
-
-        This affected the old interpreter code enough that the easiest thing for me
-        was to just delete it. While I am not certain the mysterious slowdown is not
-        still occurring, the net change is definitely a significant speedup.
-
-        * JavaScriptCore.exp: Updated.
-
-        * VM/Machine.cpp: Moved the UNLIKELY macro into AlwaysInline.h.
-        (KJS::resolve): Set up the originalObject in the PropertySlot before
-        calling getPropertySlot. Also removed the originalObject argument from
-        getValue.
-        (KJS::resolve_skip): Ditto.
-        (KJS::resolveBaseAndProperty): Ditto.
-        (KJS::resolveBaseAndFunc): Ditto.
-        (KJS::Machine::privateExecute): Removed the toObject calls from the get and
-        put functions where possible, instead calling directly with JSValue and letting
-        the JSValue and JSCell calls handle toObject. Same for toThisObject.
-
-        * kjs/ExecState.h: Removed OldInterpreterExecState.
-
-        * API/JSBase.cpp: Updated includes.
-
-        * kjs/LocalStorageEntry.h: Removed contents. Later we can remove the file too.
-
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::lengthGetter): Removed originalObject argumet.
-        (KJS::ArrayInstance::inlineGetOwnPropertySlot): Don't pass a base value to
-        setValueSlot. Also use UNLIKELY around the "getting elements past the end of
-        the array" code path; less common than successfully getting an element.
-
-        * kjs/array_object.cpp:
-        (KJS::getProperty): Initialize the PropertySlot with the original object.
-        Don't pass the original object to the get function.
-        (KJS::arrayProtoFuncFilter): Ditto.
-        (KJS::arrayProtoFuncMap): Ditto.
-        (KJS::arrayProtoFuncEvery): Ditto.
-        (KJS::arrayProtoFuncForEach): Ditto.
-        (KJS::arrayProtoFuncSome): Ditto.
-
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct): Removed an obsolete comment.
-
-        * kjs/grammar.y: Eliminated support for some of the node types that were
-        used to optimize executing from the syntax tree.
-
-        * kjs/internal.cpp:
-        (KJS::StringImp::toThisObject): Added. Same as toObject.
-        (KJS::NumberImp::toThisObject): Ditto.
-        (KJS::GetterSetterImp::getOwnPropertySlot): Added. Not reached.
-        (KJS::GetterSetterImp::put): Ditto.
-        (KJS::GetterSetterImp::toThisObject): Ditto.
-
-        * kjs/internal.h: Added toThisObject to NumberImp for speed.
-
-        * kjs/lexer.cpp:
-        (KJS::Lexer::shift): Changed shift to just do a single character, to unroll
-        the loop and especially to make the one character case faster.
-        (KJS::Lexer::setCode): Call shift multiple times instead of passing a number.
-        (KJS::Lexer::lex): Ditto.
-        (KJS::Lexer::matchPunctuator): Ditto. Also removed unneeded elses after returns.
-        (KJS::Lexer::scanRegExp): Ditto.
-        * kjs/lexer.h: Removed the count argument from shift.
-
-        * kjs/math_object.cpp:
-        (KJS::mathProtoFuncPow): Call jsNaN instead of jsNumber(NaN).
-
-        * kjs/nodes.cpp: Removed some of the things needed only for the pre-SquirrelFish
-        execution model.
-        (KJS::ForNode::emitCode): Handle cases where some expressions are missing by
-        not emitting any code at all. The old way was to emit code for "true", but
-        this is an unnecessary remnant of the old way of doing things.
-
-        * kjs/nodes.h: Removed some of the things needed only for the pre-SquirrelFish
-        execution model.
-
-        * kjs/object.cpp:
-        (KJS::JSObject::fillGetterPropertySlot): Changed to only pass in the getter
-        function. The old code passed in a base, but it was never used when
-        actually getting the property; the toThisObject call was pointless. Also
-        changed to not pass a base for setUndefined.
-
-        * kjs/object.h: Added the new JSCell operations to GetterSetterImp.
-        Never called.
-        (KJS::JSObject::get): Initialize the object in the PropertySlot and don't
-        pass it in getValue.
-        (KJS::JSObject::getOwnPropertySlotForWrite): Removed the base argument
-        in calls to setValueSlot.
-        (KJS::JSObject::getOwnPropertySlot): Ditto.
-        (KJS::JSValue::get): Added. Here because it calls through to JSObject.
-        A version of JSObject::get that also handles the other types of JSValue
-        by creating the appropriate wrapper. Saves the virtual call to toObject.
-        (KJS::JSValue::put): Ditto.
-        (KJS::JSValue::deleteProperty): Ditto.
-
-        * kjs/property_slot.cpp:
-        (KJS::PropertySlot::undefinedGetter): Removed the originalObject argument.
-        (KJS::PropertySlot::ungettableGetter): Ditto.
-        (KJS::PropertySlot::functionGetter): Ditto. Use the value in the base
-        as the "this" object, which will be set to the original object by the new
-        PropertySlot initialization code. Also call toThisObject. The old code did
-        not do this, but needed to so we can properly handle the activation object
-        like the other similar code paths.
-
-        * kjs/property_slot.h:
-        (KJS::PropertySlot::PropertySlot): Added a constructor that takes a base
-        object. In debug builds, set the base to 0 if you don't pass one.
-        (KJS::PropertySlot::getValue): Don't take or pass the originalObject.
-        (KJS::PropertySlot::setValueSlot): Don't take a base object, and clear the
-        base object in debug builds.
-        (KJS::PropertySlot::setGetterSlot): Ditto.
-        (KJS::PropertySlot::setUndefined): Ditto.
-        (KJS::PropertySlot::setUngettable): Ditto.
-        (KJS::PropertySlot::slotBase): Assert that a base object is present.
-        This will fire if someone actually calls the get function without having
-        passed in a base object and the getter needs it.
-        (KJS::PropertySlot::setBase): Added. Used by the code that implements
-        toObject so it can supply the original object after the fact.
-        (KJS::PropertySlot::clearBase): Added. Clears the base, but is debug-only
-        code because it's an error to fetch the base if you don't have a guarantee
-        it was set.
-
-        * API/JSCallbackObject.h:
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::JSCallbackObject::cachedValueGetter):
-        (KJS::JSCallbackObject::staticValueGetter):
-        (KJS::JSCallbackObject::staticFunctionGetter):
-        (KJS::JSCallbackObject::callbackGetter):
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::getOwnPropertySlot):
-        (KJS::JSActivation::argumentsGetter):
-        * kjs/JSActivation.h:
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTableGet):
-        * kjs/array_instance.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::argumentsGetter):
-        (KJS::FunctionImp::callerGetter):
-        (KJS::FunctionImp::lengthGetter):
-        (KJS::Arguments::mappedIndexGetter):
-        * kjs/function.h:
-        * kjs/lookup.h:
-        (KJS::staticFunctionGetter):
-        (KJS::staticValueGetter):
-        * kjs/string_object.cpp:
-        (KJS::StringInstance::lengthGetter):
-        (KJS::StringInstance::indexGetter):
-        (KJS::stringInstanceNumericPropertyGetter):
-        * kjs/string_object.h:
-        Removed originalObject arguments from getters. Don't pass base values to
-        the various PropertySlot functions that no longer take them.
-
-        * kjs/value.cpp:
-        (KJS::JSCell::getOwnPropertySlot): Added. Calls toObject and then sets the slot.
-        This function has to always return true, because the caller can't walk the prototype
-        chain. Because of that, we do a getPropertySlot, not getOwnPropertySlot, which works
-        for the caller. This is private, only called by getOwnPropertySlotInternal.
-        (KJS::JSCell::put): Added. Calls toObject and then put.
-        (KJS::JSCell::toThisObject): Added. Calls toObject.
-
-        * kjs/value.h: Added get, put, and toThisObject to both JSValue
-        and JSCell. These take care of the toObject operation without an additional virtual
-        function call, and so make the common "already an object" case faster.
-
-        * wtf/AlwaysInline.h: Moved the UNLIKELY macro here for now. Maybe we can find a
-        better place later, or rename this header.
-
-2008-06-03  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Tim.
-
-        Bug 12983: Web Inspector break on the debugger keyword
-        <https://bugs.webkit.org/show_bug.cgi?id=12983>
-
-        Added a DebuggerStatementNode to handle codegen, and added a new
-        DidReachBreakPoint debug event (which will hopefully be useful
-        if we ever move breakpoint management into JSC proper).  Also
-        added didReachBreakpoint to Debugger to allow us to actually respond
-        to this event.
-
-        * VM/CodeBlock.cpp:
-        (KJS::debugHookName):
-        * VM/Machine.cpp:
-        (KJS::Machine::debug):
-        * VM/Machine.h:
-        * kjs/debugger.h:
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::DebuggerStatementNode::emitCode):
-        (KJS::DebuggerStatementNode::execute):
-        * kjs/nodes.h:
-        (KJS::DebuggerStatementNode::):
-        * kjs/nodes2string.cpp:
-        (KJS::DebuggerStatementNode::streamTo):
-
-2008-06-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - document remaining opcodes.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Document call, call_eval,
-        construct, ret and end opcodes.
-
-2008-06-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Document throw and catch opcodes.
-
-2008-06-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Alexey Proskuryakov.
-
-        Removed JSObject::call, since it just called JSObject::callAsFunction.
-
-        SunSpider reports no change.
-
-2008-06-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        A little cleanup in the CodeGenerator.
-
-        * VM/CodeGenerator.cpp: A few changes here.
-
-        (1) Removed remaining cases of the old hack of putting "this" into the
-        symbol table; replaced with explicit tracking of m_thisRegister.
-
-        (2) Made m_thisRegister behave the same for function, eval, and program
-        code, removing the static programCodeThis() function.
-
-        (3) Added a feature to nix a ScopeNode's declaration stacks when done
-        compiling, to save memory.
-
-        (4) Removed code that copied eval declarations into special vectors: we
-        just use the originals in the ScopeNode now.
-        
-        * VM/CodeGenerator.h: Removed unneded parameters from the CodeGenerator
-        constructor: we just use get that data from the ScopeNode now.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute): When executing an eval node, don't iterate a
-        special copy of its declarations; iterate the originals, instead.
-
-        * kjs/nodes.cpp: Moved responsibility for knowing what AST data to throw
-        away into the CodeGenerator. Nodes no longer call shrinkCapacity on
-        their data directly.
-        
-        * kjs/nodes.h: Changed FunctionStack to ref its contents, so declaration
-        data stays around even after we've thrown away the AST, unless we explicitly
-        throw away the declaration data, too. This is useful for eval code, which
-        needs to reference its declaration data at execution time. (Soon, it will
-        be useful for program code, too, since program code should do the same.)
-
-2008-06-02  Adam Roben  <aroben@apple.com>
-
-        Build fix for non-AllInOne builds
-
-        * kjs/array_object.cpp: Added a missing #include.
-
-2008-06-02  Kevin McCullough  <kmccullough@apple.com>
-
-        Took out accidental confilct lines I checked in.
-
-        * ChangeLog:
-
-2008-06-02  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5969992> JSProfiler: Remove the recursion limit in the
-        profiler
-        Implement Next Sibling pointers as groundwork for removing the recursion
-        limit in the profiler.
-
-        * profiler/ProfileNode.cpp: Also I renamed parentNode and headNode since
-        'node' is redundant.
-        (KJS::ProfileNode::ProfileNode): Initialize the nextSibling.
-        (KJS::ProfileNode::willExecute): If there are already children then the
-        new child needs to be the nextSibling of the last child.
-        (KJS::ProfileNode::didExecute):
-        (KJS::ProfileNode::addChild): Ditto.
-        (KJS::ProfileNode::stopProfiling):
-        (KJS::ProfileNode::sortTotalTimeDescending): For all of the sorting
-        algorithms once the children are sorted their nextSibling pointers need
-        to be reset to reflect the new order.
-        (KJS::ProfileNode::sortTotalTimeAscending):
-        (KJS::ProfileNode::sortSelfTimeDescending):
-        (KJS::ProfileNode::sortSelfTimeAscending):
-        (KJS::ProfileNode::sortCallsDescending):
-        (KJS::ProfileNode::sortCallsAscending):
-        (KJS::ProfileNode::sortFunctionNameDescending):
-        (KJS::ProfileNode::sortFunctionNameAscending):
-        (KJS::ProfileNode::resetChildrensSiblings): This new function simply
-        loops over all of the children and sets their nextSibling pointers to
-        the next child in the Vector
-        (KJS::ProfileNode::debugPrintData):
-        * profiler/ProfileNode.h:
-        (KJS::ProfileNode::parent):
-        (KJS::ProfileNode::setParent):
-        (KJS::ProfileNode::nextSibling):
-        (KJS::ProfileNode::setNextSibling):
-        (KJS::ProfileNode::totalPercent):
-        (KJS::ProfileNode::selfPercent):
-
-2008-06-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Removed the recursion limit from JSObject::call, since the VM does
-        recursion checking now.
-
-        This should allow us to remove JSObject::call entirely, netting a small
-        speedup.
-
-        * kjs/object.cpp:
-        (KJS::JSObject::call):
-
-2008-06-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Adele Peterson.
-
-        Added a specific affordance for avoiding stack overflow when converting
-        recursive arrays to string, in preparation for removing generic stack
-        overflow checking from JSObject::call.
-        
-        Tested by fast/js/toString-stack-overflow.html.
-
-2008-06-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Alice Liu.
-        
-        Refactored some hand-rolled code to call ScopeChain::globalObject instead.
-
-2008-06-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Fixed ASSERT due to execution continuing after an exception is thrown
-        during array sort.
-
-        * kjs/array_instance.cpp:
-        (KJS::AVLTreeAbstractorForArrayCompare::compare_key_key): Don't call the
-        custom comparator function if an exception has been thrown. Just return
-        1 for everything, so the sort completes quickly. (The result will be
-        thrown away.)
-
-2008-05-30  Timothy Hatcher  <timothy@apple.com>
-
-        Made the starting line number of scripts be 1-based throughout the engine.
-        This cleans up script line numbers so they are all consistent now and fixes
-        some cases where script execution was shown as off by one line in the debugger.
-
-        No change in SunSpider.
-
-        Reviewed by Oliver Hunt.
-
-        * API/minidom.c:
-        (main): Pass a line number of 1 instead of 0 to parser().parse().
-        * API/testapi.c:
-        (main): Ditto. And removes a FIXME and changed an assertEqualsAsNumber
-        to use 1 instead of 2 for the line number.
-        * VM/Machine.cpp:
-        (KJS::callEval): Pass a line number of 1 instead of 0.
-        (KJS::Machine::debug): Use firstLine for WillExecuteProgram instead of
-        lastLine. Use lastLine for DidExecuteProgram instead of firstLine.
-        * kjs/DebuggerCallFrame.cpp:
-        (KJS::DebuggerCallFrame::evaluate): Pass a line number of 1 instead of
-        0 to parser().parse().
-        * kjs/Parser.cpp:
-        (KJS::Parser::parse): ASSERT startingLineNumber is greatter than 0. Change
-        the startingLineNumber to be 1 if it was less than or equal to 0. This is needed
-        for release builds to maintain compatibility with the JavaScriptCore API.
-        * kjs/function.cpp:
-        (KJS::globalFuncEval): Pass a line number of 1 instead of 0 to parser().parse().
-        * kjs/function_object.cpp:
-        (FunctionObjectImp::construct): Pass a line number of 1 instead of 0 to construct().
-        * kjs/lexer.cpp:
-        (Lexer::setCode): Made yylineno = startingLineNumber instead of adding 1.
-        * kjs/testkjs.cpp:
-        (functionRun): Pass a line number of 1 instead of 0 to Interpreter::evaluate().
-        (functionLoad): Ditto.
-        (prettyPrintScript): Ditto.
-        (runWithScripts): Ditto.
-        * profiler/Profiler.cpp:
-        (WebCore::createCallIdentifier): Removed a plus 1 of startingLineNumber.
-
-2008-05-30  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19180
-        speed up SunSpider by optimizing immediate number cases
-
-        Also fixed a JavaScriptCore regression seen on PowerPC - we didn't clip left shift
-        parameter to 0...31.
-
-        0.5% improvement on SunSpider overall, although a 8.5 regression on bitops-3bit-bits-in-byte.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::toTruncatedUInt32): Added. Same as getTruncatedInt32, but casts the result
-        to unsigned.
-
-2008-05-30  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19180
-        speed up SunSpider by optimizing immediate number cases
-
-        Also fixed two JavaScriptCore regressions seen on PowerPC - we didn't clip right shift
-        parameter to 0...31.
-
-        1.6% improvement on SunSpider, without significant regressions on any tests.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        Added fast paths for >>, ==, ===, !=, !==. Changed order of memory accesses in many
-        cases, making them less dependent on gcc's ability to properly assign registers. With this,
-        I could move exception checks back into slow code paths, and saw less randomness in general.
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::rightShiftImmediateNumbers):
-        Added.
-
-2008-05-29  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-
-        - fixed <rdar://problem/5972943> REGRESSION(r33979): Flash clips do not play on cnn.com
-        
-        Finally blocks could clobber registers that had to remain live
-        until they returned. This patch takes a conservative approach and
-        makes sure that finally blocks do not reuse any registers that
-        were previously allocated for the function. In the future this
-        could probably be tightened up to be less profligate with the
-        register allocation.
-        
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::highestUsedRegister):
-        * VM/CodeGenerator.h:
-        * kjs/nodes.cpp:
-        (KJS::TryNode::emitCode):
-
-2008-05-29  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-
-        * kjs/array_instance.cpp:
-
-2008-05-29  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19294
-        <rdar://problem/5969062> A crash when iterating over a sparse array backwards.
-
-        * kjs/array_instance.cpp: Turned sparseArrayCutoff into a macro, so that using max() on it
-        doesn't cause a PIC branch.
-        (KJS::ArrayInstance::increaseVectorLength): Added a comment about this function not
-        preserving class invariants.
-        (KJS::ArrayInstance::put): Update m_storage after reallocation. Move values that fit to
-        the vector from the map in all code paths.
-
-2008-05-29  Thiago Macieira  <tjmaciei@trolltech.com>
-
-        Reviewed by Simon.
-
-        Fix compilation in Solaris with Sun CC
-
-        Lots of WebKit code uses C99 functions that, strict as it
-        is, the Solaris system doesn't provide in C++. So we must define them
-        for both GCC and the Sun CC.
-
-        * wtf/MathExtras.h:
-
-2008-05-28  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Anders.
-
-        Fix codegen for assignment being used as a function.
-
-        FunctionCallValueNode::emitCode failed to account for the
-        potential of the function expression to allocate arbitrary
-        registers.
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallValueNode::emitCode):
-
-2008-05-27  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Tim Hatcher.
-
-        Fixed https://bugs.webkit.org/show_bug.cgi?id=19183
-        REGRESSION (r33979): Crash in DebuggerCallFrame::functionName when
-        clicking button in returnEvent-crash.html
-
-        Added two new debugger hooks, willExecuteProgram and didExecuteProgram,
-        along with code to generate them, code to invoke them when unwinding
-        due to an exception, and code to dump them.
-        
-        SunSpider reports no change.
-
-        * VM/CodeBlock.cpp:
-        (KJS::debugHookName): I had to mark this function NEVER_INLINE to avoid
-        a .4% performance regression. The mind boggles.
-
-2008-05-28  Adam Roben  <aroben@apple.com>
-
-        Fix JavaScriptCore tests on OS X
-
-        We were quoting the path to testkjs too late, after it had already
-        been combined with spaces and other options.
-
-        * tests/mozilla/jsDriver.pl:
-        (top level): Move path quoting from here...
-        (sub get_kjs_engine_command): ...to here.
-
-2008-05-28  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Oliver.
-
-        <rdar://problem/5968071> "const f" crashes in JavaScriptCore
-        
-        Make sure to null check the initializer.
-        
-        * kjs/nodes.cpp:
-        (KJS::ConstDeclNode::emitCodeSingle):
-
-2008-05-28  Adam Roben  <aroben@apple.com>
-
-        Make run-javascriptcore-tests work with a space in the path to testkjs
-
-        Reviewed by Alexey Proskuryakov.
-
-        * tests/mozilla/jsDriver.pl: Quote the path to the engine so that
-        spaces will be interpreted correctly.
-
-2008-05-28  Alexey Proskuryakov  <ap@webkit.org>
-
-        Fixed a misguiding comment - my measurement for negative numbers only included cases
-        where both operands were negative, which is not very interesting.
-
-        * VM/Machine.cpp:
-
-2008-05-28  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Maciej.
-
-        Based on a patch by Oliver Hunt.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19180
-        speed up SunSpider by optimizing immediate number cases
-
-        1.4% speedup on SunSpider.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::incImmediateNumber):
-        (KJS::JSImmediate::decImmediateNumber):
-        Added fast paths for ++ and --.
-
-        (KJS::JSImmediate::canDoFastAdditiveOperations): Corrected a comment.
-
-2008-05-28  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        https://bugs.webkit.org/show_bug.cgi?id=19180
-        speed up SunSpider by optimizing immediate number cases
-
-        2% speedup overall, maximum 10% on controlflow-recursive and bitops-3bit-bits-in-byte,
-        but a 4% regression on bitops-bits-in-byte and bitops-bitwise-and.
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::canDoFastAdditiveOperations):
-        (KJS::JSImmediate::addImmediateNumbers):
-        (KJS::JSImmediate::subImmediateNumbers):
-        Added fast cases that work with positive values less than 2^30.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Use the above operations. Also updated SunSpider frequencies
-        with my results (looks like tag values have changed, not sure what caused the minor variation
-        in actual frequencies).
-
-2008-05-27  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
-        Remove code that appended Cygwin's /bin directory to PATH.
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj:
-        Prepend Cygwin's /bin directory to PATH. We prepend instead of append
-        so that Cygwin's utilities will win out over Win32 versions of the
-        same utilities (particularly perl). We do the prepend here instead of
-        in the Makefile because nmake doesn't seem to like prepending to PATH
-        inside the Makefile. This also matches the way WebCoreGenerated works.
-
-2008-05-27  Adam Roben  <aroben@apple.com>
-
-        Roll out r34163
-
-        A better fix is on the way.
-
-        * DerivedSources.make:
-        * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh:
-
-2008-05-27  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * DerivedSources.make: Don't generate the bytecode docs if
-        OMIT_BYTECODE_DOCS is set to 1.
-        * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh: Set
-        OMIT_BYTECODE_DOCS for production builds.
-
-2008-05-27  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Geoff and Maciej.
-
-        <rdar://problem/5806428> 
-        https://bugs.webkit.org/show_bug.cgi?id=17925
-        Crash in KJS::JSObject::put after setting this.__proto__
-
-        Set slotIsWriteable to false for __proto__, we want setting __proto__ to go through JSObject::put instead.
-        
-        * kjs/object.h:
-        (KJS::JSObject::getOwnPropertySlotForWrite):
-
-2008-05-27  Kevin Ollivier  <kevino@theolliviers.com>
-
-        wx build fixes to catch up with SquirrelFish, etc.
-
-        * JavaScriptCoreSources.bkl:
-        * jscore.bkl:
-        * wtf/Platform.h:
-
-2008-05-27  Darin Adler  <darin@apple.com>
-
-        Reviewed by Tim Hatcher.
-
-        - https://bugs.webkit.org/show_bug.cgi?id=19180
-          speed up SunSpider by optimizing immediate number cases
-
-        Add immediate number cases for the &, |, and ^ operators.
-        Makes standalone SunSpider 1.010x faster.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Add areBothImmediateNumbers special cases
-        for the &, |, and ^ operators.
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::xorImmediateNumbers): Added.
-        (KJS::JSImmediate::orImmediateNumbers): Added.
-
-2008-05-26  Stephanie Lewis  <slewis@apple.com>
-
-        Windows build fix. 
-
-        * kjs/testkjs.cpp:
-
-2008-05-26  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Anders.
-        
-        - make addStaticGlobals protected instead of private so subclasses can use it
-
-        * JavaScriptCore.exp:
-        * kjs/JSGlobalObject.h:
-
-2008-05-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Fixed <rdar://problem/5960859> After an eval of a non-string or a syntax
-        error, all profile stack frames are incorrect
-        
-        SunSpider reports a .3% speedup, possibly because eval of a string is a
-        little more efficient now.
-
-        * VM/Machine.cpp:
-        (KJS::callEval): Make sure to call didExecute when returning early. I
-        simplified this function to remove one early return, making the job
-        of adding special code to early returns easier.
-
-        (KJS::Machine::execute): Use the new function ExecState when notifying
-        the profiler. (This doesn't change behavior now, but it might prevent
-        subtle errors in the future.)
-
-2008-05-23  Tor Arne Vestbø  <tavestbo@trolltech.com>
-
-        Reviewed by Simon.
-
-        Fixed toLower and toUpper implementations to allow being called
-        with a null result pointer and resultLength, to determine the
-        number of characters needed for the case conversion.
-
-        * wtf/unicode/qt4/UnicodeQt4.h:
-        (WTF::Unicode::toLower):
-        (WTF::Unicode::toUpper):
-
-2008-05-25  Alexey Proskuryakov  <ap@webkit.org>
-
-        Fixing a typo in the previous commit made as a last minute change.
-
-        * kjs/regexp_object.cpp:
-
-2008-05-24  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Changed regular expression matching result array to be lazily filled, because many callers
-        only care about it being non-null.
-
-        2% improvement on Acid3 test 26.
-
-        * kjs/array_instance.cpp: Added a void* member to ArrayStorage for ArrayInstance subclasses
-        to use.
-        * kjs/array_instance.h:
-        (KJS::ArrayInstance::lazyCreationData):
-        (KJS::ArrayInstance::setLazyCreationData):
-        Added methods to access it from subclasses.
-
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpMatchesArray::RegExpMatchesArray):
-        (KJS::RegExpMatchesArray::getOwnPropertySlot):
-        (KJS::RegExpMatchesArray::put):
-        (KJS::RegExpMatchesArray::deleteProperty):
-        (KJS::RegExpMatchesArray::getPropertyNames):
-        (KJS::RegExpMatchesArray::fillArrayInstanceIfNeeded):
-        (KJS::RegExpMatchesArray::~RegExpMatchesArray):
-        (KJS::RegExpObjectImp::arrayOfMatches):
-        RegExpMatchesArray is a subclass of ArrayInstance that isn't filled until
-        accessed for the first time.
-
-2008-05-24  Alp Toker  <alp@nuanti.com>
-
-        Win32/gcc build fix. Remove MSVC assumption.
-
-        * wtf/TCSpinLock.h:
-        (TCMalloc_SlowLock):
-
-2008-05-24  Oleg Finkelshteyn <olegfink@gmail.com>
-
-        Rubber-stamped, tweaked and landed by Alexey.
-
-        Build fix for gcc 4.3.
-
-        * JavaScriptCore/kjs/testkjs.cpp:
-        * JavaScriptCore/VM/CodeBlock.cpp:
-        Add missing standard includes.
-
-2008-05-23  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Geoff.
-
-        <rdar://problem/5959886> REGRESSION: Assertion failure in JSImmediate::toString when loading GMail (19217)
-        
-        Change List to store a JSValue*** pointer + an offset instead of a JSValue** pointer to protect against the case where 
-        a register file changes while a list object points to its buffer.
-        
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::createArgumentsObject):
-        * kjs/list.cpp:
-        (KJS::List::getSlice):
-        * kjs/list.h:
-        (KJS::List::List):
-        (KJS::List::at):
-        (KJS::List::append):
-        (KJS::List::begin):
-        (KJS::List::end):
-        (KJS::List::buffer):
-
-2008-05-23  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam.
-
-        <rdar://problem/5960012> JSProfiler: Stack overflow if recursion is
-        too deep.
-        -Use a simple depth limit to restrict too deep of recursion.
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::willExecute):
-        (KJS::Profile::didExecute):
-        * profiler/Profile.h:
-
-2008-05-23  Geoffrey Garen  <ggaren@apple.com>
-
-        Rolling back in r34085, with performance resolved.
-        
-        Apparently, passing the eval function to callEval gave GCC a hernia.
-
-        Reviewed by Darin Adler, Kevin McCullough, and Oliver Hunt.
-        
-        Fixed <rdar://problem/5959447> Crashes and incorrect reporting in the
-        JavaScript profiler
-
-        * VM/Machine.cpp:
-        (KJS::Machine::unwindCallFrame): Fixed incorrect reporting / a crash
-        when unwinding from inside eval and/or program code: detect the
-        difference, and do the right thing. Also, be sure to notify the profiler
-        *before* deref'ing the scope chain, since the profiler uses the scope chain.
-
-        (KJS::Machine::execute): Fixed incorrect reporting / crash when calling
-        a JS function re-entrently: Machine::execute(FunctionBodyNode*...)
-        should not invoke the didExecute hook, because op_ret already does that.
-        Also, use the new function's ExecState when calling out to the profiler.
-        (Not important now, but could have become a subtle bug later.)
-
-        (KJS::Machine::privateExecute): Fixed a hard to reproduce crash when
-        profiling JS functions: notify the profiler *before* deref'ing the scope
-        chain, since the profiler uses the scope chain.
-
-        * kjs/object.cpp:
-        (KJS::JSObject::call): Removed these hooks, because they are now unnecessary.
-
-        * profiler/Profile.cpp: Added a comment to explain a subtlety that only
-        Kevin and I understood previously. (Now, the whole world can understand!)
-
-        * profiler/Profiler.cpp:
-        (KJS::shouldExcludeFunction): Don't exclude .call and .apply. That was
-        a hack to fix bugs that no longer exist.
-
-        Finally, sped things up a little bit by changing the "Is the profiler
-        running?" check into an ASSERT, since we only call into the profiler
-        when it's running:
-
-        (KJS::Profiler::willExecute):
-        (KJS::Profiler::didExecute):
-
-2008-05-23  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        - fixed <rdar://problem/5957662> REGRESSION(r33943-r33980): Can't send email , attach file or save as draft from hotmail.com
-        
-        SunSpider reports no change.
-        
-        This is a reworking of r34073, which I rolled out because it caused
-        lots of crashes.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator): Use removeDirect to nix old
-        properties whose names collide with new functions. (Don't use putWithAttributes
-        because that tries to write to the register file, which hasn't grown to
-        fit this program yet.)
-
-2008-05-23  Darin Adler  <darin@apple.com>
-
-        Reviewed by Mark Rowe.
-
-        As allocateNumber is used via jsNumberCell outside of JavaScriptCore,
-        we need to provide a non-inlined version of it to avoid creating a
-        weak external symbol.
-
-        * JavaScriptCore.exp:
-        * kjs/AllInOneFile.cpp:
-        * kjs/collector.cpp:
-        (KJS::Collector::allocate):
-        (KJS::Collector::allocateNumber):
-        * kjs/collector.h:
-        (KJS::Collector::allocate):
-        (KJS::Collector::inlineAllocateNumber):
-        * kjs/value.h:
-        (KJS::NumberImp::operator new):
-
-2008-05-23  Geoffrey Garen  <ggaren@apple.com>
-
-        Rolled out r34073 because it caused lots of layout test crashes.
-
-2008-05-23  Geoffrey Garen  <ggaren@apple.com>
-
-        Rolled out r34085 because it measured as a 7.6% performance regression.
-
-2008-05-23  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add the
-        profiler directory to the include path.
-
-2008-05-23  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Anders.
-
-        SQUIRRELFISH: JavaScript error messages are missing informative text
-
-        Partial fix.
-        Tidy up error messages, makes a couple of them provide slightly more info.
-        Inexplicably leads to a 1% SunSpider Progression.
-
-        * VM/ExceptionHelpers.cpp:
-        (KJS::createError):
-        (KJS::createInvalidParamError):
-        (KJS::createNotAConstructorError):
-        (KJS::createNotAFunctionError):
-        * VM/ExceptionHelpers.h:
-        * VM/Machine.cpp:
-        (KJS::isNotObject):
-
-2008-05-23  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Tim H.
-
-        Fix call stack reported by profiler when entering event handlers.
-
-        JSObject::call was arbitrarily notifying the profiler when it was
-        called, even if it was JS code, which notifies the profile on entry
-        in any case.
-
-        * kjs/object.cpp:
-        (KJS::JSObject::call):
-
-2008-05-16  Alp Toker  <alp@nuanti.com>
-
-        Build fix for gcc 3. Default constructor required in ExecState,
-        used by OldInterpreterExecState.
-
-        * kjs/ExecState.h:
-        (KJS::ExecState::ExecState):
-
-2008-05-23  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Fix <rdar://problem/5954997> global-recursion-on-full-stack.html crashes under guardmalloc.
-
-        Growing the register file with uncheckedGrow from within Machine::execute is not safe as the
-        register file may be too close to its maximum size to grow successfully.  By using grow,
-        checking the result and throwing a stack overflow error we can avoid crashing.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * VM/RegisterFile.h: Remove the now-unused uncheckedGrow.
-
-2008-05-23  Oliver Hunt  <oliver@apple.com>
-
-        RS=Kevin McCullough
-
-        Remove JAVASCRIPT_PROFILER define
-
-        * VM/Machine.cpp:
-        (KJS::callEval):
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * kjs/config.h:
-        * kjs/object.cpp:
-        (KJS::JSObject::call):
-
-2008-05-23  Oliver Hunt  <oliver@apple.com>
-
-       <rdar://problem/5951561> Turn on JavaScript Profiler
-
-        Reviewed by Kevin McCullough.
-
-        Flipped the switch on the profiler, rearranged how we
-        signal the the profiler is active so that calls aren't
-        needed in the general case.
-        
-        Also fixed the entry point for Machine::execute(FunctionBodyNode..)
-        to correctly indicate function exit.
-
-        Results in a 0.7-1.0% regression in SunSpider :-(
-
-        * VM/Machine.cpp:
-        (KJS::callEval):
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * kjs/config.h:
-        * profiler/Profiler.cpp:
-        (KJS::Profiler::profiler):
-        (KJS::Profiler::startProfiling):
-        (KJS::Profiler::stopProfiling):
-        * profiler/Profiler.h:
-        (KJS::Profiler::enabledProfilerReference):
-
-2008-05-23  Simon Hausmann  <hausmann@webkit.org>
-
-        Fix the Qt build by adding profiler/ to the include search path.
-
-        * JavaScriptCore.pri:
-
-2008-05-22  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Adam.
-
-        Fix a bug in the profiler where time in the current function is given to
-        (idle).
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::didExecute): Set the start time and then call didExecute
-        to calculate the time spent in this function.
-        * profiler/ProfileNode.cpp: Remove confusing calculations that are no
-        longer necessary.
-        (KJS::ProfileNode::insertNode):
-        * profiler/ProfileNode.h: Expose access to the start time to allow the
-        simpler time calculations above.
-        (KJS::ProfileNode::startTime):
-        (KJS::ProfileNode::setStartTime):
-
-2008-05-22  Adam Roben  <aroben@apple.com>
-
-        Show "(Function object)" instead of "(JSInpectorCallbackWrapper
-        object)" in profiles
-
-        Reviewed by Kevin McCullough.
-
-        * profiler/Profiler.cpp:
-        (KJS::createCallIdentifier): Use JSObject::className instead of
-        getting the class name from the ClassInfo directly. JSObject
-        subclasses can override className to provide a custom class name, and
-        it seems like we should honor that.
-
-2008-05-22  Timothy Hatcher  <timothy@apple.com>
-
-        Added Profile::restoreAll and added ProfileNode::restoreAll
-        to the export file.
-
-        Reviewed by Adam Roben.
-
-        * JavaScriptCore.exp:
-        * profiler/Profile.h:
-
-2008-05-22  Alp Toker  <alp@nuanti.com>
-
-        GTK+ build fix. Add JavaScriptCore/profiler to include path.
-
-        * GNUmakefile.am:
-
-2008-05-22  Adam Roben  <aroben@apple.com>
-
-        Implement sub-millisecond profiling on Windows
-
-        Reviewed by Kevin McCullough.
-
-        * profiler/ProfileNode.cpp:
-        (KJS::getCount): Added. On Windows, we use QueryPerformanceCounter. On
-        other platforms, we use getCurrentUTCTimeWithMicroseconds.
-        (KJS::ProfileNode::endAndRecordCall): Use getCount instead of
-        getCurrentUTCTimeWithMicroseconds.
-        (KJS::ProfileNode::startTimer): Ditto.
-
-2008-05-22  Adam Roben  <aroben@apple.com>
-
-        Fix a profiler assertion when calling a NodeList as a function
-
-        Reviewed by Kevin McCullough.
-
-        * profiler/Profiler.cpp:
-        (KJS::createCallIdentifier): Don't assert when a non-function object
-        is called as a function. Instead, build up a CallIdentifier using the
-        object's class name.
-
-2008-05-22  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5951529> JSProfiler: Allow the profiler to "Exclude" a
-        profile node.
-        -Implement 'exclude'; where the excluded node attributes its time to its
-        parent's self time.
-
-        * JavaScriptCore.exp: Export the exclude function.
-        * profiler/Profile.h: 
-        (KJS::Profile::exclude):
-        * profiler/ProfileNode.cpp: 
-        (KJS::ProfileNode::setTreeVisible): New function that allows a change in
-        visiblitiy to be propogated to all the children of a node.
-        (KJS::ProfileNode::exclude): If the node matches the callIdentifier then
-        set the visiblity of this node and all of its children to false and
-        attribute it's total time to it's caller's self time.
-        * profiler/ProfileNode.h:
-
-2008-05-22  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Fix access to static global variables in Windows release builds.
-
-        * kjs/JSGlobalObject.h: Don't store a reference to an Identifier
-        in GlobalPropertyInfo as the Identifier is likely to be a temporary
-        and therefore may be destroyed before the GlobalPropertyInfo.
-
-2008-05-22  Kevin McCullough  <kmccullough@apple.com>
-
-        Build fix.
-
-        * VM/Machine.cpp:
-        (KJS::callEval):
-
-2008-05-22  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam.
-
-        <rdar://problem/5951561> Turn on JavaScript Profiler
-        Get basic JS profiling working.
-        Even with this patch the profiler will not be compiled in because we do
-        not know the extend, if any, of the performance regression it would cause
-        when it is not in use. However with these changes, if the profiler were
-        on, it would not crash and show good profiling data.
-
-        * VM/Machine.cpp: Instrument the calls sites that are needed for profiling.
-        (KJS::callEval):
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * kjs/function.cpp: Ditto.
-        (KJS::globalFuncEval):
-        * kjs/interpreter.cpp: Ditto.
-        (KJS::Interpreter::evaluate):
-        * profiler/Profile.cpp: 
-        (KJS::Profile::willExecute):
-        (KJS::Profile::didExecute): Because we do not get a good context when
-        startProfiling is called it is possible that m_currentNode will be at the
-        top of the known stack when a didExecute() is called.  What we then do is
-        create a new node that represents the function being exited and insert
-        it between the head and the currently known children, since they should
-        be children of this new node.
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::ProfileNode):
-        (KJS::ProfileNode::willExecute): Rename the add function for consistency.
-        (KJS::ProfileNode::addChild): Appends the child to this node but also
-        sets the parent pointer of the children to this node.
-        (KJS::ProfileNode::insertNode): Insert a node between this node and its
-        children.  Also set the time for the new node since it is now exiting
-        and we don't really know when it started.
-        (KJS::ProfileNode::stopProfiling):
-        (KJS::ProfileNode::startTimer):
-        * profiler/ProfileNode.h:
-        (KJS::CallIdentifier::toString): Added for debugging.
-        (KJS::ProfileNode::setParent):
-        (KJS::ProfileNode::setSelfTime): Fixed an old bug where we set the
-        visibleTotalTime not the visibleSelfTime.
-        (KJS::ProfileNode::children):
-        (KJS::ProfileNode::toString): Added for debugging.
-        * profiler/Profiler.cpp: remove unecessary calls.
-        (KJS::Profiler::startProfiling):
-
-2008-05-22  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Rename register arguments for op_call, op_call_eval, op_end, and op_construct 
-        to document what they are for.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitCall):
-        (KJS::CodeGenerator::emitCallEval):
-        (KJS::CodeGenerator::emitEnd):
-        (KJS::CodeGenerator::emitConstruct):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-05-22  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Darin.
-
-        Bug 19116: SquirrelFish shouldn't regress on variable lookups
-        <https://bugs.webkit.org/show_bug.cgi?id=19116>
-
-        Last of the multiscope look up optimisations.  This is a wash overall on SunSpider
-        but is a factor of 5-10 improvement in multiscope read/write/modify (eg. ++, --, +=,
-        ... applied to any non-local var).
-
-        * kjs/nodes.cpp:
-        (KJS::PostIncResolveNode::emitCode):
-        (KJS::PostDecResolveNode::emitCode):
-        (KJS::PreIncResolveNode::emitCode):
-        (KJS::PreDecResolveNode::emitCode):
-        (KJS::ReadModifyResolveNode::emitCode):
-
-2008-05-22  David Kilzer  <ddkilzer@apple.com>
-
-        <rdar://problem/5954233> Add method to release free memory from FastMalloc
-
-        Patch suggested by Mark Rowe.  Rubber-stamped by Maciej.
-
-        * JavaScriptCore.exp: Export _releaseFastMallocFreeMemory.
-        * wtf/FastMalloc.cpp:
-        (WTF::TCMallocStats::): Added releaseFastMallocFreeMemory() for both
-        system malloc and FastMalloc code paths.
-        * wtf/FastMalloc.h: Define releaseFastMallocFreeMemory().
-
-2008-05-22  Oliver Hunt  <oliver@apple.com>
-
-        RS=Maciej.
-
-        Roll out r34020 as it causes recursion tests to fail.
-
-        * kjs/object.cpp:
-        (KJS::JSObject::call):
-
-2008-05-22  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Mark.
-
-        Don't leak the SymbolTable when compiling eval code.
-
-        * kjs/nodes.cpp:
-        (KJS::EvalNode::generateCode):
-
-2008-05-22  Simon Hausmann  <hausmann@webkit.org>
-
-        Reviewed by Oliver.
-
-        Qt build fix.
-
-        * JavaScriptCore.pri: Added DebuggerCallFrame to the build.
-        * VM/LabelID.h: Include limits.h for UINT_MAX.
-        * wtf/VectorTraits.h: Include memory for std::auto_ptr.
-
-2008-05-22  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Adam Roben.
-        
-        Removed the old recursion guard mechanism, since squirrelfish has its
-        own mechanism. Also removed some old JS call tracing code, since we
-        have other ways to do that, too.
-        
-        SunSpider reports no change.
-
-        * kjs/object.cpp:
-        (KJS::JSObject::call):
-
-2008-05-22  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fixed <rdar://problem/5954979> crash on celtic kane JS benchmark
-
-        * kjs/nodes.cpp:
-        (KJS::WithNode::emitCode):
-        (KJS::TryNode::emitCode):
-
-2008-05-21  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Maciej and Geoff.
-
-        <rdar://problem/5951561> Turn on JavaScript Profiler
-        -As part of the effort to turn on the profiler it would be helpful if it
-        did not need ExecStates to represent the stack location of the currently
-        executing statement.
-        -We now create each node as necessary with a reference to the current
-        node and each node knows its parent so that the tree can be made without
-        the entire stack.
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::Profile): The current node starts at the head.
-        (KJS::Profile::stopProfiling): The current node is cleared when profiling
-        stops.
-        (KJS::Profile::willExecute): The current node either adds a new child or
-        starts and returns a reference to an already existing child if the call
-        ID that is requested already exists.
-        (KJS::Profile::didExecute): The current node finishes and returns its
-        parent.
-        * profiler/Profile.h: Use a single callIdentifier instead of a vector
-        since we no longer use the whole stack.
-        * profiler/ProfileNode.cpp: Now profile nodes keep a reference to their
-        parent.
-        (KJS::ProfileNode::ProfileNode): Initialize the parent.
-        (KJS::ProfileNode::didExecute): Record the time and return the parent.
-        (KJS::ProfileNode::addOrStartChild): If the given callIdentifier is
-        already a child, start it and return it, otherwise create a new one and
-        return that.
-        (KJS::ProfileNode::stopProfiling): Same logic, just use the new function.
-        * profiler/ProfileNode.h: Utilize the parent.
-        (KJS::ProfileNode::create):
-        (KJS::ProfileNode::parent):
-        * profiler/Profiler.cpp: 
-        (KJS::Profiler::startProfiling): Here is the only place where the
-        ExecState is used to figure out where in the stack the profiler is
-        currently profiling.
-        (KJS::dispatchFunctionToProfiles): Only send one CallIdentifier instead
-        of a vector of them.
-        (KJS::Profiler::willExecute): Ditto.
-        (KJS::Profiler::didExecute): Ditto.
-        (KJS::createCallIdentifier): Create only one CallIdentifier.
-        (KJS::createCallIdentifierFromFunctionImp): Ditto.
-        * profiler/Profiler.h:
-
-2008-05-21  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - https://bugs.webkit.org/show_bug.cgi?id=19180
-          speed up the < operator for the case when both values are integers
-
-        Makes standalone SunSpider 1.022x faster.
-
-        * VM/Machine.cpp:
-        (KJS::jsLess): Add a special case for when both are numbers that fit in a JSImmediate.
-
-2008-05-21  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver and Sam.
-        
-        - fixed <rdar://problem/5815631> REGRESSION (r31239): Multiscope optimisation of function calls results in incorrect this value (breaks tvtv.de)
-        
-        Track global this value in the scope chain so we can retrieve it
-        efficiently but it follows lexical scope properly.
-
-        * kjs/ExecState.h:
-        (KJS::ExecState::globalThisValue):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData):
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct):
-        * kjs/scope_chain.h:
-        (KJS::ScopeChainNode::ScopeChainNode):
-        (KJS::ScopeChainNode::globalThisObject):
-        (KJS::ScopeChainNode::push):
-        (KJS::ScopeChain::ScopeChain):
-
-2008-05-21  Kevin McCullough  <kmccullough@apple.com>
-
-        Sadness :(
-
-        * kjs/config.h:
-
-2008-05-21  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Maciej.
-
-        <rdar://problem/5950867> JSProfiler: Allow the profiler to "Focus" a
-        profile node.
-        - This patch updatest the times of the visible nodes correctly, but to do
-        so, some of the design of the ProfileNode changed.
-
-        * JavaScriptCore.exp: export focus' symbol.
-        * profiler/Profile.cpp: ProfileNodes now take a reference to the head of
-        the profile tree to get up-to-date accurate total profile time.
-        (KJS::Profile::Profile): Pass 0 for the head node.
-        (KJS::Profile::stopProfiling): stopProfiling no longer needs the time
-        passed into it, since it can get it from the head and it does not need to
-        be told it is the head because it can figure it out on it's own.
-        (KJS::Profile::willExecute): Set the head node for each created node.
-        * profiler/Profile.h:
-        (KJS::Profile::focus): Instead of taking a CallIdentifier that the caller
-        would have to create, now focus() takes a ProfileNode that they should
-        already have a reference to and focus() can extract the CallIdentifier
-        from it.
-        * profiler/ProfileNode.cpp: Create actual and visible versions fo the
-        total and self times for focus and exclude.  Also add a head node
-        reference so that nodes can get information from their head.
-        (KJS::ProfileNode::ProfileNode):
-        (KJS::ProfileNode::stopProfiling): Rename the total and self time
-        variables and set the visual ones to the actual ones, so that without any
-        changes to the visual versions of these variables, their times will match
-        the actual times.
-        (KJS::ProfileNode::focus): Now focus() has a bool to force it's children
-        to be visible if this node is visible.  If this node does not match the
-        CallIdentifier being focused then the visibleTotalTime is only updated if
-        one or more of it's children is the CallIdentifier being focused. 
-        (KJS::ProfileNode::restoreAll): Restores all variables with respect to
-        the visible data in the ProfileNode.
-        (KJS::ProfileNode::endAndRecordCall): Name change.
-        (KJS::ProfileNode::debugPrintData): Dump the new variables.
-        (KJS::ProfileNode::debugPrintDataSampleStyle): Name change.
-        * profiler/ProfileNode.h: Use the new variables and reference to the head
-        node.
-        (KJS::ProfileNode::create):
-        (KJS::ProfileNode::totalTime):
-        (KJS::ProfileNode::setTotalTime):
-        (KJS::ProfileNode::selfTime):
-        (KJS::ProfileNode::setSelfTime):
-        (KJS::ProfileNode::totalPercent):
-        (KJS::ProfileNode::selfPercent):
-        (KJS::ProfileNode::setVisible):
-
-2008-05-21  Alp Toker  <alp@nuanti.com>
-
-        GTK+/UNIX testkjs build fix. Include signal.h.
-
-        * kjs/testkjs.cpp:
-
-2008-05-21  Oliver Hunt  <oliver@apple.com>
-
-        Yet more windows build fixes
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-05-21  Oliver Hunt  <oliver@apple.com>
-
-        Yet more windows build fixes
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-05-21  Alp Toker  <alp@nuanti.com>
-
-        GTK+ build fix. Add DebuggerCallFrame.cpp and take AllInOneFile.cpp
-        changes into account.
-
-        * GNUmakefile.am:
-
-2008-05-21  Oliver Hunt  <oliver@apple.com>
-
-        Add DebuggerCallFrame.{h,cpp} to the project file
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-05-21  Alp Toker  <alp@nuanti.com>
-
-        GTK+ port build fixes following squirrelfish merge r33979.
-
-        * GNUmakefile.am:
-
-2008-05-21  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Darin.
-        
-        - save a hash lookup wne writing to global properties
-        0.3% speedup on SunSpider, 7% on bitops-bitwise-and
-
-        * VM/Machine.cpp:
-        (KJS::resolveBase): Check for being a the end of the scope chain
-        before hash lookup.
-
-2008-05-21  Alp Toker  <alp@nuanti.com>
-
-        Rubber-stamped by Maciej.
-
-        Replace non-standard #pragma marks with comments to avoid compiler
-        warnings.
-
-        * profiler/ProfileNode.cpp:
-
-2008-05-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Mark Rowe.
-
-        Fix layout test failure in fast/dom/getter-on-window-object2 introduced in r33961.
-
-        * JavaScriptCore.exp:
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::defineGetter):
-        (KJS::JSGlobalObject::defineSetter):
-        * kjs/JSGlobalObject.h:
-
-=== End merge of squirrelfish ===
-
-2008-05-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Tim Hatcher.
-        
-        Merged with trunk WebCore's new debugger.
-
-        * kjs/DebuggerCallFrame.cpp:
-        (KJS::DebuggerCallFrame::evaluate): Changed this function to separate
-        the exception value from the return value. The WebKit debugger treats
-        them as one, but the WebCore debugger doesn't.
-
-        * kjs/DebuggerCallFrame.h:
-        (KJS::DebuggerCallFrame::dynamicGlobalObject): Added a new accessor for
-        the dynamic global object, since the debugger doesn't want the lexical
-        global object.
-
-2008-05-21  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 19116: SquirrelFish shouldn't regress on variable lookups
-        <https://bugs.webkit.org/show_bug.cgi?id=19116>
-
-        Optimise cross scope assignment, 0.4% progression in sunspider.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitPutScopedVar):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::AssignResolveNode::emitCode):
-
-2008-05-21  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - check property map before symbol table in JSGlobalObject::getOwnPropertySlot
-        0.5% speedup on SunSpider
-
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::getOwnPropertySlot): Check property map before symbol table
-        because symbol table access is likely to have been optimized.
-
-2008-05-21  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 19116: SquirrelFish shouldn't regress on variable lookups
-        <https://bugs.webkit.org/show_bug.cgi?id=19116>
-
-        Optimise multiscope lookup of statically resolvable function calls.
-        SunSpider reports a 1.5% improvement, including 37% on 
-        controlflow-recursive for some reason :D
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitResolve):
-        * VM/CodeGenerator.h:
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallResolveNode::emitCode):
-
-2008-05-21  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - give JSGlobalObject a special version of getOwnPropertySlot that tells you if the slot is directly writable
-        (WebCore change using this is a 2.6% speedup on in-browser SunSpider).
-
-        * JavaScriptCore.exp:
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::getOwnPropertySlot):
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTableGet):
-        * kjs/object.h:
-        (KJS::JSObject::getDirectLocation):
-        (KJS::JSObject::getOwnPropertySlotForWrite):
-        * kjs/property_map.cpp:
-        (KJS::PropertyMap::getLocation):
-        * kjs/property_map.h:
-        * kjs/property_slot.h:
-        (KJS::PropertySlot::putValue):
-
-2008-05-20  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 19116: SquirrelFish shouldn't regress on variable lookups
-        <https://bugs.webkit.org/show_bug.cgi?id=19116>
-
-        This restores multiscope optimisation to simple resolve, producing
-        a 2.6% progression in SunSpider.  Have verified that none of the
-        sites broken by the multiscope optimisation in trunk were effected
-        by this change.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeBlock.h:
-        (KJS::CodeBlock::CodeBlock):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::findScopedProperty):
-        (KJS::CodeGenerator::emitResolve):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::resolve_n):
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/JSVariableObject.h:
-
-2008-05-20  Oliver Hunt  <oliver@apple.com>
-
-        Fixerate the windows build.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * VM/CodeGenerator.cpp:
-        * VM/RegisterFile.h:
-        * kjs/JSGlobalObject.h:
-        * kjs/Parser.cpp:
-        * kjs/interpreter.h:
-
-2008-05-20  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 19110: SquirrelFish: Google Maps - no maps
-        <https://bugs.webkit.org/show_bug.cgi?id=19110>
-
-        Correct a comedy of errors present in my original patch to "fix"
-        exceptions occurring midway through pre and post increment. This
-        solution is cleaner than the original, doesn't need the additional
-        opcodes, and as an added benefit does not break Google Maps.
-
-        Sunspider reports a 0.4% progression.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::PreIncResolveNode::emitCode):
-        (KJS::PreDecResolveNode::emitCode):
-        (KJS::PreIncBracketNode::emitCode):
-        (KJS::PreDecBracketNode::emitCode):
-        (KJS::PreIncDotNode::emitCode):
-        (KJS::PreDecDotNode::emitCode):
-
-2008-05-20  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - inline JSGlobalObject::getOwnPropertySlot
-        1% improvement on in-browser SunSpider (a wash command-line)
-
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::getOwnPropertySlot):
-
-2008-05-18  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18752: SQUIRRELFISH: exceptions are not always handled by the vm
-        <https://bugs.webkit.org/show_bug.cgi?id=18752>
-
-        Handle exceptions thrown by toString conversion in subscript operators,
-        this should basically complete exception handling in SquirrelFish.
-
-        Sunspider reports no regression.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-05-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        [Reapplying patch with previously missing files from r33553 -- Oliver]
-
-        Behold: debugging.
-        
-        SunSpider reports no change.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Added DebuggerCallFrame.h/.cpp,
-        and created a debugger folder.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::generate): If the debugger is attached, always
-        generate full scope chains for its sake.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::unwindCallFrame): Notify the debugger when unwinding
-        due to an exception, so it doesn't keep stale call frames around.
-
-        (KJS::Machine::execute): Set Callee to 0 in eval frames, so the
-        debugger can distinguish them from function call frames.
-
-        (KJS::Machine::debug): Simplified this function, since the debugger
-        doesn't actually need all the information we used to provide.
-
-        (KJS::Machine::privateExecute): Treat debugging hooks like other function
-        calls, so the code we hook into (the debugger UI) can be optimized.
-
-        * kjs/debugger.cpp: Nixed these default callback implementations and
-        made the callbacks pure virtual instead, so the compiler could tell me
-        if I made a mistake in one of the subclasses.
-
-        * kjs/debugger.h: Removed a bunch of irrelevent data from the debugger
-        callbacks. Changed from passing an ExecState* to passing a
-        DebuggerCallFrame*, since an ExecState* doesn't contain sufficient
-        information anymore.
-
-        * kjs/function.cpp:
-        (KJS::globalFuncEval): Easiest bug fix evar!
-
-        [Previously missing files from r33553]
-        * kjs/DebuggerCallFrame.cpp: Copied from JavaScriptCore/profiler/FunctionCallProfile.h.
-        (KJS::DebuggerCallFrame::functionName):
-        (KJS::DebuggerCallFrame::thisObject):
-        (KJS::DebuggerCallFrame::evaluateScript):
-        * kjs/DebuggerCallFrame.h: Copied from JavaScriptCore/VM/Register.h.
-        (KJS::DebuggerCallFrame::DebuggerCallFrame):
-        (KJS::DebuggerCallFrame::scopeChain):
-        (KJS::DebuggerCallFrame::exception):
-
-2008-05-17  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 18991: SquirrelFish: Major codegen issue in a.b=expr, a[b]=expr
-        <https://bugs.webkit.org/show_bug.cgi?id=18991>
-
-        Fix the last remaining blocking cases of this bug.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::ReadModifyResolveNode::emitCode):
-
-2008-05-17  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Partial fix for:
-
-        Bug 18991: SquirrelFish: Major codegen issue in a.b=expr, a[b]=expr
-        <https://bugs.webkit.org/show_bug.cgi?id=18991>
-
-        Ensure that the code generated for assignments uses temporaries whenever
-        necessary. This patch covers the vast majority of situations, but there
-        are still a few left.
-
-        This patch also adds some missing cases to CodeBlock::dump().
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::destinationForAssignResult):
-        (KJS::CodeGenerator::leftHandSideNeedsCopy):
-        (KJS::CodeGenerator::emitNodeForLeftHandSide):
-        * kjs/NodeInfo.h:
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::AssignDotNode::emitCode):
-        (KJS::ReadModifyDotNode::emitCode):
-        (KJS::AssignBracketNode::emitCode):
-        (KJS::ReadModifyBracketNode::emitCode):
-        (KJS::ForInNode::ForInNode):
-        * kjs/nodes.h:
-        (KJS::ReadModifyResolveNode::):
-        (KJS::AssignResolveNode::):
-        (KJS::ReadModifyBracketNode::):
-        (KJS::AssignBracketNode::):
-        (KJS::AssignDotNode::):
-        (KJS::ReadModifyDotNode::):
-
-2008-05-17  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 19106: SquirrelFish: Activation is not marked correctly
-        <https://bugs.webkit.org/show_bug.cgi?id=19106>
-
-        We can't rely on the symbol table for a count of the number of globals
-        we need to mark as that misses duplicate parameters and 'this'.  Now we
-        use the actual local register count from the codeBlock.
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::mark):
-
-2008-05-16  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 19076: SquirrelFish: RegisterFile can be corrupted if implictly reenter global scope with no declared vars
-        <https://bugs.webkit.org/show_bug.cgi?id=19076>
-
-        Don't delay allocation of initial global RegisterFile, as we can't guarantee we will be able
-        to allocate the global 'this' register safely at any point after initialisation of the Global
-        Object.
-
-        Unfortunately this initial allocation caused a regression of 0.2-0.3%, however this patch adds
-        support for the static slot optimisation for the global Math object which brings it to a 0.3%
-        progression.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::programCodeThis):
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::addParameter):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * kjs/ExecState.h:
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::GlobalPropertyInfo::GlobalPropertyInfo):
-        (KJS::JSGlobalObject::addStaticGlobals):
-        * kjs/nodes.cpp:
-
-2008-05-16  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver Hunt.
-
-        Bug 19098: SquirrelFish: Ref'd temporaries can be clobbered
-        <https://bugs.webkit.org/show_bug.cgi?id=19098>
-
-        When doing code generation for a statement list, increase the reference
-        count on a register that might eventually be returned, so that it doesn't
-        get clobbered by a request for a new temporary.
-
-        * kjs/nodes.cpp:
-        (KJS::statementListEmitCode):
-
-2008-05-16  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fixed Bug 19044: SquirrelFish: Bogus values enter evaluation when closing over scope with parameter and var with same name
-        https://bugs.webkit.org/show_bug.cgi?id=19044
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::copyRegisters): Use numLocals from the code
-        block rather than the size of the symbol table for the number of
-        registers to copy, to account for duplicate parameters and vars
-        with the same name as parameters (we still have potentially
-        suboptimal codegen in that we allocate a local register for the
-        var in the latter case but it is never used).
-        
-2008-05-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Not reviewed.
-        
-        We regret to inform you that your program is crashing because you were
-        stupid.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Math is hard.
-
-2008-05-14  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        A little more debugger action: filled in op_debug. All debugger control
-        flow works now, but variable inspection and backtraces still don't.
-        
-        SunSpider reports no change.
-
-        * VM/CodeGenerator.cpp: Changed op_debug to accept line number parameters.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::getFunctionAndArguments): Moved op_debug into a
-        NEVER_INLINE function to avoid a stunning 10% performance regression.
-        Also factored out a common function for retrieving the function and 
-        arguments from a  call frame. 
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::createArgumentsObject): Use the new factored out
-        function mentioned above.
-
-        * kjs/Parser.cpp:
-        (KJS::Parser::parse): Increment m_sourceId before assigning it, so the
-        sourceId we send to the debugger matches the sourceId recorded in the
-        node.
-
-        * kjs/nodes.cpp: Emit debugging hooks.
-
-2008-05-14  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 19024: SQUIRRELFISH: ASSERTION FAILED: activation->isActivationObject() in Machine::unwindCallFrame
-        <https://bugs.webkit.org/show_bug.cgi?id=19024>
-
-        This fixes a number of issues.  The most important is that we now check every register
-        file for tainting rather than just looking for function register files as that was
-        insufficient. Additionally guarded against implicit re-entry into Eval code.
-
-        Also added a few additional assertions to reduce the amout of time between something
-        going wrong and us seeing the error.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/RegisterFile.cpp:
-        (KJS::RegisterFile::growBuffer):
-        (KJS::RegisterFile::addGlobalSlots):
-        * VM/RegisterFileStack.cpp:
-        (KJS::RegisterFileStack::pushGlobalRegisterFile):
-        (KJS::RegisterFileStack::pushFunctionRegisterFile):
-        * VM/RegisterFileStack.h:
-        (KJS::RegisterFileStack::inImplicitCall):
-
-2008-05-14  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        A little more debugger action: emit opcodes for debugger hooks. Right
-        now, the opcode implementation is just a stub.
-        
-        SunSpider reports no change.
-        
-        Some example codegen for "function f() { 1; }":
-
-            [   0] dbg         DidEnterCallFrame
-            [   2] dbg         WillExecuteStatement
-            [   4] load        tr0, 1(@k0)
-            [   7] load        tr0, undefined(@k1)
-            [  10] dbg         WillLeaveCallFrame
-            [  12] ret         tr0
-
-2008-05-14  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 19025: SQUIRRELFISH: malformed syntax in onload handler causes crash
-        <https://bugs.webkit.org/show_bug.cgi?id=19025>
-
-        Simple fix -- move the use of functionBodyNode to after the null check.
-
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct):
-
-2008-05-13  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed a codegen crash with run-time parse errors.
-        
-        SunSpider reports no change.
-        
-        emitThrowError needs to return the temporary holding the error, not dst,
-        since dst may be NULL. In fact, emitThrowError shouldn't take a dst
-        parameter at all, since exceptions should not modify the destination
-        register.
-
-2008-05-13  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 19027: SquirrelFish: Incorrect codegen for pre-increment
-        <https://bugs.webkit.org/show_bug.cgi?id=19027>
-
-        This fixes the codegen issues for the pre-inc/decrement operators
-        to prevent incorrectly clobbering the destination in the event of
-        an exception.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitPreInc):
-        (KJS::CodeGenerator::emitPreDec):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::PreIncResolveNode::emitCode):
-        (KJS::PreDecResolveNode::emitCode):
-        (KJS::PreIncBracketNode::emitCode):
-        (KJS::PreDecBracketNode::emitCode):
-        (KJS::PreIncDotNode::emitCode):
-        (KJS::PreDecDotNode::emitCode):
-
-2008-05-13  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        A little more debugger action: supply a real line number, sourceId,
-        and sourceURL in op_new_error.
-        
-        SunSpider reports a .2% speedup. Not sure what that's about.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Use the new good stuff in op_new_error.
-
-        * kjs/nodes.cpp:
-        (KJS::RegExpNode::emitCode): Use the shared emitThrowError instead of
-        rolling our own.
-
-2008-05-13  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        A little more debugger action: implemented the exception callback.
-        
-        SunSpider reports a .2% speedup. Not sure what that's about.
-
-        * VM/CodeBlock.h: A little refactoring here. Store a pointer to our
-        owner ScopeNode so we can retrieve data from it. This allows us to
-        stop storing copies of the data ourselves. Also, store a "this" register
-        instead of a code type, since we were only using the code type to
-        calculate the "this" register.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::generate): Calculate the "this" register mentioned
-        above. Also, take care of removing "this" from the symbol table after
-        codegen is done, since relying on the timing of a destructor for correct
-        behavior is not so good.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::throwException): Invoke the debugger's exception callback.
-        (KJS::Machine::privateExecute): Use the "this" register mentioned above.
-
-2008-05-13  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Removed some unused exception machinery.
-        
-        SunSpider reports a .3% speedup.
-
-        * API/JSCallbackObject.h:
-        * API/JSCallbackObjectFunctions.h:
-        * JavaScriptCore.exp:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/internal.cpp:
-        * kjs/object.cpp:
-        * kjs/object.h:
-        * kjs/value.h:
-
-2008-05-13  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        A little more debugger action.
-
-        * kjs/debugger.cpp:
-        * kjs/debugger.h: Removed debuggersPresent because it was unused.
-        Replaced AttachedGlobalObject linked list with a HashSet because HashSet
-        is faster and simpler. Changed all functions to return void instead of
-        bool, because no clients ever return false, and we don't want to support
-        it.
-
-        * kjs/nodes.cpp: Did some up-keep to avoid build bustage.
-        (KJS::Node::handleException):
-        (KJS::BreakpointCheckStatement::execute):
-        (KJS::FunctionBodyNodeWithDebuggerHooks::execute):
-
-2008-05-13  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Darin.
-
-        Bug 18752: SQUIRRELFISH: exceptions are not always handled by the vm
-        <https://bugs.webkit.org/show_bug.cgi?id=18752>
-
-        Replace old attempt at "branchless" exceptions as the extra information
-        being passed made gcc an unhappy compiler, replacing these custom toNumber
-        calls with ordinary toNumber logic (by relying on toNumber now preventing
-        side effects after an exception has been thrown) provided sufficient leeway
-        to add the additional checks for the remaining unchecked cases.
-
-        This leaves only toString conversions in certain contexts as possibly
-        misbehaving.
-
-        * VM/Machine.cpp:
-        (KJS::jsAdd):
-        (KJS::resolve):
-        (KJS::resolveBaseAndProperty):
-        (KJS::resolveBaseAndFunc):
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/value.h:
-        (KJS::JSValue::safeGetNumber):
-
-2008-05-13  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        First steps toward supporting the debugger API: support the sourceParsed
-        callback; plus some minor fixups.
-
-        SunSpider reports no regression.
-
-        * VM/CodeGenerator.h: Removed a misleading comment.
-
-        * kjs/Parser.h: Changed the parser to take an ExecState*, so it can
-        implement the sourceParsed callback -- that way, we only have to
-        implement the callback in one place.
-
-        * kjs/debugger.cpp: Nixed DebuggerImp, because its sole purpose in life
-        was to demonstrate the misapplication of design patterns.
-
-        * kjs/debugger.h: Changed sourceParsed to take a SourceProvider, to
-        reduce copying, and not to return a value, because pausing execution
-        after parsing is complicated, and no clients needed that ability, anyway.
-
-        * kjs/grammar.y: Make sure never to pass a NULL SourceElements* to
-        didFinishParsing -- that simplifies some code down the road.
-        
-        * kjs/nodes.cpp: Don't generate special AST nodes just because the
-        debugger is attached -- that's a relic of the old AST execution model,
-        and those nodes haven't been maintained.
-
-2008-05-13  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 18752: SQUIRRELFISH: exceptions are not always handled by the vm
-        <https://bugs.webkit.org/show_bug.cgi?id=18752>
-
-        First step: prevent incorrect evaluation of valueOf/toString conversion
-        in right hand side of expression after earlier conversion throws.
-
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::toNumber):
-        * kjs/object.cpp:
-        (KJS::JSObject::defaultValue):
-
-2008-05-12  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 18934: SQUIRRELFISH: ASSERT @ nytimes.com due to RegisterFile being clobbered
-        <https://bugs.webkit.org/show_bug.cgi?id=18934>
-
-        Unfortunately we cannot create new statically optimised globals if there are any
-        tainted RegisterFiles on the RegisterFileStack.  To handle this we re-introduce
-        (in a slightly cleaner form) the inImplicitCall concept to the RegisterFileStack.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * VM/RegisterFileStack.cpp:
-        (KJS::RegisterFileStack::pushFunctionRegisterFile):
-        * VM/RegisterFileStack.h:
-
-2008-05-12  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Introduced support for function.caller.
-        
-        Improved support for walking interesting scopes for function introspection.
-        
-        This fixes all remaining layout tests not blocked by rebasing to trunk.
-        
-        SunSpider reports no change.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::dumpRegisters): Fixed a spacing issue.
-
-2008-05-11  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 18961: SQUIRRELFISH: Gmail doesn't load
-        <https://bugs.webkit.org/show_bug.cgi?id=18961>
-
-        Fix codegen for logical nodes so that they don't use their destination
-        as a temporary.
-
-        * kjs/nodes.cpp:
-        (KJS::LogicalAndNode::emitCode):
-        (KJS::LogicalOrNode::emitCode):
-
-2008-05-10  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-
-        - JavaScriptCore part of fix for: "SQUIRRELFISH: function toString broken after calling"
-        https://bugs.webkit.org/show_bug.cgi?id=18869
-       
-        Three layout tests are fixed:
-          fast/js/toString-elision-trailing-comma.html
-          fast/js/toString-prefix-postfix-preserve-parens.html
-          fast/js/kde/lval-exceptions.html
-        
-        Functions now save a shared subrange of the original source used
-        to make them (so in the common case this adds no storage above the
-        memory cache).
-        
-        * kjs/SourceProvider.h: Added.
-        (KJS::SourceProvider): New abstract base class for classes that provide on-demand access
-        to the source for a JavaScript program. This allows function objects to have access to their
-        original source without copying.
-        (KJS::UStringSourceProvider): SourceProvider subclass backed by a KJS::UString.
-        (KJS::UStringSourceProvider::create):
-        (KJS::UStringSourceProvider::getRange):
-        (KJS::UStringSourceProvider::data):
-        (KJS::UStringSourceProvider::length):
-        (KJS::UStringSourceProvider::UStringSourceProvider):
-        * kjs/SourceRange.h: Added.
-        (KJS::SourceRange::SourceRange): Class that holds a SourceProvider and a character range into
-        the source, to encapsulate on-demand access to the source of a function.
-        (KJS::SourceRange::toString):
-        * VM/Machine.cpp:
-        (KJS::eval): Pass a UStringSourceProvider to the parser.
-        * kjs/Parser.cpp:
-        (KJS::Parser::parse): Take a SourceProvider and pass it on to the lexer.
-        * kjs/Parser.h:
-        (KJS::Parser::parse): Take a SourceProvider.
-        * kjs/lexer.cpp:
-        (KJS::Lexer::setCode): Take a SourceProvider; keep it around, and
-        use it to get the raw buffer and length.
-        * kjs/lexer.h:
-        (KJS::Lexer::sourceRange): Convenience function to get a source
-        range based on the lexer's source provieder, and char offsets
-        right before and after the desired range.
-        * kjs/function.cpp:
-        (KJS::globalFuncEval): Pass a UStringSourceProvider to the parser.
-        * kjs/function_object.cpp:
-        (KJS::functionProtoFuncToString): Use toSourceString to get the source.
-        (KJS::FunctionObjectImp::construct): Give the parser a UStringSourceProvider.
-        * kjs/grammar.y: When parsing a function declaration, function
-        expression, or getter or setter, tell the function body about its
-        SourceRange.
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::checkSyntax): Pass a SourceProvider to the parser.
-        (KJS::Interpreter::evaluate): Pass a SourceProvider to the parser.
-        * kjs/interpreter.h:
-        * kjs/nodes.h:
-        (KJS::FunctionBodyNode::setSource): Establish a SourceRange for this function.
-        (KJS::FunctionBodyNode::toSourceString): Get the source string out
-        of the SourceRange.
-        (KJS::FuncExprNode::): Take a SourceRange and set it on the body.
-        (KJS::FuncDeclNode::): ditto
-        * kjs/testkjs.cpp:
-        (prettyPrintScript): Use a SourceProvider appropriately.
-        * JavaScriptCore.exp: Export new symbols.
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add new files.
-        * JavaScriptCore.xcodeproj/project.pbxproj: Add new files.
-
-2008-05-09  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bring back RegisterFile tainting in order to correctly handle
-        natively implemented getters and setters that re-enter JavaScript
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/RegisterFile.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-        * kjs/object.cpp:
-        (KJS::JSObject::put):
-        (KJS::tryGetAndCallProperty):
-        * kjs/property_slot.cpp:
-        (KJS::PropertySlot::functionGetter):
-
-2008-05-09  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - track character offsets of open and close braces, in preparation for saving function source
-        
-        I verified that there is no performance regression from this change.
-
-        * kjs/grammar.y:
-        * kjs/lexer.cpp:
-        (KJS::Lexer::lex):
-        (KJS::Lexer::matchPunctuator):
-        * kjs/lexer.h:
-
-2008-05-09  Oliver Hunt  <oliver@apple.com>
-
-        Debug build fix
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::restoreLocalStorage):
-
-2008-05-09  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Build fixes for SquirrelFish on windows.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj:
-        * VM/Register.h:
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::restoreLocalStorage):
-        * kjs/collector.cpp:
-        (KJS::Collector::allocate):
-        (KJS::Collector::allocateNumber):
-        * kjs/collector.h:
-        (KJS::Collector::allocate):
-        (KJS::Collector::allocateNumber):
-        * kjs/property_slot.cpp:
-
-2008-05-08  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - fix activation tearoff in the case where functions are called with too many arguments
-        
-        Fixes:
-        fast/canvas/patternfill-repeat.html
-        fast/dom/SelectorAPI/bug-17313.html
-
-        * VM/Machine.cpp:
-        (KJS::slideRegisterWindowForCall):
-        (KJS::scopeChainForCall):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-
-2008-05-08  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed failure in fast/canvas/canvas-pattern-behaviour.html.
-        
-        SunSpider reports a small speedup. Not sure what that's about.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump): Fixed op_call_eval to dump as "op_call_eval".
-        This helped me while debugging.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::unwindCallFrame): When looking for an activation to tear
-        off, don't use the scope chain. Inside eval, the scope chain doesn't
-        belong to us; it belongs to our calling function.
-        
-        Also, don't use the needsFullScopeChain flag to decide whether to tear
-        off the activation. "function.arguments" can create an activation
-        for a function whose needsFullScopeChain flag is set to false.
-
-2008-05-08  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fix function.call for calls of more than 8 arguments
-        
-        Fixes svg/carto.net/button.svg
-
-        * kjs/list.cpp:
-        (KJS::List::getSlice): properly set up the m_buffer of the target list.
-
-2008-05-08  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - don't return a null RegisterID from RegExpNode in the exception case, since the caller may need a real register
-
-        Fixes:
-        - fast/regex/early-acid3-86.html
-        - http/tests/misc/acid3.html
-        
-        * kjs/nodes.cpp:
-        (KJS::RegExpNode::emitCode):
-
-2008-05-07  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Fix a performance regression caused by the introduction of property
-        attributes to SymbolTable in r32859 by encoding the attributes and the
-        register index into a single field of SymbolTableEntry.
-
-        This leaves Node::optimizeVariableAccess() definitely broken, although
-        it was probably not entirely correct in SquirrelFish before this change.
-
-        * VM/CodeBlock.h:
-        (KJS::missingThisObjectMarker):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addVar):
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::registerForLocal):
-        (KJS::CodeGenerator::registerForLocalConstInit):
-        (KJS::CodeGenerator::isLocalConstant):
-        (KJS::CodeGenerator::addConstant):
-        (KJS::CodeGenerator::emitCall):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::IdentifierMapIndexHashTraits::emptyValue):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::saveLocalStorage):
-        * kjs/JSVariableObject.cpp:
-        (KJS::JSVariableObject::getPropertyNames):
-        (KJS::JSVariableObject::getPropertyAttributes):
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTableGet):
-        (KJS::JSVariableObject::symbolTablePut):
-        (KJS::JSVariableObject::symbolTablePutWithAttributes):
-        * kjs/SymbolTable.h:
-        (KJS::SymbolTableEntry::SymbolTableEntry):
-        (KJS::SymbolTableEntry::isEmpty):
-        (KJS::SymbolTableEntry::getIndex):
-        (KJS::SymbolTableEntry::getAttributes):
-        (KJS::SymbolTableEntry::setAttributes):
-        (KJS::SymbolTableEntry::isReadOnly):
-        * kjs/nodes.cpp:
-        (KJS::getSymbolTableEntry):
-        (KJS::PostIncResolveNode::optimizeVariableAccess):
-        (KJS::PostDecResolveNode::optimizeVariableAccess):
-        (KJS::DeleteResolveNode::optimizeVariableAccess):
-        (KJS::TypeOfResolveNode::optimizeVariableAccess):
-        (KJS::PreIncResolveNode::optimizeVariableAccess):
-        (KJS::PreDecResolveNode::optimizeVariableAccess):
-        (KJS::ReadModifyResolveNode::optimizeVariableAccess):
-        (KJS::AssignResolveNode::optimizeVariableAccess):
-        (KJS::ProgramNode::initializeSymbolTable):
-
-2008-05-06  Maciej Stachowiak  <mjs@apple.com>
-
-        Rubber stamped by Oliver.
-        
-        - add missing ! in an assert that I failed to reverse
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-
-2008-05-06  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fixed "SQUIRRELFISH: window.this shows up as a property, but it shouldn't"
-        https://bugs.webkit.org/show_bug.cgi?id=18868
-        
-        The basic approach is to have "this" only be present in the symbol
-        table at compile time, not runtime.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::~CodeGenerator): Remove "this" from symbol table.
-        (KJS::CodeGenerator::CodeGenerator): Add "this" back when re-using
-        a symbol table.
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::execute): Don't assert that "this" is in the symbol table.
-
-2008-05-06  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Trivial support for function.arguments: Currently, we only support
-        function.arguments from within the scope of function.
-        
-        This fixes the remaining Mozilla JS test failures.
-        
-        SunSpider reports no change.
-
-        * JavaScriptCore.exp:
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Separated scope chain deref from
-        activation register copying: since it is now possible for client code
-        to create an activation on behalf of a function that otherwise wouldn't
-        need one, having an activation no longer necessarily means that you need
-        to deref the scope chain.
-        
-        (KJS::Machine::getCallFrame): For now, this function only examines the
-        current scope. Walking parent scopes requires some refactoring in the
-        way we track execution stacks.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState): We use a negative call frame offset to
-        indicate that a given scope is not a function call scope.
-        
-2008-05-05  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Fix call frame set up for native -> JS function calls.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-
-2008-05-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed ecma_3/Object/8.6.2.6-001.js, and similar bugs.
-        
-        SunSpider reports a .4% speedup. Not sure what that's about.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Check for exception return from equal,
-        since toPrimitive can throw.
-
-        * kjs/operations.cpp:
-        (KJS::strictEqual): In response to an error I made in an earlier version
-        of this patch, I changed strictEqual to make clear the fact that it
-        performs no conversions and can't throw, making it slightly more efficient
-        in the process.
-
-2008-05-05  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fix some dumb mistakes in my last patch
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitPushScope):
-        (KJS::CodeGenerator::emitGetPropertyNames):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-05-05  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - document opcodes relating to jumps, scopes, and property name iteration
-        
-        Documented jmp, jtrue, false, push_scope, pop_scope, get_pnames,
-        next_pname and jmp_scopes.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitJump):
-        (KJS::CodeGenerator::emitJumpIfTrue):
-        (KJS::CodeGenerator::emitJumpIfFalse):
-        (KJS::CodeGenerator::emitPushScope):
-        (KJS::CodeGenerator::emitNextPropertyName):
-        (KJS::CodeGenerator::emitGetPropertyNames):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/nodes.cpp:
-        (KJS::LogicalAndNode::emitCode):
-        (KJS::LogicalOrNode::emitCode):
-        (KJS::ConditionalNode::emitCode):
-        (KJS::IfNode::emitCode):
-        (KJS::IfElseNode::emitCode):
-        (KJS::DoWhileNode::emitCode):
-        (KJS::WhileNode::emitCode):
-        (KJS::ForNode::emitCode):
-        (KJS::ForInNode::emitCode):
-        (KJS::WithNode::emitCode):
-
-2008-05-05  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 18749: SQUIRRELFISH: const support is broken
-        <https://bugs.webkit.org/show_bug.cgi?id=18749>
-
-        Adds support for const during code generation.
-
-        Fixes 2 layout tests.
-
-        * ChangeLog:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addVar):
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::isLocalConstant):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::addVar):
-        * kjs/nodes.cpp:
-        (KJS::PostIncResolveNode::emitCode):
-        (KJS::PostDecResolveNode::emitCode):
-        (KJS::PreIncResolveNode::emitCode):
-        (KJS::PreDecResolveNode::emitCode):
-        (KJS::ReadModifyResolveNode::emitCode):
-        (KJS::AssignResolveNode::emitCode):
-
-2008-05-04  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - document some more opcodes (and fix argument names)
-        
-        Added docs for eq, neq, stricteq, nstriceq, less and lesseq.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitEqual):
-        (KJS::CodeGenerator::emitNotEqual):
-        (KJS::CodeGenerator::emitStrictEqual):
-        (KJS::CodeGenerator::emitNotStrictEqual):
-        (KJS::CodeGenerator::emitLess):
-        (KJS::CodeGenerator::emitLessEq):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/nodes.cpp:
-        (KJS::LessNode::emitCode):
-        (KJS::GreaterNode::emitCode):
-        (KJS::LessEqNode::emitCode):
-        (KJS::GreaterEqNode::emitCode):
-        (KJS::EqualNode::emitCode):
-        (KJS::NotEqualNode::emitCode):
-        (KJS::StrictEqualNode::emitCode):
-        (KJS::NotStrictEqualNode::emitCode):
-        (KJS::CaseBlockNode::emitCodeForBlock):
-
-2008-05-04  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        More scaffolding for f.arguments.
-        
-        Track the offset of the last call frame in the ExecState, so we can
-        produce a backtrace at any time.
-        
-        Also, record numLocals, the sum of numVars + numParameters, in each code
-        block, to make updates to the ExecState a little cheaper than they
-        would be otherwise.
-        
-        We now use numLocals in a bunch of places where we used to calculate
-        numVars + numParameters or -numVars - numParameters.
-        
-        Reports are mixed, but all in all, this seems to be a wash on SunSpider.
-
-2008-05-04  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Whoops, correctly handle properties that don't exist in the 
-        symbol table.
-
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTablePutWithAttributes):
-
-2008-05-04  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Add attribute information to SymbolTable as ground work for
-        various DontEnum and ReadOnly issues.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addVar):
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::registerForLocal):
-        (KJS::CodeGenerator::registerForLocalConstInit):
-        (KJS::CodeGenerator::addConstant):
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::saveLocalStorage):
-        * kjs/JSVariableObject.cpp:
-        (KJS::JSVariableObject::getPropertyNames):
-        (KJS::JSVariableObject::getPropertyAttributes):
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTablePut):
-        (KJS::JSVariableObject::symbolTablePutWithAttributes):
-        * kjs/SymbolTable.h:
-        (KJS::SymbolTableEntry::SymbolTableEntry):
-        (KJS::SymbolTableIndexHashTraits::emptyValue):
-        * kjs/nodes.cpp:
-        (KJS::getSymbolTableEntry):
-        (KJS::ReadModifyResolveNode::optimizeVariableAccess):
-        (KJS::AssignResolveNode::optimizeVariableAccess):
-        (KJS::ProgramNode::initializeSymbolTable):
-
-2008-05-04  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        More scaffolding for f.arguments.
-        
-        Store the register file associated with an ExecState in the ExecState.
-        
-        SunSpider reports no change.
-
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData): Moved
-        registerFileStack above globalExec, so it gets initialized first.
-        Removed remnants of old activation scheme.
-
-2008-05-04  Maciej Stachowiak  <mjs@apple.com>
-
-        Rubber stamped by Oliver.
-        
-        - renamed a few opcodes and fixed assembly formatting to accomodate the longest opcode
-        
-        equal --> eq
-        nequal --> neq
-        resolve_base_and_property --> resolve_with_base
-        resolve_base_and_func --> resolve_func
-        get_prop_id --> get_by_id
-        put_prop_id --> put_by_id
-        delete_prop_id --> del_by_id
-        get_prop_val --> get_by_val
-        put_prop_val --> put_by_val
-        delete_prop_val --> del_by_val
-        put_prop_index --> put_by_index
-        
-        * VM/CodeBlock.cpp:
-        (KJS::printUnaryOp):
-        (KJS::printBinaryOp):
-        (KJS::printConditionalJump):
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitEqual):
-        (KJS::CodeGenerator::emitNotEqual):
-        (KJS::CodeGenerator::emitResolveWithBase):
-        (KJS::CodeGenerator::emitResolveFunction):
-        (KJS::CodeGenerator::emitGetById):
-        (KJS::CodeGenerator::emitPutById):
-        (KJS::CodeGenerator::emitDeleteById):
-        (KJS::CodeGenerator::emitGetByVal):
-        (KJS::CodeGenerator::emitPutByVal):
-        (KJS::CodeGenerator::emitDeleteByVal):
-        (KJS::CodeGenerator::emitPutByIndex):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::ArrayNode::emitCode):
-        (KJS::PropertyListNode::emitCode):
-        (KJS::BracketAccessorNode::emitCode):
-        (KJS::DotAccessorNode::emitCode):
-        (KJS::EvalFunctionCallNode::emitCode):
-        (KJS::FunctionCallResolveNode::emitCode):
-        (KJS::FunctionCallBracketNode::emitCode):
-        (KJS::FunctionCallDotNode::emitCode):
-        (KJS::PostIncResolveNode::emitCode):
-        (KJS::PostDecResolveNode::emitCode):
-        (KJS::PostIncBracketNode::emitCode):
-        (KJS::PostDecBracketNode::emitCode):
-        (KJS::PostIncDotNode::emitCode):
-        (KJS::PostDecDotNode::emitCode):
-        (KJS::DeleteResolveNode::emitCode):
-        (KJS::DeleteBracketNode::emitCode):
-        (KJS::DeleteDotNode::emitCode):
-        (KJS::TypeOfResolveNode::emitCode):
-        (KJS::PreIncResolveNode::emitCode):
-        (KJS::PreDecResolveNode::emitCode):
-        (KJS::PreIncBracketNode::emitCode):
-        (KJS::PreDecBracketNode::emitCode):
-        (KJS::PreIncDotNode::emitCode):
-        (KJS::PreDecDotNode::emitCode):
-        (KJS::ReadModifyResolveNode::emitCode):
-        (KJS::AssignResolveNode::emitCode):
-        (KJS::AssignDotNode::emitCode):
-        (KJS::ReadModifyDotNode::emitCode):
-        (KJS::AssignBracketNode::emitCode):
-        (KJS::ReadModifyBracketNode::emitCode):
-        (KJS::ConstDeclNode::emitCodeSingle):
-        (KJS::ForInNode::emitCode):
-        (KJS::TryNode::emitCode):
-
-2008-05-04  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Fix assertion when accessing arguments object with too many arguments provided
-
-        The arguments constructor was assuming that the register offset given for argv
-        was an absolute offset into the registerfile, rather than the offset from the
-        frame.  This patches corrects that issue.
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::createArgumentsObject):
-
-2008-05-04  Geoffrey Garen  <ggaren@apple.com>
-
-        Rubber stamped by Sam Weinig.
-        
-        Cleaned up Machine.cpp according to our style guidelines: moved static
-        data to the top of the file; moved stand-alone functions below that;
-        moved the Machine constructor above other Machine member functions.
-
-2008-05-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Sam.
-        
-        - fix accidental breakage from last patch
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-05-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - a bunch more opcode documentation and corresponding parameter name fixes
-
-        I renamed a few opcodes:
-        
-        type_of --> typeof (that's what the JS operator is named)
-        instance_of --> instanceof (ditto)
-        create_error --> new_error (for consistency with other new_* opcodes)
-        
-        I documented the following opcodes:
-        
-        - load
-        - new_object
-        - new_array
-        - new_regexp
-        - mov
-        - pre_inc
-        - pre_dec
-        - post_inc
-        - post_dec
-        - to_jsnumber
-        - negate
-        - bitnot
-        - not
-        - instanceof
-        - typeof
-        - in
-        - new_func
-        - new_funcexp
-        - new_error
-
-        I also fixed formatting on some existing opcode docs.
-        
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitMove):
-        (KJS::CodeGenerator::emitNot):
-        (KJS::CodeGenerator::emitPreInc):
-        (KJS::CodeGenerator::emitPreDec):
-        (KJS::CodeGenerator::emitPostInc):
-        (KJS::CodeGenerator::emitPostDec):
-        (KJS::CodeGenerator::emitToJSNumber):
-        (KJS::CodeGenerator::emitNegate):
-        (KJS::CodeGenerator::emitBitNot):
-        (KJS::CodeGenerator::emitInstanceOf):
-        (KJS::CodeGenerator::emitTypeOf):
-        (KJS::CodeGenerator::emitIn):
-        (KJS::CodeGenerator::emitLoad):
-        (KJS::CodeGenerator::emitNewObject):
-        (KJS::CodeGenerator::emitNewArray):
-        (KJS::CodeGenerator::emitNewRegExp):
-        (KJS::CodeGenerator::emitNewError):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::scopeDepth):
-        (KJS::CodeGenerator::addVar):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::Node::emitThrowError):
-        (KJS::RegExpNode::emitCode):
-        (KJS::TypeOfValueNode::emitCode):
-        (KJS::UnaryPlusNode::emitCode):
-        (KJS::NegateNode::emitCode):
-        (KJS::BitwiseNotNode::emitCode):
-        (KJS::LogicalNotNode::emitCode):
-        (KJS::InstanceOfNode::emitCode):
-        (KJS::InNode::emitCode):
-
-2008-05-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff and Sam.
-        
-        - generate HTML bytecode docs at build time
-
-        * DerivedSources.make:
-        * docs: Added.
-        * docs/make-bytecode-docs.pl: Added.
-
-2008-05-03  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Update ExecState::m_scopeChain when switching scope chains inside the
-        machine.
-        
-        This fixes uses of lexicalGlobalObject, such as, in a subframe
-
-            alert(top.makeArray() instanceof Array ? "FAIL" : "PASS");
-        
-        and a bunch of the security failures listed in
-        https://bugs.webkit.org/show_bug.cgi?id=18870. (Those tests still fail,
-        seemingly because of regressions in exception messages).
-        
-        SunSpider reports no change.
-
-        * VM/Machine.cpp: Factored out scope chain updating into a common
-        function that takes care to update ExecState::m_scopeChain, too.
-
-        * kjs/ExecState.h: I made Machine a friend of ExecState so that Machine
-        could update ExecState::m_scopeChain, even though that value is
-        read-only for everyone else.
-
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData): Changed
-        this client to be a little friendlier to ExecState's internal
-        storage type for scope chain data.
-
-2008-05-03  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Fixed https://bugs.webkit.org/show_bug.cgi?id=18876
-        Squirrelfish: ScopeChainNode leak in op_jmp_scopes.
-        
-        SunSpider reports no change.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Don't construct a ScopeChain object,
-        since the direct threaded interpreter will goto across its destructor.
-
-2008-05-03  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        A bit more efficient fix than r32832: Don't copy globals into function
-        register files; instead, have the RegisterFileStack track only the base
-        of the last *global* register file, so the global object's register
-        references stay good.
-        
-        SunSpider reports a .3% speedup. Not sure what that's about.
-
-2008-05-03  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18864: SquirrelFish: Support getter and setter definition in object literals
-        <https://bugs.webkit.org/show_bug.cgi?id=18864>
-
-        Add new opcodes to allow us to add getters and setters to an object.  These are
-        only used by the codegen for object literals.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitPutGetter):
-        (KJS::CodeGenerator::emitPutSetter):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::PropertyListNode::emitCode):
-
-2008-05-02  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - properly copy globals into and out of implicit call register
-        files, otherwise they will fail at global lookup
-
-        Fixes fast/js/array-tostring-and-join.html layout test.
-        
-        * VM/RegisterFileStack.cpp:
-        (KJS::RegisterFileStack::pushGlobalRegisterFile):
-        (KJS::RegisterFileStack::popGlobalRegisterFile):
-        (KJS::RegisterFileStack::pushFunctionRegisterFile):
-        (KJS::RegisterFileStack::popFunctionRegisterFile):
-
-2008-05-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed https://bugs.webkit.org/show_bug.cgi?id=18822
-        SQUIRRELFISH: incorrect eval used in some cases
-        
-        Changed all code inside the machine to fetch the lexical global object
-        directly from the scope chain, instead of from the ExecState.
-        
-        Clients who fetch the lexical global object through the ExecState
-        still don't work.
-        
-        SunSpider reports no change.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Fetch the lexical global object from
-        the scope chain.
-        
-        * kjs/ExecState.h:
-        (KJS::ExecState::ExecState::lexicalGlobalObject): Moved the logic for
-        this function into ScopeChainNode, but kept this function around to
-        support existing clients.
-
-2008-05-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Rubber stamped by Oliver Hunt.
-        
-        Removed ExecState.cpp from AllInOneFile.cpp, for a .2% speedup.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/AllInOneFile.cpp:
-
-2008-05-01  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff and Maciej.
-
-        Bug 18827: SquirrelFish: Prevent getters and setters from destroying the current RegisterFile
-        <https://bugs.webkit.org/show_bug.cgi?id=18827>
-
-        Remove safe/unsafe RegisterFile concept, and instead just add additional
-        logic to ensure we always push/pop RegisterFiles when executing getters
-        and setters, similar to the logic for valueOf and toString.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/RegisterFile.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-        * kjs/object.cpp:
-        (KJS::JSObject::put):
-        * kjs/property_slot.cpp:
-        (KJS::PropertySlot::functionGetter):
-
-2008-05-01  Oliver Hunt  <oliver@apple.com>
-
-        RS=Geoff
-
-        Rename unsafeForReentry to safeForReentry to avoid double negatives.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/RegisterFile.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-
-2008-05-01  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18827: SquirrelFish: Prevent getters and setters from destroying the current RegisterFile
-        <https://bugs.webkit.org/show_bug.cgi?id=18827>
-        
-        This patch makes getters and setters work.  It does this by
-        tracking whether the RegisterFile is "safe", that is whether
-        the interpreter is in a state that in which it can handle
-        the RegisterFile being reallocated.
-
-        * VM/Machine.cpp:
-        (KJS::resolve):
-        (KJS::Machine::privateExecute):
-        * VM/RegisterFile.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-
-2008-04-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Release build fix: Always compile in "isGlobalObject", since it's
-        listed in our .exp file.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::isGlobalObject):
-        * kjs/ExecState.h:
-
-2008-04-30  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Minor code restructuring to prepare for getters and setters, 
-        also helps exception semantics a bit.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Fixed tyop.
-
-        * kjs/ExecState.h:
-
-2008-04-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Debug build fix: export a missing symbol.
-
-        * JavaScriptCore.exp:
-
-2008-04-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        A little more ExecState refactoring: Now, only the global object creates
-        an ExecState.
-        
-        Also inlined ExecState::lexicalGlobalObject().
-        
-        SunSpider reports no change.
-
-2008-04-30  Geoffrey Garen  <ggaren@apple.com>
-
-        WebCore build fix: forward-declare ScopeChain.
-
-        * kjs/interpreter.h:
-
-2008-04-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix for JavaScriptGlue: export a missing symbol.
-
-        * JavaScriptCore.exp:
-
-2008-04-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Removed a lot of unused bits from ExecState, moving them into
-        OldInterpreterExecState, the fake scaffolding class.
-        
-        The clutter was making it hard to see the forest from the trees.
-        
-        .4% SunSpider speedup, probably because ExecState::lexicalGlobalObject()
-        is faster now.
-
-2008-04-29  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18643: SQUIRRELFISH: need to support implicit function calls (valueOf, toString, getters/setters)
-        <https://bugs.webkit.org/show_bug.cgi?id=18643>
-
-        Prevent static slot optimisation for new variables and functions in
-        globally re-entrant code called from an an implicit function call.
-
-        This is necessary to prevent us from needing to resize the global
-        slot portion of the root RegisterFile during an implicit (and hence
-        unguarded) function call.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * VM/RegisterFile.h:
-        * VM/RegisterFileStack.cpp:
-        (KJS::RegisterFileStack::pushGlobalRegisterFile):
-        (KJS::RegisterFileStack::popGlobalRegisterFile):
-        (KJS::RegisterFileStack::pushFunctionRegisterFile):
-        (KJS::RegisterFileStack::popFunctionRegisterFile):
-        * VM/RegisterFileStack.h:
-        (KJS::RegisterFileStack::inImplicitFunctionCall):
-        (KJS::RegisterFileStack::lastGlobal):
-        * kjs/nodes.cpp:
-        (KJS::ProgramNode::generateCode):
-        * kjs/nodes.h:
-        (KJS::ProgramNode::):
-
-2008-04-29  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        In nested program code, don't propogate "this" back to the parent
-        register file. ("this" should remain constant in the parent register
-        file, regardless of the scripts it invokes.)
-
-        * VM/RegisterFile.cpp:
-        (KJS::RegisterFile::copyGlobals):
-
-2008-04-28  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Restore base pointer when popping a global RegisterFile
-
-        * VM/RegisterFileStack.cpp:
-        (KJS::RegisterFileStack::popGlobalRegisterFile):
-
-2008-04-28  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 18643: SQUIRRELFISH: need to support implicit function calls (valueOf, toString, getters/setters)
-        <https://bugs.webkit.org/show_bug.cgi?id=18643>
-
-        Partial fix.  This results in all implicit calls to toString or valueOf
-        executing in a separate RegisterFile, so ensuring that the the pointers
-        in the triggering interpreter don't get trashed.  This still leaves the
-        task of preventing new global re-entry from toString and valueOf from
-        clobbering the RegisterFile.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * VM/RegisterFileStack.cpp:
-        (KJS::RegisterFileStack::pushFunctionRegisterFile):
-        (KJS::RegisterFileStack::popFunctionRegisterFile):
-        * VM/RegisterFileStack.h:
-        * kjs/object.cpp:
-        (KJS::tryGetAndCallProperty):
-
-2008-04-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Simplified activation object a bit: No need to store the callee
-        in the activation object -- we can pull it out of the call frame
-        when needed, instead.
-        
-        SunSpider reports no change.
-
-2008-04-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        RS by Oliver Hunt on moving JSArguments.cpp out of AllInOneFile.cpp.
-
-        Substantially more handling of "arguments": "arguments" works fully
-        now, but "f.arguments" still doesn't work.
-
-        Fixes 10 regression tests.
-        
-        SunSpider reports no regression.
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::createArgumentsObject): Reconstruct an arguments
-        List to pass to the arguments object constructor.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/AllInOneFile.cpp: Removed JSActivation.cpp from AllInOneFile.cpp
-        because that seems to make GCC happy. (Previously, I had added
-        JSActivation.cpp to AllInOneFile.cpp because *that* seemed to make GCC
-        happy. So it goes.)
-
-2008-04-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Groundwork for more handling of "arguments". I'm not checking in the
-        actual handling of "arguments" yet, because it still needs a little
-        fiddling to avoid a performance regression.
-        
-        SunSpider reports no change.
-
-        * VM/Machine.cpp:
-        (KJS::initializeCallFrame): Put argc in the register file, so the
-        arguments object can find it later, to determine arguments.length.
-
-        * kjs/nodes.h:
-        (KJS::FunctionBodyNode::): Added a special code accessor for when you
-        know the code has already been generated, and you don't have a scopeChain
-        to supply for potential code generation. (This is the case when the
-        activation object creates the arguments object.)
-
-2008-04-28  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Replace unsafe use of auto_ptr in Vector with manual memory
-        management.
-
-        * VM/RegisterFileStack.cpp:
-        (KJS::RegisterFileStack::~RegisterFileStack):
-        (KJS::RegisterFileStack::popRegisterFile):
-        * VM/RegisterFileStack.h:
-
-2008-04-27  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 18746: SQUIRRELFISH: indirect eval used when direct eval should be used
-        <https://bugs.webkit.org/show_bug.cgi?id=18746>
-
-        Change the base to the correct value of the 'this' object after the direct
-        eval test instead of before.
-
-        Fixes 5 layout tests.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/nodes.cpp:
-        (KJS::EvalFunctionCallNode::emitCode):
-
-2008-04-26  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - document all property getting, setting and deleting opcodes
-        
-        (And fix function parameter names to match corresponding opcode parameter names.)
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitResolve):
-        (KJS::CodeGenerator::emitResolveBase):
-        (KJS::CodeGenerator::emitResolveBaseAndProperty):
-        (KJS::CodeGenerator::emitResolveBaseAndFunc):
-        (KJS::CodeGenerator::emitGetPropId):
-        (KJS::CodeGenerator::emitPutPropId):
-        (KJS::CodeGenerator::emitDeletePropId):
-        (KJS::CodeGenerator::emitPutPropVal):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::resolve):
-        (KJS::resolveBase):
-        (KJS::resolveBaseAndProperty):
-        (KJS::resolveBaseAndFunc):
-        (KJS::Machine::privateExecute):
-        * kjs/nodes.cpp:
-        (KJS::ResolveNode::emitCode):
-        (KJS::ArrayNode::emitCode):
-        (KJS::PropertyListNode::emitCode):
-        (KJS::BracketAccessorNode::emitCode):
-        (KJS::EvalFunctionCallNode::emitCode):
-        (KJS::FunctionCallResolveNode::emitCode):
-        (KJS::FunctionCallBracketNode::emitCode):
-        (KJS::PostIncResolveNode::emitCode):
-        (KJS::PostDecResolveNode::emitCode):
-        (KJS::PostIncBracketNode::emitCode):
-        (KJS::PostDecBracketNode::emitCode):
-        (KJS::PostIncDotNode::emitCode):
-        (KJS::PostDecDotNode::emitCode):
-        (KJS::DeleteResolveNode::emitCode):
-        (KJS::TypeOfResolveNode::emitCode):
-        (KJS::PreIncResolveNode::emitCode):
-        (KJS::PreDecResolveNode::emitCode):
-        (KJS::PreIncBracketNode::emitCode):
-        (KJS::PreDecBracketNode::emitCode):
-        (KJS::AssignResolveNode::emitCode):
-        (KJS::AssignDotNode::emitCode):
-        (KJS::ReadModifyDotNode::emitCode):
-        (KJS::AssignBracketNode::emitCode):
-        (KJS::ReadModifyBracketNode::emitCode):
-        (KJS::ConstDeclNode::emitCodeSingle):
-
-2008-04-26  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18628: SQUIRRELFISH: need to support recursion limit
-        <https://bugs.webkit.org/show_bug.cgi?id=18628>
-
-        Basically completes recursion limiting.  There is still some
-        tuning we may want to do to make things better in the face of
-        very bad code, but certainly nothing worse than anything already
-        possible in trunk.
-
-        Also fixes a WebKit test by fixing the exception text :D
-
-        * JavaScriptCore.exp:
-        * VM/ExceptionHelpers.cpp:
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * VM/RegisterFile.cpp:
-        (KJS::RegisterFile::growBuffer):
-        (KJS::RegisterFile::addGlobalSlots):
-        * VM/RegisterFile.h:
-        (KJS::RegisterFile::grow):
-        (KJS::RegisterFile::uncheckedGrow):
-        * VM/RegisterFileStack.cpp:
-        (KJS::RegisterFileStack::pushRegisterFile):
-        * VM/RegisterFileStack.h:
-
-2008-04-25  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 18628: SQUIRRELFISH: need to support recursion limit
-        <https://bugs.webkit.org/show_bug.cgi?id=18628>
-
-        Put a limit on the level of reentry recursion.  128 levels of re-entrant recursion
-        seems reasonable as it is greater than the old eval limit, and a long way short of
-        the reentry depth needed to overflow the stack.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * VM/Machine.h:
-
-2008-04-25  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        A tiny bit of cleanup to the regexp code.
-        
-        Removed some static_cast.
-        
-        Removed createRegExpImp because it's no longer used.
-
-2008-04-25  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18736: SQUIRRELFISH: switch statements with no default have incorrect codegen
-        <https://bugs.webkit.org/show_bug.cgi?id=18736>
-
-        Ensure the "default" target is correct in the absence of an explicit default handler.
-
-        * kjs/nodes.cpp:
-        (KJS::CaseBlockNode::emitCodeForBlock):
-
-2008-04-25  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18628: SQUIRRELFISH: need to support recursion limit
-        <https://bugs.webkit.org/show_bug.cgi?id=18628>
-
-        More bounds checking.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * VM/RegisterFile.cpp:
-        (KJS::RegisterFile::growBuffer):
-        * VM/RegisterFile.h:
-
-2008-04-25  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fix signal catching magic
-        
-        The signal handlers are restored to _exit but are only set when
-        running under run-javascriptcore-tests. fprintf from a signal
-        handler is not safe.
-
-        * kjs/testkjs.cpp:
-        (main):
-        (parseArguments):
-        * tests/mozilla/jsDriver.pl:
-
-2008-04-25  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 18732: SQUIRRELFISH: exceptions thrown by native constructors are ignored
-        <https://bugs.webkit.org/show_bug.cgi?id=18732>
-
-        Fixes another regression test.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-25  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 18728: SQUIRRELFISH: invalid regular expression constants should throw exceptions
-        <https://bugs.webkit.org/show_bug.cgi?id=18728>
-
-        Fixes another regression test.
-
-        * kjs/nodes.cpp:
-        (KJS::RegExpNode::emitCode):
-
-2008-04-24  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Geoffrey Garen.
-
-        Bug 18735: SQUIRRELFISH: closures are sometimes given an incorrect 'this' value when called
-        <https://bugs.webkit.org/show_bug.cgi?id=18735>
-
-        The overloaded toThisObject method was not copied over to JSActivation.
-
-        Fixes two regression tests.
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::toThisObject):
-        * kjs/JSActivation.h:
-
-2008-04-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Added support for arguments.callee.
-
-2008-04-24  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18628: SQUIRRELFISH: need to support recursion limit
-        <https://bugs.webkit.org/show_bug.cgi?id=18628>
-
-        Partial fix -- this gets us some of the required bounds checking, but not
-        complete coverage.  But it does manage to do them without regressing :D
-
-        * VM/ExceptionHelpers.cpp:
-        (KJS::createError):
-        (KJS::createStackOverflowError):
-        * VM/ExceptionHelpers.h:
-        * VM/Machine.cpp:
-        (KJS::slideRegisterWindowForCall):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/RegisterFile.cpp:
-        * VM/RegisterFile.h:
-        (KJS::RegisterFile::):
-        (KJS::RegisterFile::RegisterFile):
-        (KJS::RegisterFile::grow):
-
-2008-04-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        A tiny bit more handling of "arguments": create a real, but mostly
-        hollow, arguments object.
-        
-        Fixes 2 regression tests.
-
-2008-04-24  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 18717: SQUIRRELFISH: eval returns the wrong value for a variable declaration statement
-        <https://bugs.webkit.org/show_bug.cgi?id=18717>
-
-        Fixes a regression test, but exposes the failure of another due to the
-        lack of getters and setters.
-
-        * kjs/nodes.cpp:
-        (KJS::ConstDeclNode::emitCodeSingle):
-        (KJS::ConstDeclNode::emitCode):
-        (KJS::ConstStatementNode::emitCode):
-        (KJS::VarStatementNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Print a CRASH statement when crashing, so test failures are not a
-        mystery.
-
-        * kjs/testkjs.cpp:
-        (handleCrash):
-        (main):
-
-2008-04-24  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Geoffrey Garen.
-
-        Bug 18716: SQUIRRELFISH: typeof should return undefined for an undefined variable reference
-        <https://bugs.webkit.org/show_bug.cgi?id=18716>
-
-        This fixes 2 more regression tests.
-
-        * kjs/nodes.cpp:
-        (KJS::TypeOfResolveNode::emitCode):
-
-2008-04-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Put the callee in the call frame.
-        
-        Necessary in order to support "arguments" and "arguments.callee".
-
-        Also fixes a latent GC bug, where an executing function could be
-        subject to GC if the register holding it were overwritten. Here's
-        an example that would have caused problems:
-        
-        function f()
-        {
-            // Flood the machine stack to eliminate any old pointers to f.
-            g.call({});
-            
-            // Overwrite f in the register file.
-            f = 1;
-
-            // Force a GC.
-            for (var i = 0; i < 5000; ++i) {
-                ({});
-            }
-            
-            // Welcome to crash-ville.
-        }
-
-        function g()
-        {
-        }
-
-        f();
-
-        * VM/Machine.h: Changed the order of arguments to
-        execute(FunctionBodyNode*...) to match the other execute functions.
-        * kjs/function.cpp: Updated to match new argument requirements from
-        execute(FunctionBodyNode*...). Renamed newObj to thisObj to match the
-        rest of JavaScriptCore.
-
-        SunSpider reports no change.
-
-2008-04-23  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 18707: SQUIRRELFISH: eval always performs toString() on its argument
-        <https://bugs.webkit.org/show_bug.cgi?id=18707>
-
-        This fixes 4 more regression tests.
-
-        * VM/Machine.cpp:
-        (KJS::eval):
-
-2008-04-23  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fix logic bug in SegmentedVector::grow which would sometimes fail to resize a segment when needed
-        
-        Fixes 3 JSC tests.
-
-        * VM/SegmentedVector.h:
-        (KJS::SegmentedVector::grow):
-
-2008-04-23  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Degenerate handling of "arguments" as a property of the activation
-        object. Currently, we just return a vanilla object.
-        
-        SunSpider reports no change.
-
-        Fixes:
-
-        ecma_3/Function/regress-94506.js.
-        
-        Reveals to have been secretly broken:
-
-        ecma_3/Function/15.3.4.3-1.js
-        ecma_3/Function/15.3.4.4-1.js
-        
-        These tests were passing incorrectly. testkjs creates a global array
-        named "arguments" to hold command-line arguments. That array was
-        tricking these tests into thinking that an arguments object with length
-        0 had been created. Since our new vanilla object shadows the global
-        property named arguments, that object no longer fools these tests into
-        passing.
-        
-        Net change: +1 failing test.
-
-        * kjs/AllInOneFile.cpp: Had to put JSActivation.cpp into AllInOneFile.cpp
-        to solve a surprising 8.6% regression in bitops-3bit-bits-in-byte.
-
-2008-04-23  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - save and restore callFrame
-
-        * VM/Machine.cpp:
-        (KJS::slideRegisterWindowForCall):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * kjs/testkjs.cpp:
-        (main):
-
-2008-04-23  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed scopes for named function expressions.
-        
-        Fixes one regression test.
-        
-        Two changes here:
-        
-        (1) The function's name is supposed to have attributes DontDelete,
-        ReadOnly, regardless of the type of code executing.
-        
-        (2) Push the name object on the function's scope chain, rather than
-        the ExecState's scope chain because, well, that's where it belongs.
-
-2008-04-23  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Inlined JSObject::putDirect, for a .4% SunSpider speedup.
-        
-        I did this as a first step toward removing nodes.cpp from
-        AllInOneFile.cpp, but I'm putting that larger project aside for now.
-
-2008-04-23  Maciej Stachowiak  <mjs@apple.com>
-
-        Rubber stamped by Geoff.
-        
-        - add OldInterpreterExecState class and use it in dead code
-        
-        This will allow removing things from the real ExecState class
-        without having to figure out how to remove all this code without
-        getting a perf regression.
-
-        * kjs/nodes.cpp:
-        (KJS::ExpressionNode::evaluateToNumber):
-        (KJS::ExpressionNode::evaluateToBoolean):
-        (KJS::ExpressionNode::evaluateToInt32):
-        (KJS::ExpressionNode::evaluateToUInt32):
-        (KJS::Node::setErrorCompletion):
-        (KJS::Node::throwError):
-        (KJS::Node::throwUndefinedVariableError):
-        (KJS::Node::handleException):
-        (KJS::Node::rethrowException):
-        (KJS::BreakpointCheckStatement::execute):
-        (KJS::BreakpointCheckStatement::optimizeVariableAccess):
-        (KJS::NullNode::evaluate):
-        (KJS::FalseNode::evaluate):
-        (KJS::TrueNode::evaluate):
-        (KJS::NumberNode::evaluate):
-        (KJS::NumberNode::evaluateToNumber):
-        (KJS::NumberNode::evaluateToBoolean):
-        (KJS::NumberNode::evaluateToInt32):
-        (KJS::NumberNode::evaluateToUInt32):
-        (KJS::ImmediateNumberNode::evaluate):
-        (KJS::ImmediateNumberNode::evaluateToInt32):
-        (KJS::ImmediateNumberNode::evaluateToUInt32):
-        (KJS::StringNode::evaluate):
-        (KJS::StringNode::evaluateToNumber):
-        (KJS::StringNode::evaluateToBoolean):
-        (KJS::RegExpNode::evaluate):
-        (KJS::ThisNode::evaluate):
-        (KJS::ResolveNode::inlineEvaluate):
-        (KJS::ResolveNode::evaluate):
-        (KJS::ResolveNode::evaluateToNumber):
-        (KJS::ResolveNode::evaluateToBoolean):
-        (KJS::ResolveNode::evaluateToInt32):
-        (KJS::ResolveNode::evaluateToUInt32):
-        (KJS::getSymbolTableEntry):
-        (KJS::ResolveNode::optimizeVariableAccess):
-        (KJS::LocalVarAccessNode::inlineEvaluate):
-        (KJS::LocalVarAccessNode::evaluate):
-        (KJS::LocalVarAccessNode::evaluateToNumber):
-        (KJS::LocalVarAccessNode::evaluateToBoolean):
-        (KJS::LocalVarAccessNode::evaluateToInt32):
-        (KJS::LocalVarAccessNode::evaluateToUInt32):
-        (KJS::getNonLocalSymbol):
-        (KJS::ScopedVarAccessNode::inlineEvaluate):
-        (KJS::ScopedVarAccessNode::evaluate):
-        (KJS::ScopedVarAccessNode::evaluateToNumber):
-        (KJS::ScopedVarAccessNode::evaluateToBoolean):
-        (KJS::ScopedVarAccessNode::evaluateToInt32):
-        (KJS::ScopedVarAccessNode::evaluateToUInt32):
-        (KJS::NonLocalVarAccessNode::inlineEvaluate):
-        (KJS::NonLocalVarAccessNode::evaluate):
-        (KJS::NonLocalVarAccessNode::evaluateToNumber):
-        (KJS::NonLocalVarAccessNode::evaluateToBoolean):
-        (KJS::NonLocalVarAccessNode::evaluateToInt32):
-        (KJS::NonLocalVarAccessNode::evaluateToUInt32):
-        (KJS::ElementNode::optimizeVariableAccess):
-        (KJS::ElementNode::evaluate):
-        (KJS::ArrayNode::optimizeVariableAccess):
-        (KJS::ArrayNode::evaluate):
-        (KJS::ObjectLiteralNode::optimizeVariableAccess):
-        (KJS::ObjectLiteralNode::evaluate):
-        (KJS::PropertyListNode::optimizeVariableAccess):
-        (KJS::PropertyListNode::evaluate):
-        (KJS::PropertyNode::optimizeVariableAccess):
-        (KJS::PropertyNode::evaluate):
-        (KJS::BracketAccessorNode::optimizeVariableAccess):
-        (KJS::BracketAccessorNode::inlineEvaluate):
-        (KJS::BracketAccessorNode::evaluate):
-        (KJS::BracketAccessorNode::evaluateToNumber):
-        (KJS::BracketAccessorNode::evaluateToBoolean):
-        (KJS::BracketAccessorNode::evaluateToInt32):
-        (KJS::BracketAccessorNode::evaluateToUInt32):
-        (KJS::DotAccessorNode::optimizeVariableAccess):
-        (KJS::DotAccessorNode::inlineEvaluate):
-        (KJS::DotAccessorNode::evaluate):
-        (KJS::DotAccessorNode::evaluateToNumber):
-        (KJS::DotAccessorNode::evaluateToBoolean):
-        (KJS::DotAccessorNode::evaluateToInt32):
-        (KJS::DotAccessorNode::evaluateToUInt32):
-        (KJS::ArgumentListNode::optimizeVariableAccess):
-        (KJS::ArgumentListNode::evaluateList):
-        (KJS::ArgumentsNode::optimizeVariableAccess):
-        (KJS::NewExprNode::optimizeVariableAccess):
-        (KJS::NewExprNode::inlineEvaluate):
-        (KJS::NewExprNode::evaluate):
-        (KJS::NewExprNode::evaluateToNumber):
-        (KJS::NewExprNode::evaluateToBoolean):
-        (KJS::NewExprNode::evaluateToInt32):
-        (KJS::NewExprNode::evaluateToUInt32):
-        (KJS::ExpressionNode::resolveAndCall):
-        (KJS::EvalFunctionCallNode::optimizeVariableAccess):
-        (KJS::EvalFunctionCallNode::evaluate):
-        (KJS::FunctionCallValueNode::optimizeVariableAccess):
-        (KJS::FunctionCallValueNode::evaluate):
-        (KJS::FunctionCallResolveNode::optimizeVariableAccess):
-        (KJS::FunctionCallResolveNode::inlineEvaluate):
-        (KJS::FunctionCallResolveNode::evaluate):
-        (KJS::FunctionCallResolveNode::evaluateToNumber):
-        (KJS::FunctionCallResolveNode::evaluateToBoolean):
-        (KJS::FunctionCallResolveNode::evaluateToInt32):
-        (KJS::FunctionCallResolveNode::evaluateToUInt32):
-        (KJS::LocalVarFunctionCallNode::inlineEvaluate):
-        (KJS::LocalVarFunctionCallNode::evaluate):
-        (KJS::LocalVarFunctionCallNode::evaluateToNumber):
-        (KJS::LocalVarFunctionCallNode::evaluateToBoolean):
-        (KJS::LocalVarFunctionCallNode::evaluateToInt32):
-        (KJS::LocalVarFunctionCallNode::evaluateToUInt32):
-        (KJS::ScopedVarFunctionCallNode::inlineEvaluate):
-        (KJS::ScopedVarFunctionCallNode::evaluate):
-        (KJS::ScopedVarFunctionCallNode::evaluateToNumber):
-        (KJS::ScopedVarFunctionCallNode::evaluateToBoolean):
-        (KJS::ScopedVarFunctionCallNode::evaluateToInt32):
-        (KJS::ScopedVarFunctionCallNode::evaluateToUInt32):
-        (KJS::NonLocalVarFunctionCallNode::inlineEvaluate):
-        (KJS::NonLocalVarFunctionCallNode::evaluate):
-        (KJS::NonLocalVarFunctionCallNode::evaluateToNumber):
-        (KJS::NonLocalVarFunctionCallNode::evaluateToBoolean):
-        (KJS::NonLocalVarFunctionCallNode::evaluateToInt32):
-        (KJS::NonLocalVarFunctionCallNode::evaluateToUInt32):
-        (KJS::FunctionCallBracketNode::optimizeVariableAccess):
-        (KJS::FunctionCallBracketNode::evaluate):
-        (KJS::FunctionCallDotNode::optimizeVariableAccess):
-        (KJS::FunctionCallDotNode::inlineEvaluate):
-        (KJS::FunctionCallDotNode::evaluate):
-        (KJS::FunctionCallDotNode::evaluateToNumber):
-        (KJS::FunctionCallDotNode::evaluateToBoolean):
-        (KJS::FunctionCallDotNode::evaluateToInt32):
-        (KJS::FunctionCallDotNode::evaluateToUInt32):
-        (KJS::PostIncResolveNode::optimizeVariableAccess):
-        (KJS::PostIncResolveNode::evaluate):
-        (KJS::PostIncLocalVarNode::evaluate):
-        (KJS::PostDecResolveNode::optimizeVariableAccess):
-        (KJS::PostDecResolveNode::evaluate):
-        (KJS::PostDecLocalVarNode::evaluate):
-        (KJS::PostDecLocalVarNode::inlineEvaluateToNumber):
-        (KJS::PostDecLocalVarNode::evaluateToNumber):
-        (KJS::PostDecLocalVarNode::evaluateToBoolean):
-        (KJS::PostDecLocalVarNode::evaluateToInt32):
-        (KJS::PostDecLocalVarNode::evaluateToUInt32):
-        (KJS::PostfixBracketNode::optimizeVariableAccess):
-        (KJS::PostIncBracketNode::evaluate):
-        (KJS::PostDecBracketNode::evaluate):
-        (KJS::PostfixDotNode::optimizeVariableAccess):
-        (KJS::PostIncDotNode::evaluate):
-        (KJS::PostDecDotNode::evaluate):
-        (KJS::PostfixErrorNode::evaluate):
-        (KJS::DeleteResolveNode::optimizeVariableAccess):
-        (KJS::DeleteResolveNode::evaluate):
-        (KJS::LocalVarDeleteNode::evaluate):
-        (KJS::DeleteBracketNode::optimizeVariableAccess):
-        (KJS::DeleteBracketNode::evaluate):
-        (KJS::DeleteDotNode::optimizeVariableAccess):
-        (KJS::DeleteDotNode::evaluate):
-        (KJS::DeleteValueNode::optimizeVariableAccess):
-        (KJS::DeleteValueNode::evaluate):
-        (KJS::VoidNode::optimizeVariableAccess):
-        (KJS::VoidNode::evaluate):
-        (KJS::TypeOfValueNode::optimizeVariableAccess):
-        (KJS::TypeOfResolveNode::optimizeVariableAccess):
-        (KJS::LocalVarTypeOfNode::evaluate):
-        (KJS::TypeOfResolveNode::evaluate):
-        (KJS::TypeOfValueNode::evaluate):
-        (KJS::PreIncResolveNode::optimizeVariableAccess):
-        (KJS::PreIncLocalVarNode::evaluate):
-        (KJS::PreIncResolveNode::evaluate):
-        (KJS::PreDecResolveNode::optimizeVariableAccess):
-        (KJS::PreDecLocalVarNode::evaluate):
-        (KJS::PreDecResolveNode::evaluate):
-        (KJS::PreIncConstNode::evaluate):
-        (KJS::PreDecConstNode::evaluate):
-        (KJS::PostIncConstNode::evaluate):
-        (KJS::PostDecConstNode::evaluate):
-        (KJS::PrefixBracketNode::optimizeVariableAccess):
-        (KJS::PreIncBracketNode::evaluate):
-        (KJS::PreDecBracketNode::evaluate):
-        (KJS::PrefixDotNode::optimizeVariableAccess):
-        (KJS::PreIncDotNode::evaluate):
-        (KJS::PreDecDotNode::evaluate):
-        (KJS::PrefixErrorNode::evaluate):
-        (KJS::UnaryPlusNode::optimizeVariableAccess):
-        (KJS::UnaryPlusNode::evaluate):
-        (KJS::UnaryPlusNode::evaluateToBoolean):
-        (KJS::UnaryPlusNode::evaluateToNumber):
-        (KJS::UnaryPlusNode::evaluateToInt32):
-        (KJS::UnaryPlusNode::evaluateToUInt32):
-        (KJS::NegateNode::optimizeVariableAccess):
-        (KJS::NegateNode::evaluate):
-        (KJS::NegateNode::evaluateToNumber):
-        (KJS::BitwiseNotNode::optimizeVariableAccess):
-        (KJS::BitwiseNotNode::inlineEvaluateToInt32):
-        (KJS::BitwiseNotNode::evaluate):
-        (KJS::BitwiseNotNode::evaluateToNumber):
-        (KJS::BitwiseNotNode::evaluateToBoolean):
-        (KJS::BitwiseNotNode::evaluateToInt32):
-        (KJS::BitwiseNotNode::evaluateToUInt32):
-        (KJS::LogicalNotNode::optimizeVariableAccess):
-        (KJS::LogicalNotNode::evaluate):
-        (KJS::LogicalNotNode::evaluateToBoolean):
-        (KJS::MultNode::optimizeVariableAccess):
-        (KJS::MultNode::inlineEvaluateToNumber):
-        (KJS::MultNode::evaluate):
-        (KJS::MultNode::evaluateToNumber):
-        (KJS::MultNode::evaluateToBoolean):
-        (KJS::MultNode::evaluateToInt32):
-        (KJS::MultNode::evaluateToUInt32):
-        (KJS::DivNode::optimizeVariableAccess):
-        (KJS::DivNode::inlineEvaluateToNumber):
-        (KJS::DivNode::evaluate):
-        (KJS::DivNode::evaluateToNumber):
-        (KJS::DivNode::evaluateToInt32):
-        (KJS::DivNode::evaluateToUInt32):
-        (KJS::ModNode::optimizeVariableAccess):
-        (KJS::ModNode::inlineEvaluateToNumber):
-        (KJS::ModNode::evaluate):
-        (KJS::ModNode::evaluateToNumber):
-        (KJS::ModNode::evaluateToBoolean):
-        (KJS::ModNode::evaluateToInt32):
-        (KJS::ModNode::evaluateToUInt32):
-        (KJS::throwOutOfMemoryErrorToNumber):
-        (KJS::addSlowCase):
-        (KJS::addSlowCaseToNumber):
-        (KJS::add):
-        (KJS::addToNumber):
-        (KJS::AddNode::optimizeVariableAccess):
-        (KJS::AddNode::evaluate):
-        (KJS::AddNode::inlineEvaluateToNumber):
-        (KJS::AddNode::evaluateToNumber):
-        (KJS::AddNode::evaluateToInt32):
-        (KJS::AddNode::evaluateToUInt32):
-        (KJS::AddNumbersNode::inlineEvaluateToNumber):
-        (KJS::AddNumbersNode::evaluate):
-        (KJS::AddNumbersNode::evaluateToNumber):
-        (KJS::AddNumbersNode::evaluateToInt32):
-        (KJS::AddNumbersNode::evaluateToUInt32):
-        (KJS::AddStringsNode::evaluate):
-        (KJS::AddStringLeftNode::evaluate):
-        (KJS::AddStringRightNode::evaluate):
-        (KJS::SubNode::optimizeVariableAccess):
-        (KJS::SubNode::inlineEvaluateToNumber):
-        (KJS::SubNode::evaluate):
-        (KJS::SubNode::evaluateToNumber):
-        (KJS::SubNode::evaluateToInt32):
-        (KJS::SubNode::evaluateToUInt32):
-        (KJS::LeftShiftNode::optimizeVariableAccess):
-        (KJS::LeftShiftNode::inlineEvaluateToInt32):
-        (KJS::LeftShiftNode::evaluate):
-        (KJS::LeftShiftNode::evaluateToNumber):
-        (KJS::LeftShiftNode::evaluateToInt32):
-        (KJS::LeftShiftNode::evaluateToUInt32):
-        (KJS::RightShiftNode::optimizeVariableAccess):
-        (KJS::RightShiftNode::inlineEvaluateToInt32):
-        (KJS::RightShiftNode::evaluate):
-        (KJS::RightShiftNode::evaluateToNumber):
-        (KJS::RightShiftNode::evaluateToInt32):
-        (KJS::RightShiftNode::evaluateToUInt32):
-        (KJS::UnsignedRightShiftNode::optimizeVariableAccess):
-        (KJS::UnsignedRightShiftNode::inlineEvaluateToUInt32):
-        (KJS::UnsignedRightShiftNode::evaluate):
-        (KJS::UnsignedRightShiftNode::evaluateToNumber):
-        (KJS::UnsignedRightShiftNode::evaluateToInt32):
-        (KJS::UnsignedRightShiftNode::evaluateToUInt32):
-        (KJS::lessThan):
-        (KJS::lessThanEq):
-        (KJS::LessNode::optimizeVariableAccess):
-        (KJS::LessNode::inlineEvaluateToBoolean):
-        (KJS::LessNode::evaluate):
-        (KJS::LessNode::evaluateToBoolean):
-        (KJS::LessNumbersNode::inlineEvaluateToBoolean):
-        (KJS::LessNumbersNode::evaluate):
-        (KJS::LessNumbersNode::evaluateToBoolean):
-        (KJS::LessStringsNode::inlineEvaluateToBoolean):
-        (KJS::LessStringsNode::evaluate):
-        (KJS::LessStringsNode::evaluateToBoolean):
-        (KJS::GreaterNode::optimizeVariableAccess):
-        (KJS::GreaterNode::inlineEvaluateToBoolean):
-        (KJS::GreaterNode::evaluate):
-        (KJS::GreaterNode::evaluateToBoolean):
-        (KJS::LessEqNode::optimizeVariableAccess):
-        (KJS::LessEqNode::inlineEvaluateToBoolean):
-        (KJS::LessEqNode::evaluate):
-        (KJS::LessEqNode::evaluateToBoolean):
-        (KJS::GreaterEqNode::optimizeVariableAccess):
-        (KJS::GreaterEqNode::inlineEvaluateToBoolean):
-        (KJS::GreaterEqNode::evaluate):
-        (KJS::GreaterEqNode::evaluateToBoolean):
-        (KJS::InstanceOfNode::optimizeVariableAccess):
-        (KJS::InstanceOfNode::evaluate):
-        (KJS::InstanceOfNode::evaluateToBoolean):
-        (KJS::InNode::optimizeVariableAccess):
-        (KJS::InNode::evaluate):
-        (KJS::InNode::evaluateToBoolean):
-        (KJS::EqualNode::optimizeVariableAccess):
-        (KJS::EqualNode::inlineEvaluateToBoolean):
-        (KJS::EqualNode::evaluate):
-        (KJS::EqualNode::evaluateToBoolean):
-        (KJS::NotEqualNode::optimizeVariableAccess):
-        (KJS::NotEqualNode::inlineEvaluateToBoolean):
-        (KJS::NotEqualNode::evaluate):
-        (KJS::NotEqualNode::evaluateToBoolean):
-        (KJS::StrictEqualNode::optimizeVariableAccess):
-        (KJS::StrictEqualNode::inlineEvaluateToBoolean):
-        (KJS::StrictEqualNode::evaluate):
-        (KJS::StrictEqualNode::evaluateToBoolean):
-        (KJS::NotStrictEqualNode::optimizeVariableAccess):
-        (KJS::NotStrictEqualNode::inlineEvaluateToBoolean):
-        (KJS::NotStrictEqualNode::evaluate):
-        (KJS::NotStrictEqualNode::evaluateToBoolean):
-        (KJS::BitAndNode::optimizeVariableAccess):
-        (KJS::BitAndNode::evaluate):
-        (KJS::BitAndNode::inlineEvaluateToInt32):
-        (KJS::BitAndNode::evaluateToNumber):
-        (KJS::BitAndNode::evaluateToBoolean):
-        (KJS::BitAndNode::evaluateToInt32):
-        (KJS::BitAndNode::evaluateToUInt32):
-        (KJS::BitXOrNode::optimizeVariableAccess):
-        (KJS::BitXOrNode::inlineEvaluateToInt32):
-        (KJS::BitXOrNode::evaluate):
-        (KJS::BitXOrNode::evaluateToNumber):
-        (KJS::BitXOrNode::evaluateToBoolean):
-        (KJS::BitXOrNode::evaluateToInt32):
-        (KJS::BitXOrNode::evaluateToUInt32):
-        (KJS::BitOrNode::optimizeVariableAccess):
-        (KJS::BitOrNode::inlineEvaluateToInt32):
-        (KJS::BitOrNode::evaluate):
-        (KJS::BitOrNode::evaluateToNumber):
-        (KJS::BitOrNode::evaluateToBoolean):
-        (KJS::BitOrNode::evaluateToInt32):
-        (KJS::BitOrNode::evaluateToUInt32):
-        (KJS::LogicalAndNode::optimizeVariableAccess):
-        (KJS::LogicalAndNode::evaluate):
-        (KJS::LogicalAndNode::evaluateToBoolean):
-        (KJS::LogicalOrNode::optimizeVariableAccess):
-        (KJS::LogicalOrNode::evaluate):
-        (KJS::LogicalOrNode::evaluateToBoolean):
-        (KJS::ConditionalNode::optimizeVariableAccess):
-        (KJS::ConditionalNode::evaluate):
-        (KJS::ConditionalNode::evaluateToBoolean):
-        (KJS::ConditionalNode::evaluateToNumber):
-        (KJS::ConditionalNode::evaluateToInt32):
-        (KJS::ConditionalNode::evaluateToUInt32):
-        (KJS::valueForReadModifyAssignment):
-        (KJS::ReadModifyResolveNode::optimizeVariableAccess):
-        (KJS::AssignResolveNode::optimizeVariableAccess):
-        (KJS::ReadModifyLocalVarNode::evaluate):
-        (KJS::AssignLocalVarNode::evaluate):
-        (KJS::ReadModifyConstNode::evaluate):
-        (KJS::AssignConstNode::evaluate):
-        (KJS::ReadModifyResolveNode::evaluate):
-        (KJS::AssignResolveNode::evaluate):
-        (KJS::AssignDotNode::optimizeVariableAccess):
-        (KJS::AssignDotNode::evaluate):
-        (KJS::ReadModifyDotNode::optimizeVariableAccess):
-        (KJS::ReadModifyDotNode::evaluate):
-        (KJS::AssignErrorNode::evaluate):
-        (KJS::AssignBracketNode::optimizeVariableAccess):
-        (KJS::AssignBracketNode::evaluate):
-        (KJS::ReadModifyBracketNode::optimizeVariableAccess):
-        (KJS::ReadModifyBracketNode::evaluate):
-        (KJS::CommaNode::optimizeVariableAccess):
-        (KJS::CommaNode::evaluate):
-        (KJS::ConstDeclNode::optimizeVariableAccess):
-        (KJS::ConstDeclNode::handleSlowCase):
-        (KJS::ConstDeclNode::evaluateSingle):
-        (KJS::ConstDeclNode::evaluate):
-        (KJS::ConstStatementNode::optimizeVariableAccess):
-        (KJS::ConstStatementNode::execute):
-        (KJS::statementListExecute):
-        (KJS::BlockNode::optimizeVariableAccess):
-        (KJS::BlockNode::execute):
-        (KJS::EmptyStatementNode::execute):
-        (KJS::ExprStatementNode::optimizeVariableAccess):
-        (KJS::ExprStatementNode::execute):
-        (KJS::VarStatementNode::optimizeVariableAccess):
-        (KJS::VarStatementNode::execute):
-        (KJS::IfNode::optimizeVariableAccess):
-        (KJS::IfNode::execute):
-        (KJS::IfElseNode::optimizeVariableAccess):
-        (KJS::IfElseNode::execute):
-        (KJS::DoWhileNode::optimizeVariableAccess):
-        (KJS::DoWhileNode::execute):
-        (KJS::WhileNode::optimizeVariableAccess):
-        (KJS::WhileNode::execute):
-        (KJS::ForNode::optimizeVariableAccess):
-        (KJS::ForNode::execute):
-        (KJS::ForInNode::optimizeVariableAccess):
-        (KJS::ForInNode::execute):
-        (KJS::ContinueNode::execute):
-        (KJS::BreakNode::execute):
-        (KJS::ReturnNode::optimizeVariableAccess):
-        (KJS::ReturnNode::execute):
-        (KJS::WithNode::optimizeVariableAccess):
-        (KJS::WithNode::execute):
-        (KJS::CaseClauseNode::optimizeVariableAccess):
-        (KJS::CaseClauseNode::evaluate):
-        (KJS::CaseClauseNode::executeStatements):
-        (KJS::ClauseListNode::optimizeVariableAccess):
-        (KJS::CaseBlockNode::optimizeVariableAccess):
-        (KJS::CaseBlockNode::executeBlock):
-        (KJS::SwitchNode::optimizeVariableAccess):
-        (KJS::SwitchNode::execute):
-        (KJS::LabelNode::optimizeVariableAccess):
-        (KJS::LabelNode::execute):
-        (KJS::ThrowNode::optimizeVariableAccess):
-        (KJS::ThrowNode::execute):
-        (KJS::TryNode::optimizeVariableAccess):
-        (KJS::TryNode::execute):
-        (KJS::ProgramNode::initializeSymbolTable):
-        (KJS::ScopeNode::optimizeVariableAccess):
-        (KJS::ProgramNode::processDeclarations):
-        (KJS::EvalNode::processDeclarations):
-        (KJS::ProgramNode::execute):
-        (KJS::EvalNode::execute):
-        (KJS::FunctionBodyNodeWithDebuggerHooks::execute):
-        (KJS::FuncDeclNode::execute):
-        (KJS::FuncExprNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::Node::):
-        (KJS::FalseNode::):
-        (KJS::TrueNode::):
-        (KJS::ArgumentsNode::):
-
-2008-04-23  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 18672: SQUIRRELFISH: codegen fails with a large number of temporaries
-        <https://bugs.webkit.org/show_bug.cgi?id=18672>
-
-        Add a SegmentedVector type, which provides a Vector<T> which maintains
-        existing memory locations during resize.  This allows dynamically sizing
-        local, temporary and label "vectors" in CodeGenerator.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addVar):
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::newTemporary):
-        (KJS::CodeGenerator::newLabel):
-        * VM/CodeGenerator.h:
-        * VM/SegmentedVector.h: Added.
-        (KJS::SegmentedVector::SegmentedVector):
-        (KJS::SegmentedVector::~SegmentedVector):
-        (KJS::SegmentedVector::last):
-        (KJS::SegmentedVector::append):
-        (KJS::SegmentedVector::removeLast):
-        (KJS::SegmentedVector::size):
-        (KJS::SegmentedVector::operator[]):
-        (KJS::SegmentedVector::resize):
-        (KJS::SegmentedVector::shrink):
-        (KJS::SegmentedVector::grow):
-
-2008-04-23  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        A little refactoring in preparation for supporting 'arguments'.
-        
-        Fixes 2 regression tests.
-
-        SunSpider reports no change.        
-
-        We now check the activation register, instead of the codeBlock, to
-        determine whether we need to tear off the activation. This is to support
-        "f.arguments", which will create an activation/arguments pair for f,
-        even though the needsFullScopeChain flag is false for f's codeBlock.
-        
-        The test fixes resulted from calling initializeCallFrame for re-entrant
-        function code, instead of initializing (not enough) parts of the call
-        frame by hand.
-
-2008-04-22  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Sam.
-        
-        - propagate the "this" value properly to local eval
-        
-        (fixes a measly one regression test)
-
-        * VM/CodeBlock.h:
-        (KJS::CodeBlock::CodeBlock):
-        (KJS::ProgramCodeBlock::ProgramCodeBlock):
-        (KJS::EvalCodeBlock::EvalCodeBlock):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-22  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Add support for function declarations in eval code.
-
-        (this fixes 12 more regression tests)
-        
-        * VM/CodeBlock.h:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * kjs/nodes.cpp:
-        (KJS::EvalNode::generateCode):
-
-2008-04-22  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Implement LabelNode.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::pushJumpContext):
-        (KJS::CodeGenerator::jumpContextForContinue):
-        (KJS::CodeGenerator::jumpContextForBreak):
-        * VM/CodeGenerator.h:
-        * kjs/nodes.cpp:
-        (KJS::DoWhileNode::emitCode):
-        (KJS::WhileNode::emitCode):
-        (KJS::ForNode::emitCode):
-        (KJS::ForInNode::emitCode):
-        (KJS::ContinueNode::emitCode):
-        (KJS::BreakNode::emitCode):
-        (KJS::SwitchNode::emitCode):
-        (KJS::LabelNode::emitCode):
-
-2008-04-22  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed crash when unwinding from exceptions inside eval.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::unwindCallFrame): Don't assume that the top of the
-        current call frame's scope chain is an activation: it can be the global
-        object, instead.
-
-2008-04-22  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-
-        * kjs/testkjs.cpp:
-        (main): Convert signals to exit codes, so that crashing tests are
-        detected as regression test failures.
-
-2008-04-22  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt and Maciej Stachowiak.
-        
-        Renamed "needsActivation" to "needsFullScopeChain" because lying will
-        make hair grow on the backs of your hands.
-
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed ScopeChainNode lifetime problems:
-        
-        (1) In "with" and "catch" scopes, we would construct a ScopeChain
-        object and then jump across its destructor, leaking the ScopeChainNode
-        we had pushed.
-
-        (2) In global and eval scopes, we would fail to initially ref
-        "scopeChain", causing us to overrelease it later. Now that we ref
-        "scopeChain" properly, we also need to deref it when the script
-        terminates.
-
-        SunSpider reports a .2% regression, but an earlier round of ScopeChain
-        refactoring was a .4% speedup, so there.
-
-2008-04-22  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Alexey.
-        
-        - use global object instead of null for "this" on unqualified calls
-        
-        This fixes 10 more JSC test regressions.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-22  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - throw proper exceptions for objects that don't implement call or construct
-        
-        This fixes 21 more JSC test regressions. It is also seemingly an
-        0.5% progression.
-
-        * VM/ExceptionHelpers.cpp:
-        (KJS::createNotAnObjectError):
-        (KJS::createNotAConstructorError):
-        (KJS::createNotAFunctionError):
-        * VM/ExceptionHelpers.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-21  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Implement emitCode for ConstDeclNode.
-
-        This fixes the crash (assertion) in js1_5/Scope/scope-001.js
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::registerForLocalConstInit):
-        * VM/CodeGenerator.h:
-        * kjs/nodes.cpp:
-        (KJS::AssignResolveNode::emitCode):
-        (KJS::ConstDeclNode::emitCodeSingle):
-        (KJS::ConstDeclNode::emitCode):
-        (KJS::ConstStatementNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-21  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Sam.
-        
-        - add some support for the split window object
-
-        This fixes many layout tests.
-        
-        * VM/Machine.cpp:
-        (KJS::resolveBaseAndFunc): Use toThisObject() to ensure we get the
-        wrapper global, if one exists, as the "this" object.
-        * kjs/function.cpp:
-        (KJS::globalFuncEval): Use toGlobalObject() to handle the wrapper
-        case properly.
-
-2008-04-21  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - restore ScopeChain::operator= to avoid crash on many layout tests
-        
-        Otherwise, FunctionImp::setScope would cause a reference
-        underflow. I implemented using the copy construct and swap idiom.
-
-        * kjs/scope_chain.h:
-        (KJS::ScopeChain::swap):
-        (KJS::ScopeChain::operator=):
-
-2008-04-21  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 18649: SQUIRRELFISH: correctly handle exceptions in eval code
-        <https://bugs.webkit.org/show_bug.cgi?id=18649>
-
-        Allocate a callframe for eval() and initialise with a null codeBlock to
-        indicate native code.  This prevents the unwinder from clobbering the
-        register stack.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Removed ScopeChain::push(ScopeChain&) because it was unused. Moved
-        ScopeChain::print to ScopeChainNode.
-        
-        ScopeChain is now nothing more than a resource-handling wrapper around
-        ScopeChainNode.
-
-2008-04-21  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 18671: SquirrelFish: continue inside switch fails
-        <https://bugs.webkit.org/show_bug.cgi?id=18671>
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::jumpContextForLabel):
-        * VM/CodeGenerator.h:
-        * kjs/nodes.cpp:
-        (KJS::ContinueNode::emitCode):
-
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Moved push(JSObject*) and pop() from ScopeChain to ScopeChainNode,
-        rearranging scope_chain.h a bit.
-
-        SunSpider reports no change.
-
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Moved bottom() from ScopeChain to ScopeChainNode, simplifying it based
-        on the knowledge that the ScopeChain is never empty.
-
-        SunSpider reports no change.
-
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Moved begin() and end() from ScopeChain to ScopeChainNode. 
-        
-        Also marked a few methods "const".
-
-        SunSpider reports no change.
-        
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Turned ScopeChain::depth into a stand-alone function, and simplified it
-        a bit. 
-        
-        I also moved ScopeChain::depth to Machine.cpp because it doesn't report
-        the true depth of the ScopeChain -- just the Machine's perspective of
-        its depth within a given call frame.
-
-        SunSpider reports no change.
-        
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Removed indirection in ScopeChain::ref / ScopeChain::deref.
-        
-        SunSpider reports no change.
-        
-        * kjs/scope_chain.h:
-        (KJS::ScopeChain::ScopeChain):
-        (KJS::ScopeChain::~ScopeChain):
-        (KJS::ScopeChain::clear):
-
-2008-04-21  Oliver Hunt  <oliver@apple.com>
-
-        Fix debug build
-
-        * kjs/nodes.cpp:
-        (KJS::ConstDeclNode::evaluateSingle):
-
-2008-04-21  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 18664: SQUIRRELFISH: correctly throw a SyntaxError when parsing of eval code fails
-        <https://bugs.webkit.org/show_bug.cgi?id=18664>
-
-        Correctly throw a SyntaxError when parsing of eval code fails.
-
-        * VM/Machine.cpp:
-        (KJS::eval):
-
-2008-04-21  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Partial fix for Bug 18649: SQUIRRELFISH: correctly handle exceptions in eval code
-
-        Make sure we correct the register state before jumping to vm_throw.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Simplified ScopeChain ref/deref.
-        
-        SunSpider reports a .4% speedup.
-        
-        * kjs/scope_chain.h:
-        (KJS::ScopeChainNode::ref): Removed this function because it was nonsense.
-        ScopeChainNodes are initialized with a refCount of 1, so the loop was
-        guaranteed to iterate exactly once.
-
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Removed support for empty ScopeChains.
-
-        SunSpider reports no change.
-
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Removed some completely unused ScopeChain member functions.
-
-        SunSpider reports no change.
-
-2008-04-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Avoid creating unnecessary ScopeChain objects, to reduce refcount churn.
-
-        SunSpider reports no change.
-
-2008-04-21  Maciej Stachowiak  <mjs@apple.com>
-
-        Rubber stamped by Alexey.
-        
-        Add some braces.x
-
-        * kjs/testkjs.cpp:
-        (runWithScripts):
-
-2008-04-21  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - only print "End:" output when -d flag is passed.
-        
-        This fixes half of our failing JSC regression tests.
-
-        * kjs/testkjs.cpp:
-        (runWithScripts):
-
-2008-04-21  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Add support for variable declarations in eval code.
-
-        * VM/CodeBlock.h:
-        (KJS::EvalCodeBlock::EvalCodeBlock):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * VM/Machine.h:
-        * kjs/function.cpp:
-        (KJS::globalFuncEval):
-        * kjs/nodes.cpp:
-        (KJS::EvalNode::generateCode):
-        * kjs/nodes.h:
-        (KJS::EvalNode::):
-
-2008-04-20  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Throw exceptions for invalid continue, break, and return statements.
-
-        Simple refactoring and extension of Cameron's AssignErrorNode, etc patch
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::pushJumpContext):
-        (KJS::CodeGenerator::popJumpContext):
-        (KJS::CodeGenerator::jumpContextForLabel):
-        * VM/CodeGenerator.h:
-        * kjs/nodes.cpp:
-        (KJS::Node::emitThrowError):
-        (KJS::ContinueNode::emitCode):
-        (KJS::BreakNode::emitCode):
-        (KJS::ReturnNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-20  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Removed Machine.cpp from AllInOneFile.cpp, and manually inlined a few
-        things that used to be inlined automatically.
-        
-        1.9% speedup on SunSpider.
-        
-        My hope is that we'll face fewer surprises in Machine.cpp codegen, now
-        that GCC is making fewer decisions. The speedup seems to confirm that.
-
-2008-04-20  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18642: Iterator context may get placed into the return register, leading to much badness
-        <https://bugs.webkit.org/show_bug.cgi?id=18642>
-
-        To prevent incorrectly reusing what will become the result register for
-        eval and global code execution, we need to request and ref the destination
-        in advance of codegen.  Unfortunately this may lead to unnecessary copying,
-        although in future we can probably limit this.  Curiously SunSpider shows
-        a progression in a number of tests, although it comes out as a wash overall.
-
-        * kjs/nodes.cpp:
-        (KJS::EvalNode::emitCode):
-        (KJS::ProgramNode::emitCode):
-
-2008-04-20  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Add support for AssignErrorNode, PrefixErrorNode, and PostfixErrorNode.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitCreateError):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::PostfixErrorNode::emitCode):
-        (KJS::PrefixErrorNode::emitCode):
-        (KJS::AssignErrorNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-20  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff and Mark.
-
-        Provide line number information in exceptions
-
-        Simple patch, adds line number information metadata to CodeBlock
-        and a simple method to get the line number responsible for a given
-        Instruction*.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::lineNumberForVPC):
-        * VM/CodeBlock.h:
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::emitNode):
-        * VM/Machine.cpp:
-        (KJS::Machine::throwException):
-
-2008-04-20  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Provide "sourceURL" in exceptions
-
-        * VM/CodeBlock.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::throwException):
-        * kjs/nodes.cpp:
-        (KJS::EvalNode::generateCode):
-        (KJS::ProgramNode::generateCode):
-
-2008-04-19  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Don't call emitCode directly on subnodes, instead use CodeGenerator::emitNode
-
-        This patch just a preparation for tracking line numbers.
-
-        * kjs/nodes.cpp:
-        (KJS::ObjectLiteralNode::emitCode):
-        (KJS::PropertyListNode::emitCode):
-        (KJS::ArgumentListNode::emitCode):
-        (KJS::TryNode::emitCode):
-
-2008-04-19  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18619: Support continue, break, and return in try .. finally blocks
-        <https://bugs.webkit.org/show_bug.cgi?id=18619>
-
-        This patch replaces the current partial finally support (which uses code
-        duplication to achieve what it does) with a subroutine based approach.
-        This has a number of advantages over code duplication:
-          * Reduced code size
-          * Simplified exception handling as the finaliser code only exists in 
-            one place, so no "magic" is needed to get the correct handler for a 
-            finaliser.
-          * When we support instruction to line number mapping we won't need to
-            worry about the dramatic code movement caused by duplication
-
-        On the downside it is necessary to add two new opcodes, op_jsr and op_sret
-        to enter and exit the finaliser subroutines, happily SunSpider reports
-        a performance progression (gcc amazes me) and ubench reports a wash.
-
-        While jsr and sret provide a mechanism that allows us to enter and exit
-        any arbitrary finaliser we need to, it was still necessary to increase
-        the amount of information tracked when entering and exiting both finaliser
-        scopes and dynamic scopes ("with").  This means "scopeDepth" is now
-        the combination of "finaliserDepth" and "dynamicScopeDepth".  We also
-        now use a scopeContextStack to ensure that we pop scopes and execute
-        finalisers in the correct order.  This increases the cost of "with" nodes
-        during codegen, but it should not be significant enough to effect real
-        world performance and greatly simplifies codegen for return, break and
-        continue when interacting with finalisers.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-          Pretty printing of jsr/sret opcodes
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::emitPushScope):
-        (KJS::CodeGenerator::emitPopScope):
-          Dynamic scopes need to be tracked on the scopeContextStack now
-
-        (KJS::CodeGenerator::pushFinallyContext):
-        (KJS::CodeGenerator::popFinallyContext):
-          Handle entry and exit from code regions with finalisers.  This is
-          needed solely to support return, continue and break inside finaliser
-          regions.
-
-        (KJS::CodeGenerator::emitComplexJumpScopes):
-          Helper function for emitJumpScopes to handle the complex codegen
-          needed to handle return, continue and break inside a finaliser region
-
-        (KJS::CodeGenerator::emitJumpScopes):
-          Updated to be aware of finalisers, if a cross-scope jump occurs inside
-          a finaliser we hand off codegen to emitComplexJumpScopes, otherwise
-          we can handle the normal (trivial) case with a single instruction.
-
-        (KJS::CodeGenerator::emitJumpSubroutine):
-        (KJS::CodeGenerator::emitSubroutineReturn):
-          Trivial opcode emitter functions.
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::scopeDepth):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-          Implement op_jsr and op_sret.
-
-        * VM/Opcode.h:
-          Ad op_jsr and op_sret
-
-        * kjs/nodes.cpp:
-        (KJS::TryNode::emitCode):
-          Fix codegen for new finaliser model.
-
-2008-04-17  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Oliver Hunt.
-
-        Remove unnecessary files from testkjs, testapi and minidom targets.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-04-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed ASSERT seen during run-sunspider of a debug build.
-
-        * VM/CodeGenerator.h: Made the default codegen buffers bigger. SunSpider
-        runs all tests in one global environment, so you end up with more than
-        128 locals. This is just a stop-gap until we code up a real
-        solution to arbitrary symbol and label limits.
-
-2008-04-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed a bug in exception unwinding, where we wouldn't deref the scope
-        chain in global scope, so we would leak ScopeChainNodes when exceptions
-        were thrown inside "with" and "catch" scopes.
-        
-        Also did some cleanup of the unwinding code along the way.
-        
-        Scope chain reference counting is still wrong in a few ways. I thought
-        I would fix this portion of it first.
-        
-        run-sunspider shows no change.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::throwException):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-
-2008-04-17  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Add more exception checking to toNumber conversions
-
-        This corrects op_pre_dec, op_negate, op_mod and op_sub.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-17  Geoffrey Garen  <ggaren@apple.com> and Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver Hunt.
-        
-        Behold: eval.
-        
-        Introduced a new opcode: op_call_eval. In the normal case, it performs
-        an eval. In the case where eval has been overridden in some way, it
-        performs a function call.
-
-        * VM/CodeGenerator.h: Added a feature so the code generator knows not
-        to optimized locals in eval code.
-        
-2008-04-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Added some ASSERTs to document codegen failures in
-        run-javascriptcore-tests.
-        
-        For all tests, program-level codegen now either succeeds, or fails with
-        an ASSERT.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addVar):
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::newTemporary):
-        (KJS::CodeGenerator::newLabel):
-
-2008-04-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed another case of a dst register being an unreferenced temporary
-        (caused an ASSERT when running the full sunspider suite).
-
-        * kjs/nodes.cpp:
-        (KJS::CaseBlockNode::emitCodeForBlock):
-
-2008-04-16  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - add documentation (and meaningful parameter names) for arithmetic and bitwise binary ops
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitMul):
-        (KJS::CodeGenerator::emitDiv):
-        (KJS::CodeGenerator::emitMod):
-        (KJS::CodeGenerator::emitSub):
-        (KJS::CodeGenerator::emitLeftShift):
-        (KJS::CodeGenerator::emitRightShift):
-        (KJS::CodeGenerator::emitUnsignedRightShift):
-        (KJS::CodeGenerator::emitBitAnd):
-        (KJS::CodeGenerator::emitBitXOr):
-        (KJS::CodeGenerator::emitBitOr):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::MultNode::emitCode):
-        (KJS::DivNode::emitCode):
-        (KJS::ModNode::emitCode):
-        (KJS::SubNode::emitCode):
-        (KJS::LeftShiftNode::emitCode):
-        (KJS::RightShiftNode::emitCode):
-        (KJS::UnsignedRightShiftNode::emitCode):
-        (KJS::BitAndNode::emitCode):
-        (KJS::BitXOrNode::emitCode):
-        (KJS::BitOrNode::emitCode):
-        (KJS::emitReadModifyAssignment):
-        (KJS::ReadModifyResolveNode::emitCode):
-
-2008-04-16  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Exception checks for toNumber in op_pre_inc
-
-        This is somewhat more convoluted than the simple hadException checks
-        we currently use.  Instead we use special toNumber conversions that
-        select between the exception and ordinary vPC.  This allows us to 
-        remove any branches in the common case (incrementing a number).
-
-        * API/JSCallbackObject.h:
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::toNumber):
-        * ChangeLog:
-        * JavaScriptCore.exp:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * VM/JSPropertyNameIterator.cpp:
-        (KJS::JSPropertyNameIterator::toNumber):
-        * VM/JSPropertyNameIterator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        * kjs/ExecState.h:
-        * kjs/JSNotAnObject.cpp:
-        (KJS::JSNotAnObject::toNumber):
-        * kjs/JSNotAnObject.h:
-        * kjs/internal.cpp:
-        (KJS::StringImp::toNumber):
-        (KJS::NumberImp::toNumber):
-        (KJS::GetterSetterImp::toNumber):
-        * kjs/internal.h:
-        * kjs/object.cpp:
-        (KJS::JSObject::toNumber):
-        * kjs/object.h:
-        * kjs/value.h:
-        (KJS::JSValue::toNumber):
-
-2008-04-16  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - ensure that activations are kept in a register to protect them from GC
-        
-        Also renamed OptionalCalleeScopeChain constant to OptionalCalleeActivation, since
-        that is what is now kept there, and there is no more need to keep the scope chain in
-        the register file.
-
-        * VM/Machine.cpp:
-        (KJS::initializeCallFrame):
-        (KJS::scopeChainForCall):
-        * VM/Machine.h:
-        (KJS::Machine::):
-
-2008-04-16  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Made "this" work in program code / global scope.
-        
-        The machine can initialize "this" prior to execution because it knows
-        that, for program code, "this" is always stored in lr1. 
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        * VM/Machine.h:
-        (KJS::Machine::):
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate):
-
-2008-04-16  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed a codegen bug when returning from inside a dynamic scope (a with
-        or catch block): we need to pop any dynamic scope(s) that have been
-        added so op_ret can find the activation object at the top of the scope
-        chain.
-
-        * kjs/nodes.cpp:
-        (KJS::ReturnNode::emitCode): If we're returning from inside a dynamic
-        scope, emit a jmp_scopes to take care of popping any dynamic scope(s)
-        and then branching to the return instruction.
-
-2008-04-16  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - document the add and get_prop_id opcodes
-        
-        In addition to adding documentation in comments, I changed
-        references to register IDs or indices relating to these opcodes to
-        have meaningful names instead of r0 r1 r2.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitAdd):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/nodes.cpp:
-        (KJS::DotAccessorNode::emitCode):
-        (KJS::FunctionCallDotNode::emitCode):
-        (KJS::PostIncDotNode::emitCode):
-        (KJS::PostDecDotNode::emitCode):
-        (KJS::PreIncDotNode::emitCode):
-        (KJS::PreDecDotNode::emitCode):
-        (KJS::AddNode::emitCode):
-        (KJS::ReadModifyDotNode::emitCode):
-
-2008-04-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt and Maciej Stachowiak.
-        
-        Fixed a codegen bug in with and switch, and added an ASSERT to
-        make sure it doesn't happen again.
-        
-        emitCode() assumes that dst, if non-zero, is either referenced or
-        non-temporary (i.e., it assumes that newTemporary() will return a
-        register not equal to dst). Certain callers to emitCode() weren't
-        guaranteeing that to be so, so temporary register values were being
-        overwritten.
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::emitNode): ASSERT that dst is referenced or non-temporary.
-
-        * kjs/nodes.cpp:
-        (KJS::CommaNode::emitCode): Reference the dst we pass.
-
-        (KJS::WithNode::emitCode): No need to pass an explicit dst register.
-        
-        (KJS::CaseBlockNode::emitCodeForBlock): No need to pass an explicit dst register.
-        (KJS::SwitchNode::emitCode): No need to pass an explicit dst register.
-
-        * kjs/nodes.h: Made dst the last parameter to emitCodeForBlock, to match
-        emitCode.
-
-2008-04-15  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18526: Throw exceptions when resolve fails for op_resolve_base_and_func.
-        <https://bugs.webkit.org/show_bug.cgi?id=18526>
-
-        Very simple fix, sunspider shows a 0.7% progression, ubench shows a 0.4% regression.
-
-        * VM/Machine.cpp:
-        (KJS::resolveBaseAndFunc):
-        (KJS::Machine::privateExecute):
-
-2008-04-15  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fix incorrect result on 3d-raytrace test
-        
-        Oliver found and tracked down this bug, I just typed in the fix.
-
-        * VM/Machine.cpp:
-        (KJS::slideRegisterWindowForCall): When setting omitted parameters to undefined,
-        account for the space for local variables.
-
-2008-04-15  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fix codegen handling of dst registers
-        
-        1.006x speedup (not sure why).
-        
-        Most emitCode functions take an optional "dst" parameter that says
-        where the output of the instruction should be written. I made some
-        functions for convenient handling of the dst register:
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::tempDestination): Takes the dst register. Returns it if
-        it is not null and is a temporary, otherwise allocates a new temporary. This is
-        intended for cases where an intermediate value might be written into the dst
-
-        (KJS::CodeGenerator::finalDestination): Takes the dst register and an optional
-        register that was used as a temp destination. Picks the right thing for the final
-        output. Intended to be used as the output register for the instruction that generates
-        the final value of a particular node.
-        
-        (KJS::CodeGenerator::moveToDestinationIfNeeded): Takes dst and a
-        RegisterID; moves from the register to dst if dst is defined and
-        different from the register. This is intended for cases where the
-        result of a node is already in a specific register (likely a
-        local), and so no code needs to be generated unless a specific
-        destination has been requested, in which case a move is needed.
-        
-        I also applied these methods throughout emitCode functions. In
-        some cases this was just cleanup, in other cases I fixed actual
-        codegen bugs. Below I have given specific comments for the cases
-        where I believe I fixed a codegen bug, or improved quality of codegen.
-        
-        * kjs/nodes.cpp:
-        (KJS::NullNode::emitCode):
-        (KJS::FalseNode::emitCode):
-        (KJS::TrueNode::emitCode):
-        (KJS::NumberNode::emitCode):
-        (KJS::StringNode::emitCode):
-        (KJS::RegExpNode::emitCode):
-        (KJS::ThisNode::emitCode): Now avoids emitting a mov when dst is
-        the same as the this register (the unlikely case of "this = this");
-        (KJS::ResolveNode::emitCode): Now avoids emitting a mov when dst
-        is the same as the local regiester, in the local var case (the
-        unlikely case of "x = x");
-        (KJS::ArrayNode::emitCode): Fixed a codegen bug where array
-        literal element expressions may have observed an intermediate
-        value of constructing the array.
-        (KJS::ObjectLiteralNode::emitCode): 
-        (KJS::PropertyListNode::emitCode): Fixed a codegen bug where object literal
-        property definition expressions may have obesrved an intermediate value of
-        constructing the object.
-        (KJS::BracketAccessorNode::emitCode):
-        (KJS::DotAccessorNode::emitCode):
-        (KJS::NewExprNode::emitCode):
-        (KJS::FunctionCallValueNode::emitCode):
-        (KJS::FunctionCallBracketNode::emitCode):
-        (KJS::FunctionCallDotNode::emitCode):
-        (KJS::PostIncResolveNode::emitCode):
-        (KJS::PostDecResolveNode::emitCode):
-        (KJS::PostIncBracketNode::emitCode):
-        (KJS::PostDecBracketNode::emitCode):
-        (KJS::PostIncDotNode::emitCode):
-        (KJS::PostDecDotNode::emitCode):
-        (KJS::DeleteResolveNode::emitCode):
-        (KJS::DeleteBracketNode::emitCode):
-        (KJS::DeleteDotNode::emitCode):
-        (KJS::DeleteValueNode::emitCode):
-        (KJS::VoidNode::emitCode):
-        (KJS::TypeOfResolveNode::emitCode):
-        (KJS::TypeOfValueNode::emitCode):
-        (KJS::PreIncResolveNode::emitCode): Fixed a codegen bug where the final
-        value would not be output to the dst register in the local var case.
-        (KJS::PreDecResolveNode::emitCode): Fixed a codegen bug where the final
-        value would not be output to the dst register in the local var case.
-        (KJS::PreIncBracketNode::emitCode):
-        (KJS::PreDecBracketNode::emitCode):
-        (KJS::PreIncDotNode::emitCode):
-        (KJS::PreDecDotNode::emitCode):
-        (KJS::UnaryPlusNode::emitCode):
-        (KJS::NegateNode::emitCode):
-        (KJS::BitwiseNotNode::emitCode):
-        (KJS::LogicalNotNode::emitCode):
-        (KJS::MultNode::emitCode):
-        (KJS::DivNode::emitCode):
-        (KJS::ModNode::emitCode):
-        (KJS::AddNode::emitCode):
-        (KJS::SubNode::emitCode):
-        (KJS::LeftShiftNode::emitCode):
-        (KJS::RightShiftNode::emitCode):
-        (KJS::UnsignedRightShiftNode::emitCode):
-        (KJS::LessNode::emitCode):
-        (KJS::GreaterNode::emitCode):
-        (KJS::LessEqNode::emitCode):
-        (KJS::GreaterEqNode::emitCode):
-        (KJS::InstanceOfNode::emitCode):
-        (KJS::InNode::emitCode):
-        (KJS::EqualNode::emitCode):
-        (KJS::NotEqualNode::emitCode):
-        (KJS::StrictEqualNode::emitCode):
-        (KJS::NotStrictEqualNode::emitCode):
-        (KJS::BitAndNode::emitCode):
-        (KJS::BitXOrNode::emitCode):
-        (KJS::BitOrNode::emitCode):
-        (KJS::LogicalAndNode::emitCode):
-        (KJS::LogicalOrNode::emitCode):
-        (KJS::ConditionalNode::emitCode):
-        (KJS::emitReadModifyAssignment): Allow an out argument separate from the operands,
-        needed for fixes below.
-        (KJS::ReadModifyResolveNode::emitCode): Fixed a codegen bug where the right side of
-        the expression may observe an intermediate value.
-        (KJS::AssignResolveNode::emitCode): Fixed a codegen bug where the right side of the
-        expression may observe an intermediate value.
-        (KJS::ReadModifyDotNode::emitCode): Fixed a codegen bug where the right side of the
-        expression may observe an intermediate value.
-        (KJS::ReadModifyBracketNode::emitCode): Fixed a codegen bug where the right side of the
-        expression may observe an intermediate value.
-        (KJS::CommaNode::emitCode): Avoid writing temporary value to dst register.
-        (KJS::ReturnNode::emitCode): Void return should return undefined, not null.
-        (KJS::FuncExprNode::emitCode):
-
-2008-04-15  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix huge performance regression (from trunk) in string-unpack-code
-        
-        This restores string-unpack-code performance to parity with
-        trunk (2.27x speedup relative to previous SquirrelFish)
-        
-        * VM/Machine.cpp:
-        (KJS::Machine::execute): Shrink register file after call to avoid
-        growing repeatedly.
-
-2008-04-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Fixed dumpCallFrame to match our new convention of passing around a
-        ScopeChainNode* instead of a ScopeChain*.
-
-        * JavaScriptCore.exp:
-        * VM/Machine.cpp:
-        (KJS::Machine::dumpCallFrame):
-        * VM/Machine.h:
-
-2008-04-15  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18436: Need to throw exception on read/modify/write or similar resolve for nonexistent property
-        <https://bugs.webkit.org/show_bug.cgi?id=18436>
-
-        Add op_resolve_base_and_property for read/modify/write operations,
-        this adds a "superinstruction" to resolve the base and value of a
-        property simultaneously.  Just using resolveBase and resolve results 
-        in an 5% regression in ubench, 30% in loop-empty-resolve (which is 
-        expected).  1.3% progression in sunspider, 2.1% in ubench, with a 
-        21% gain in loop-empty-resolve.  The only outlier is function-missing-args
-        which gets a 3% regression that I could never resolve.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitResolveBaseAndProperty):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::resolveBaseAndProperty):
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::PostIncResolveNode::emitCode):
-        (KJS::PostDecResolveNode::emitCode):
-        (KJS::PreIncResolveNode::emitCode):
-        (KJS::PreDecResolveNode::emitCode):
-        (KJS::ReadModifyResolveNode::emitCode):
-
-2008-04-15  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fixed "SquirrelFish crashes due to bad scope chain on some SunSpider tests"
-        https://bugs.webkit.org/show_bug.cgi?id=18508
-
-        3d-raytrace and string-unpack-code now run.
-        
-        The basic approach is to pass around ScopeChainNode* instead of
-        ScopeChain*, which in addition to not becoming suddenly an invalid
-        pointer also saves an indirection.
-        
-        This is an 0.4% speedup on SunSpider --squirrelfish (1.8% on --ubench)
-        
-        * VM/Machine.cpp:
-        (KJS::resolve):
-        (KJS::resolveBase):
-        (KJS::resolveBaseAndFunc):
-        (KJS::initializeCallFrame):
-        (KJS::scopeChainForCall):
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::throwException):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        * VM/Register.h:
-        (KJS::Register::):
-        * kjs/nodes.cpp:
-        (KJS::EvalNode::generateCode):
-        (KJS::FunctionBodyNode::generateCode):
-        (KJS::ProgramNode::generateCode):
-        (KJS::ProgramNode::processDeclarations):
-        (KJS::EvalNode::processDeclarations):
-        (KJS::FuncDeclNode::makeFunction):
-        (KJS::FuncExprNode::makeFunction):
-        * kjs/nodes.h:
-        (KJS::ProgramNode::):
-        (KJS::EvalNode::):
-        (KJS::FunctionBodyNode::):
-        * kjs/object.h:
-        * kjs/scope_chain.h:
-        (KJS::ScopeChainNode::ScopeChainNode):
-        (KJS::ScopeChainNode::deref):
-        (KJS::ScopeChainIterator::ScopeChainIterator):
-        (KJS::ScopeChainIterator::operator*):
-        (KJS::ScopeChainIterator::operator->):
-        (KJS::ScopeChain::ScopeChain):
-        (KJS::ScopeChain::node):
-        (KJS::ScopeChain::deref):
-        (KJS::ScopeChain::ref):
-        (KJS::ScopeChainNode::ref):
-        (KJS::ScopeChainNode::release):
-        (KJS::ScopeChainNode::begin):
-        (KJS::ScopeChainNode::end):
-
-2008-04-14  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed crash when accessing registers in a torn-off activation object.
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::copyRegisters): Update our registerOffset after
-        copying our registers, since our offset should now be relative to
-        our private register array, not the shared register file.
-
-2008-04-14  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fix a codegen flaw that makes some tests run way too fast or way too slow
-        
-        The basic problem was that FunctionCallResolveNode results in
-        codegen which can incorrectly write an intermediate value into the
-        dst register even when that is a local. I added convenience
-        functions to CodeGenerator for getting this right, but for now I
-        only fixed FunctionCallResolve.
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::tempDestination):
-        (KJS::CodeGenerator::):
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallResolveNode::emitCode):
-
-2008-04-14  Gabor Loki  <loki@inf.u-szeged.hu>
-
-        Reviewed and slightly tweaked by Geoffrey Garen.
-
-        Bug 18489: Squirrelfish doesn't build on linux
-        <https://bugs.webkit.org/show_bug.cgi?id=18489>
-
-        * JavaScriptCore.pri: Add VM into include path and its files into
-        source set
-        * VM/JSPropertyNameIterator.cpp: Fix include name
-        * VM/Machine.cpp: Add UNLIKELY macro for GCC
-        * VM/Machine.h: Add missing includes
-        * VM/RegisterFile.cpp: Add missing include
-        * kjs/testkjs.pro: Add VM into include path
-
-2008-04-14  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Restored OwnPtr in some places where I had removed it previously. We
-        can have an OwnPtr to an undefined class in a header as long as the
-        class's destructor isn't in the header.
-        
-2008-04-14  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Fixed access to "this" inside dynamic scopes.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::registerForLocal): Always return a register for
-        "this", even if we're not optimizing access to other locals. Because
-        "this" is a keyword, it's always in a register and always accessible.
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::shouldOptimizeLocals): Factored out a function
-        for determining whether we should optimize access to locals, since
-        eval will need to make this test a little more complicated.
-
-2008-04-14  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Adam.
-        
-        - fix crash when running SunSpider full harness
-        
-        When growing the register file's buffer to make space for new globals,
-        make sure to copy accounting for the fact that the new space is logically
-        at the beginning of the buffer in this case, instead of at the end as when
-        growing for a new call frame.
-
-        * VM/RegisterFile.cpp:
-        (KJS::RegisterFile::newBuffer):
-        (KJS::RegisterFile::growBuffer):
-        (KJS::RegisterFile::addGlobalSlots):
-        * VM/RegisterFile.h:
-
-2008-04-11  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Mark constant pools for global and eval code (collectively known as
-        "program code"). (Constant pools for function code are already marked by
-        their functions.)
-        
-        The global object is responsible for marking program code constant
-        pools. Code blocks add themselves to the mark set at creation time, and
-        remove themselves from the mark set at destruction time.
-        
-        sunspider --squirrelfish reports a 1% speedup, perhaps because
-        generateCode() is now non-virtual.
-
-        * kjs/nodes.cpp: I had to use manual init and delete in this file
-        because putting an OwnPtr into the header would have created a circular
-        header dependency.
-
-2008-04-10  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Bug 18231: Improve support for function call nodes in SquirrelFish
-        <https://bugs.webkit.org/show_bug.cgi?id=18231>
-
-        Use correct value of 'this' for function calls.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitResolveBaseAndFunc):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::resolveBaseAndFunc):
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallResolveNode::emitCode):
-
-2008-04-10  Geoffrey Garen  <ggaren@apple.com>
-
-        This time for sure.
-
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate):
-
-2008-04-10  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Fixed Interpreter::execute to honor the new model for returning non-NULL
-        values when an exception is thrown.
-
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate):
-
-2008-04-10  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Fix SquirrelFish interpreter to pass internal exceptions back to 
-        native code correctly.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-10  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Replace the use of getCallData in op_construct with the new
-        getConstructData function that replaces implementsConstruct.
-
-        * API/JSCallbackConstructor.cpp:
-        (KJS::JSCallbackConstructor::getConstructData):
-        * API/JSCallbackConstructor.h:
-        * API/JSCallbackObject.h:
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::getConstructData):
-        (KJS::::construct):
-        * API/JSObjectRef.cpp:
-        (JSObjectIsConstructor):
-        * JavaScriptCore.exp:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/CallData.h:
-        * kjs/ConstructData.h: Copied from JavaScriptCore/kjs/CallData.h.
-        * kjs/array_object.cpp:
-        (KJS::ArrayObjectImp::getConstructData):
-        * kjs/array_object.h:
-        * kjs/bool_object.cpp:
-        (KJS::BooleanObjectImp::getConstructData):
-        * kjs/bool_object.h:
-        * kjs/date_object.cpp:
-        (KJS::DateObjectImp::getConstructData):
-        * kjs/date_object.h:
-        * kjs/error_object.cpp:
-        (KJS::ErrorObjectImp::getConstructData):
-        (KJS::NativeErrorImp::getConstructData):
-        * kjs/error_object.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::getCallData):
-        (KJS::FunctionImp::getConstructData):
-        (KJS::FunctionImp::construct):
-        * kjs/function.h:
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::getConstructData):
-        * kjs/function_object.h:
-        * kjs/nodes.cpp:
-        (KJS::NewExprNode::inlineEvaluate):
-        * kjs/number_object.cpp:
-        (KJS::NumberObjectImp::getConstructData):
-        * kjs/number_object.h:
-        * kjs/object.cpp:
-        * kjs/object.h:
-        * kjs/object_object.cpp:
-        (KJS::ObjectObjectImp::getConstructData):
-        * kjs/object_object.h:
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpObjectImp::getConstructData):
-        * kjs/regexp_object.h:
-        * kjs/string_object.cpp:
-        (KJS::StringObjectImp::getConstructData):
-        * kjs/string_object.h:
-        * kjs/value.cpp:
-        (KJS::JSCell::getConstructData):
-        * kjs/value.h:
-        (KJS::JSValue::getConstructData):
-
-2008-04-10  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 18420: SquirrelFish: need to throw Reference and Type errors 
-        when attempting invalid operations on JSValues
-
-        Add validation and exception checks to SquirrelFish so that the
-        correct exceptions are thrown for undefined variables, type errors
-        and toObject failure.  Also handle exceptions thrown by native
-        function calls.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * VM/ExceptionHelpers.cpp: Added.
-        (KJS::substitute):
-        (KJS::createError):
-        (KJS::createUndefinedVariableError):
-        * VM/ExceptionHelpers.h: Added.
-          Helper functions
-        * VM/Machine.cpp:
-        (KJS::resolve):
-           Modified to signal failure
-        (KJS::isNotObject):
-           Wrapper for JSValue::isObject and exception creation (these need
-           to be merged, lest GCC go off the deep end)
-        (KJS::Machine::privateExecute):
-           Adding the many exception and validity checks.
-
-        * kjs/JSNotAnObject.cpp: Added.
-          Stub object used to reduce the need for multiple exception checks
-          when toObject fails.
-        (KJS::JSNotAnObject::toPrimitive):
-        (KJS::JSNotAnObject::getPrimitiveNumber):
-        (KJS::JSNotAnObject::toBoolean):
-        (KJS::JSNotAnObject::toNumber):
-        (KJS::JSNotAnObject::toString):
-        (KJS::JSNotAnObject::toObject):
-        (KJS::JSNotAnObject::mark):
-        (KJS::JSNotAnObject::getOwnPropertySlot):
-        (KJS::JSNotAnObject::put):
-        (KJS::JSNotAnObject::deleteProperty):
-        (KJS::JSNotAnObject::defaultValue):
-        (KJS::JSNotAnObject::construct):
-        (KJS::JSNotAnObject::callAsFunction):
-        (KJS::JSNotAnObject::getPropertyNames):
-        * kjs/JSNotAnObject.h: Added.
-        (KJS::JSNotAnObject::JSNotAnObject):
-        * kjs/JSImmediate.cpp:
-        (KJS::JSImmediate::toObject):
-          modified to create an JSNotAnObject rather than throwing an exception
-          directly.
-
-2008-04-10  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Pass a function body node its function's scope chain, rather than the
-        current execution context's scope chain, when compiling it.
-        
-        This doesn't matter yet, but it will once we start using the scope
-        chain during compilation.
-
-        sunspider --squirrelfish notes a tiny speedup.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-10  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fix two bugs when throwing exceptions from re-entrant JS calls:
-        
-        (1) Don't shrink the register file to 0, since our caller may still
-        be using it.
-        
-        (2) In case of exception, return jsNull() instead of 0 because,
-        surprisingly, some JavaScriptCore clients rely on a function's return
-        value being safe to operate on even if the function threw an exception.
-        
-        Also:
-        
-        - Changed FunctionImp::callAsFunction to honor the new semantics of
-        exceptions not returning 0.
-        
-        - Renamed "handlerPC" to "handlerVPC" to match other uses of "VPC".
-        
-        - Renamed "exceptionData" to "exceptionValue", because "data" seemed to
-        imply something more than just a JSValue.
-        
-        - Merged prepareException into throwException, since throwException was
-        its only caller, and it seemed weird that throwException didn't take
-        an exception as an argument.
-
-        sunspider --squirrelfish does not seem to complain on my machine, but it
-        complains a little (.6%) on Oliver's.
-
-2008-04-10  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed op_construct for CallTypeNative to reacquire "r" before setting
-        its return value, since registerBase can theoretically change during the
-        execution of arbitrary code. (Not sure if any native constructors
-        actually make this possible.)
-
-        sunspider --squirrelfish does not seem to complain.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-10  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt and Sam Weinig.
-        
-        Re-entrant execution of function code (global code -> built-in function
-        -> JS function):
-        
-        Miraculously, sunspider --squirrelfish does not seem to complain.
-
-        A re-entrant function call is the same as a normal function call with
-        one exception: the re-entrant call leaves everything except for
-        CallerCodeBlock in the call frame header uninitialized, since the call
-        doesn't need to return to JS code. (It sets CallerCodeBlock to 0, to
-        indicate that the call shouldn't return to JS code.)
-        
-        Also fixed a few issues along the way:
-        
-        - Fixed two bugs in the read-write List implementation that caused
-        m_size and m_buffer to go stale.
-        
-        - Changed native call code to update "r" *before* setting the return
-        value, since the call may in turn call JS code, which changes the value
-        of "r".
-        
-        - Migrated initialization of "r" outside of Machine::privateExecute,
-        because global code and function code initialize "r" differently.
-        
-        - Migrated a codegen warning from Machine::privateExecute to the wiki.
-        
-        - Removed unnecessary "r" parameter from slideRegisterWindowForCall
-
-        * VM/Machine.cpp:
-        (KJS::slideRegisterWindowForCall):
-        (KJS::scopeChainForCall):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-        * kjs/list.cpp:
-        (KJS::List::getSlice):
-        * kjs/list.h:
-        (KJS::List::clear):
-
-2008-04-10  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fix problem with code generation for return with no argument
-        
-        3d-cube now runs
-
-        * kjs/nodes.cpp:
-        (KJS::ReturnNode::emitCode):
-
-2008-04-10  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - Implement support for JS constructors
-        
-        access-binary-trees and access-nbody now run.
-        
-        Inexplicably a 1% speedup.
-
-        * VM/Machine.cpp:
-        (KJS::initializeCallFrame):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        (KJS::Machine::):
-
-2008-04-10  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-
-        - More code cleanup in preparation for JS constructors
-
-        Factor the remaining interesting parts of JS function calls into
-        slideRegisterWindowForCall and scopeChainForCall.
-        
-        * VM/Machine.cpp:
-        (KJS::slideRegisterWindowForCall):
-        (KJS::scopeChainForCall):
-        (KJS::Machine::privateExecute):
-
-2008-04-10  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - Code cleanup in preparation for JS constructors
-
-        - Renamed returnInfo to callFrame. 
-        - Made an enum which defines what goes where in the call frame.
-        - Factored out initializeCallFrame function from op_call
-        
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitCall):
-        (KJS::CodeGenerator::emitConstruct):
-        * VM/Machine.cpp:
-        (KJS::Machine::dumpRegisters):
-        (KJS::initializeCallFrame):
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        (KJS::Machine::):
-
-2008-04-10  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed two bugs in register allocation for function calls:
-        
-        (1) op_call used to allocate codeBlock->numVars too many registers for
-        each call frame, due to duplicated math. Fixing this revealed...
-        
-        (2) By unconditionally calling resize(), op_call used to truncate the
-        register file when calling a function whose registers fit wholly within
-        the register file already allocated by its caller.
-        
-        sunspider --squirrelfish reports no regression.
-        
-        I also threw in a little extra formatting to dumpCallFrame, because it
-        helped me debug these issues.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::dumpRegisters):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/RegisterFile.h:
-        (KJS::RegisterFile::shrink):
-        (KJS::RegisterFile::grow):
-        * VM/RegisterFileStack.cpp:
-        (KJS::RegisterFileStack::popRegisterFile):
-
-2008-04-09  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Next step toward re-entrant execution of function code (global code ->
-        built-in function -> JS function):
-        
-        Made op_ret return from Machine::privateExecute if its calling codeBlock
-        is NULL.
-        
-        I'm checking this in by itself to demonstrate that a more clever
-        mechanism is not necessary for performance.
-        
-        sunspider --squirrelfish reports no regression.
-
-        * ChangeLog:
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-
-2008-04-09  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Next step toward re-entrant execution of function code (global code ->
-        built-in function -> JS function):
-        
-        Made Machine::execute return a value.
-        
-        Sketched out some code for Machine::execute for functions -- still
-        doesn't work yet, though.
-
-        sunspider --squirrelfish reports no regression.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate):
-        * kjs/testkjs.cpp:
-        (runWithScripts):
-
-2008-04-09  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        First step toward re-entrant execution of function code (global code ->
-        built-in function -> JS function):
-        
-        Tiny bit of refactoring in the Machine class.
-
-        sunspider --squirrelfish reports no regression.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::dumpRegisters):
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::execute):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        (KJS::Machine::isGlobalCallFrame):
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate):
-
-2008-04-08  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Support for re-entrant execution of global code (global code -> built-in
-        function -> global code).
-        
-        Keep a stack of register files instead of just one. Globals propogate
-        between register files as the register files enter and exit the stack.
-        
-        An activation still uses its own register file's base as its
-        registerBase, but the global object uses the register file *stack*'s
-        registerBase, which updates dynamically to match the register file at
-        the top of the stack.
-        
-        sunspider --squirrelfish reports no regression.
-
-2008-04-08  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - initial preparatory work for JS constructors
-        
-        1) Allocate registers for the returnInfo block and "this" value when generating code for
-        op_construct. These are not used yet, but the JS branch of op_construct will use them.
-        
-        2) Adjust argc and argv appropriately for native constructor calls.
-        
-        3) Assign return value in a more straightforward way in op_ret since this is actually
-        a bit faster (and makes up for the allocation of extra registers above).
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitConstruct):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed crashing SunSpider tests.
-        
-        Let's just pretend this never happened, bokay?
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::CodeGenerator):
-        * VM/CodeGenerator.h:
-        * VM/RegisterFile.cpp:
-        (KJS::RegisterFile::addGlobals):
-
-2008-04-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Restored dumping of generated code as a command-line switch:
-        run-testkjs -d will do it.
-
-2008-04-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Next step toward supporting re-entrant evaluation: Moved register file
-        maintenance code into a proper "RegisterFile" class.
-        
-        There's a subtle change to the register file's internal layout: for
-        global code / the global object, registerOffset is always 0 now. In
-        other words, all register counting starts at 0, not 0 + (number of
-        global variables). The helps simplify accounting when the number of
-        global variables changes.
-
-2008-04-07  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 18338: Support exceptions in SquirrelFish <http://bugs.webkit.org/show_bug.cgi?id=18338>
-        
-        Initial support for exceptions in SquirrelFish, only supports finalisers in the
-        simple cases (eg. exceptions and non-goto/return across finaliser boundaries).
-        This doesn't add the required exception checks to existing code, it merely adds
-        support for throw, catch, and the required stack unwinding.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        (KJS::CodeBlock::getHandlerForVPC):
-        * VM/CodeBlock.h:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitCatch):
-        (KJS::CodeGenerator::emitThrow):
-        * VM/CodeGenerator.h:
-        * VM/JSPropertyNameIterator.cpp:
-        (KJS::JSPropertyNameIterator::create):
-        * VM/Machine.cpp:
-        (KJS::prepareException):
-        (KJS::Machine::unwindCallFrame):
-        (KJS::Machine::throwException):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::ThrowNode::emitCode):
-        (KJS::TryNode::emitCode):
-        * kjs/nodes.h:
-        * kjs/scope_chain.cpp:
-        (KJS::ScopeChain::depth):
-        * kjs/scope_chain.h:
-
-2008-04-06  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        First step toward supporting re-entrant evaluation: Switch register
-        clients from using "registers", a pointer to a register vector, to
-        "registerBase", an indirect pointer to the logical first entry in the
-        register file. (The logical first entry is the first entry that is not
-        a global variable).
-        
-        With a vector, offsets into the register file remain good when the
-        underlying buffer reallocates, but they go bad when the logical
-        first entry moves. (The logical first entry moves when new global
-        variables get added to the beginning of the register file.) With an
-        indirect pointer to the logical first entry, offsets will remain good
-        regardless.
-
-        1.4% speedup on sunspider --squirrelfish. I suspect this is due to
-        reduced allocation when creating closures, and reduced indirection
-        through the register vector.
-
-        * wtf/Vector.h: Added an accessor for an indirect pointer to the vector's
-        buffer, which we currently use (incorrectly) for registerBase. This is
-        temporary scaffolding to allow us to change client code without
-        changing behavior.
-
-2008-04-06  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Implement codegen for ReadModifyDotNode.
-
-        * kjs/nodes.cpp:
-        (KJS::ReadModifyDotNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-06  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Fix codegen for PostIncDotNode and implement codegen for PostIncBracketNode,
-        PostDecBracketNode and PostDecDotNode.
-
-        * kjs/nodes.cpp:
-        (KJS::PostIncBracketNode::emitCode):
-        (KJS::PostDecBracketNode::emitCode):
-        (KJS::PostIncDotNode::emitCode):
-        (KJS::PostDecDotNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-06  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Implement codegen for PreDecResolveNode, PreIncBracketNode, PreDecBracketNode,
-        PreIncDotNode and PreDecDotNode.  This required adding one new op code, op_pre_dec.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitPreDec):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::PreDecResolveNode::emitCode):
-        (KJS::PreIncBracketNode::emitCode):
-        (KJS::PreDecBracketNode::emitCode):
-        (KJS::PreIncDotNode::emitCode):
-        (KJS::PreDecDotNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-06  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Improved register dumping, plus a liberal smattering of "const". Here's
-        what the new format looks like:
-
-        (gdb) call (void)dumpCallFrame(codeBlock, scopeChain, registers->begin(), r)
-        4 instructions; 48 bytes at 0x509210; 3 locals (2 parameters); 1 temporaries
-
-        [   0] load             lr1, undefined(@k0)
-        [   3] load             lr1, 2(@k1)
-        [   6] add              tr0, lr2, lr1
-        [  10] ret              tr0
-
-        Constants:
-          k0 = undefined
-          k1 = 2
-
-        Register frame: 
-
-        ----------------------------------------
-             use      |   address  |    value   
-        ----------------------------------------
-        [return info] |   0x80ac08 |   0x5081c0 
-        [return info] |   0x80ac0c |   0x508e90 
-        [return info] |   0x80ac10 |   0x504acc 
-        [return info] |   0x80ac14 |        0x2 
-        [return info] |   0x80ac18 |        0x0 
-        [return info] |   0x80ac1c |        0x7 
-        [return info] |   0x80ac20 |        0x0 
-        ----------------------------------------
-        [param]       |   0x80ac24 |        0x1 
-        [param]       |   0x80ac28 |        0x7 
-        [var]         |   0x80ac2c |        0xb 
-        [temp]        |   0x80ac30 |        0xf 
-
-2008-04-06  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Support for evaluating multiple scripts in the same global environment.
-        (Still don't support re-entrant evaluation yet.)
-
-        The main changes here are:
-
-        (1) Obey the ECMA 10.1.3 rules regarding how to resolve collisions when
-        a given symbol is declared more than once. (This patch fixes the same
-        issue for function code, too.)
-        
-        (2) In the case of var and/or function collisions, reuse the existing
-        storage slot. For global code, this is required for previously
-        generated instructions to continue to work. For function code, it's
-        more of a "nice to have": it makes register layout in the case of
-        collisions easier to understand, and has the added benefit of saving
-        memory.
-        
-        (3) Allocate slots in the CodeGenerator's m_locals vector in parallel
-        to register indexes in the symbol table. This ensures that, given an
-        index in the symbol table, we can find the corresponding RegisterID
-        without hashing, which speeds up codegen. 
-        
-        I moved responsibility for emitting var and function initialization
-        instructions into the CodeGenerator, because bookkeeping in cases where
-        var, function, and/or parameter names collide requires a lot of
-        internal knowledge about the CodeGenerator.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addVar): Removed responsibility for checking whether
-        a var declaration overwrites "arguments", because the check is
-        inappropriate for global code, which may not have a pre-existing
-        "arguments" symbol in scope. Also changed this function to return a
-        boolean indicating whether addVar actually created a new RegisterID,
-        or just reused an old one.
-        
-        (KJS::CodeGenerator::CodeGenerator): Split out the constructors for
-        function code and global code, since they're quite different now.
-        
-        (KJS::CodeGenerator::registerForLocal): This function does its job
-        without any hashing now.
-        
-        * VM/Machine.cpp: Move old globals and update "r" before executing a
-        new script. That way, old globals stay at a constant offset from "r",
-        and previously optimized code still works.
-        
-        * VM/RegisterID.h: Added the ability to allocate a RegisterID before
-        initializing its index field. We use this for parameters now.
-
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTableGet): Changed the ungettable getter
-        ASSERT to account for the fact that symbol indexes are all negative.
-
-2008-04-05  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Implement codegen for InNode.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitIn):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::InNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-05  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        - Implement codegen for DeleteResolveNode, DeleteBracketNode, DeleteDotNode and DeleteValueNode.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitGetPropId):
-        (KJS::CodeGenerator::emitPutPropId):
-        (KJS::CodeGenerator::emitDeletePropId):
-        (KJS::CodeGenerator::emitDeletePropVal):
-        (KJS::CodeGenerator::emitPutPropIndex):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::DeleteResolveNode::emitCode):
-        (KJS::DeleteBracketNode::emitCode):
-        (KJS::DeleteDotNode::emitCode):
-        (KJS::DeleteValueNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-04  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        - Implement codegen for Switch statements.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::pushJumpContext):
-        (KJS::CodeGenerator::popJumpContext):
-        (KJS::CodeGenerator::jumpContextForLabel):
-        * VM/CodeGenerator.h:
-        Rename LoopContext to JumpContext now that it used of Switch statements in addition
-        to loops.
-
-        * kjs/nodes.cpp:
-        (KJS::DoWhileNode::emitCode):
-        (KJS::WhileNode::emitCode):
-        (KJS::ForNode::emitCode):
-        (KJS::ForInNode::emitCode):
-        (KJS::ContinueNode::emitCode):
-        (KJS::BreakNode::emitCode):
-        (KJS::CaseBlockNode::emitCodeForBlock):
-        (KJS::SwitchNode::emitCode):
-        * kjs/nodes.h:
-        (KJS::CaseClauseNode::expr):
-        (KJS::CaseClauseNode::children):
-        (KJS::CaseBlockNode::):
-
-2008-04-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Sam.
-        
-        - fix crash in codegen from new nodes
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitConstruct):
-        * kjs/nodes.h:
-
-2008-04-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-
-        * kjs/nodes.cpp:
-        (KJS::ReadModifyResolveNode::emitCode):
-        (KJS::ReadModifyBracketNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-02  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - take a shot at marking constant pools for global and eval code
-        
-        Geoff says this won't really work in all cases but is an ok stopgap.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::mark):
-
-2008-04-02  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - fix 2x perf regression in 3d-morph
-        
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): If we subbed in null for the global object,
-        don't toObject it, since that will throw an exception (very slowly).
-
-2008-04-02  Maciej Stachowiak  <mjs@apple.com>
-
-        Rubber stamped by Geoff
-        
-        - fix Release build
-
-        * kjs/nodes.cpp:
-        (KJS::getNonLocalSymbol):
-
-2008-04-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Removed the last vestiges of LocalStorage from JSVariableObject and
-        JSGlobalObject.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::saveLocalStorage): Save and restore from/to
-        registers. Use stub isReadOnly and isDontEnum methods for now, until
-        we really implement attributes in the symbol table.
-        (KJS::JSGlobalObject::restoreLocalStorage):
-        (KJS::JSGlobalObject::reset):
-
-        * kjs/JSVariableObject.cpp:
-        (KJS::JSVariableObject::getPropertyNames): Use stub isDontEnum method
-        for now, as above.
-        (KJS::JSVariableObject::getPropertyAttributes): ditto
-
-        * kjs/JSVariableObject.h: Removed LocalStorage from JSVariableObjectData.
-        Removed mark method, because subclasses implement different strategies for
-        marking registers.
-        (KJS::JSVariableObject::isReadOnly): Stub method
-        (KJS::JSVariableObject::isDontEnum): ditto
-
-        Changed the code below to ASSERT_NOT_REACHED() and return 0, since it
-        can no longer retrieve LocalStorage from the ExecState. (Eventually,
-        we'll just remove this code and all its friends, but that's a task for
-        later.)
-        
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        * kjs/function.cpp:
-        (KJS::ActivationImp::markChildren):
-        * kjs/function.h:
-        * kjs/nodes.cpp:
-        (KJS::getNonLocalSymbol):
-        (KJS::ScopeNode::optimizeVariableAccess):
-        (KJS::ProgramNode::processDeclarations):
-
-2008-04-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Got globals?
-        
-        To get things working, I had to roll out
-        http://trac.webkit.org/projects/webkit/changeset/31226 for the time
-        being.
-
-        * VM/CodeBlock.h: Removed obsolete function.
-        
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): For the sake of re-entrancy, we track
-        and restore the global object's old rOffset value. (No way to test this
-        yet, but I think it will work.)
-
-2008-04-01  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - mark the constant pool (at least for function code blocks)
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::mark):
-        * VM/CodeBlock.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::mark):
-        * kjs/nodes.cpp:
-        (KJS::ScopeNode::mark):
-        * kjs/nodes.h:
-        (KJS::FuncExprNode::body):
-        (KJS::FuncDeclNode::body):
-
-2008-04-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Beth Dakin.
-        
-        Cleaned up a few loose ends.
-
-        * JavaScriptCore.exp: Export dumpRegisters, so it's visible to gdb even
-        if we don't explicitly call it in the source text.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): No need to call dumpRegisters anymore,
-        since that was just a hack for gdb's sake.
-
-        * kjs/JSActivation.h: Removed obsolete comment.
-
-        * VM/CodeGenerator.cpp: Added ASSERTs to verify that the localCount
-        we're given matches the number of locals actually allocated.
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::CodeGenerator): Changed "localCount" to include
-        the parameter count, since we're using the word "local" to mean
-        parameter, var, function, or "this". Renamed "m_nextLocal" to
-        "m_nextVar", since "m_nextLocal" doesn't contrast well with
-        "m_nextParameter".
-        
-        Also moved tracking of implicit "this" parameter from here...
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionBodyNode::generateCode): ... to here
-        (KJS::ProgramNode::generateCode): ... and here
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump): Added missing "\n".
-
-2008-04-01  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver.
-
-        Bug 18274: ResolveNode::emitCode() doesn't make a new temporary when dst
-                   is 0, leading to incorrect codegen
-        <http://bugs.webkit.org/show_bug.cgi?id=18274>
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallBracketNode::emitCode):
-        (KJS::FunctionCallDotNode::emitCode):
-
-2008-04-01  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - fix bug in for..in codegen (gotta use ident, not m_ident)
-
-        * kjs/nodes.cpp:
-        (KJS::ForInNode::emitCode):
-
-2008-04-01  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - Add suport for regexp literals
-
-        * VM/CodeBlock.cpp:
-        (KJS::regexpToSourceString):
-        (KJS::regexpName):
-        (KJS::CodeBlock::dump):
-        * VM/CodeBlock.h:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addRegExp):
-        (KJS::CodeGenerator::emitNewRegExp):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::RegExpNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-01  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff
-
-        Add support for for..in nodes
-        
-        Added two new opcodes to get_pnames and next_pname to handle iterating
-        over the set of properties on an object.  This iterator is explicitly
-        invalidated and the property name array is released on standard exit
-        from the loop, otherwise we rely on GC to do the clean up for us.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitNextPropertyName):
-        (KJS::CodeGenerator::emitGetPropertyNames):
-        * VM/CodeGenerator.h:
-        * VM/JSPropertyNameIterator.cpp: Added.
-        (KJS::JSPropertyNameIterator::JSPropertyNameIterator):
-        (KJS::JSPropertyNameIterator::type):
-        (KJS::JSPropertyNameIterator::toPrimitive):
-        (KJS::JSPropertyNameIterator::getPrimitiveNumber):
-        (KJS::JSPropertyNameIterator::toBoolean):
-        (KJS::JSPropertyNameIterator::toNumber):
-        (KJS::JSPropertyNameIterator::toString):
-        (KJS::JSPropertyNameIterator::toObject):
-        (KJS::JSPropertyNameIterator::mark):
-        (KJS::JSPropertyNameIterator::next):
-        (KJS::JSPropertyNameIterator::invalidate):
-        (KJS::JSPropertyNameIterator::~JSPropertyNameIterator):
-        (KJS::JSPropertyNameIterator::create):
-        * VM/JSPropertyNameIterator.h: Added.
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * VM/Register.h:
-        (KJS::Register::):
-        * kjs/PropertyNameArray.h:
-        * kjs/nodes.cpp:
-        (KJS::ForInNode::emitCode):
-        * kjs/nodes.h:
-        * kjs/value.h:
-
-2008-04-01  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Change CodeGenerator::emitCall() so it increments the reference count of
-        registers passed to it, and change its callers so they don't needlessly
-        increment the reference count of the registers they are passing.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitCall):
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallResolveNode::emitCode):
-        (KJS::FunctionCallDotNode::emitCode):
-
-2008-04-01  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - generate call for PostIncDotNode
-
-        * kjs/nodes.cpp:
-        (KJS::PostIncDotNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-01  Maciej Stachowiak  <mjs@apple.com>
-
-        Build fix.
-        
-        - fix build (not sure how this ever worked?)
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallBracketNode::emitCode):
-
-2008-04-01  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - generate code for FunctionCallBracketNode
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallBracketNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-01  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Geoff.
-        
-        - Fix two crashing SunSpider tests
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): set up 'this' properly for native calls.
-        * kjs/list.h:
-        (KJS::List::List): Fix intialization of buffer and size from
-        vector, the initialization order was wrong.
-
-2008-04-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: marked ASSERT-only variables as UNUSED_PARAMs.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTableInitializeVariable):
-
-2008-04-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Next step toward global code: Moved get, put, and initializeVariable
-        functionality up into JSVariableObject, and changed JSActivation to
-        rely on it. 
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::JSActivation):
-        (KJS::JSActivation::getOwnPropertySlot):
-        (KJS::JSActivation::put):
-        (KJS::JSActivation::initializeVariable):
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::valueAt):
-        (KJS::JSVariableObject::isReadOnly):
-        (KJS::JSVariableObject::symbolTableGet):
-        (KJS::JSVariableObject::symbolTablePut):
-        (KJS::JSVariableObject::symbolTableInitializeVariable):
-
-2008-04-01  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Sam.
-        
-        - fix HashTable assertion on some SunSpider tests
-        
-        Don't use -1 as the deleted value for JSValue*-keyed hashtables,
-        since it is a valid value (it's the immediate for -1).
-
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::JSValueHashTraits::emptyValue):
-        (KJS::CodeGenerator::JSValueHashTraits::deletedValue):
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::impossibleValue):
-
-2008-04-01  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Maciej Stachowiak.
-
-        Add support for calling Native constructors like new Array(). 
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitConstruct):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::NewExprNode::emitCode):
-        * kjs/nodes.h:
-
-2008-04-01  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Sam.
-        
-        - add some missing toOpbject calls to avoid crashing when calling methods on primitives
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-04-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Changed Machine::dumpRegisters to take a pointer instead of a reference,
-        so gdb understands how to call it.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::dumpRegisters):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-
-2008-03-31  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Fix CodeGenerator::addConstant() so it uses the functionExpressions
-        counter for function expressions, not the functions counter.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addConstant):
-
-2008-03-31  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Add emitCode support for TypeOfResolveNode and TypeOfValueNode.
-        Added new opcode op_type_of to handle them.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitNot):
-        (KJS::CodeGenerator::emitInstanceOf):
-        (KJS::CodeGenerator::emitTypeOf):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::jsTypeStringForValue):
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::TypeOfResolveNode::emitCode):
-        (KJS::TypeOfValueNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-31  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Fix non-computed goto version of isOpcode. op_end is a valid opcode.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::isOpcode):
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Added op_post_dec.
-
-2008-03-31  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Geoffrey Garen.
-
-        Add support for FunctionCallDotNode.
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallDotNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Beth Dakin.
-
-        Next step toward global code: Removed more obsolete API, moved
-        saveLocalStorage and restoreLocalStorage to JSGlobalObject subclass,
-        since it's only intended for use there.
-        
-        * ChangeLog:
-        * JavaScriptCore.exp:
-        * kjs/Activation.h:
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::saveLocalStorage):
-        (KJS::JSGlobalObject::restoreLocalStorage):
-        * kjs/JSGlobalObject.h:
-        * kjs/JSVariableObject.cpp:
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::JSVariableObjectData::JSVariableObjectData):
-        * kjs/function.cpp:
-        (KJS::ActivationImp::ActivationImp):
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Beth Dakin.
-
-        Next step toward global code: subclass JSActivation + JSActivationData
-        from JSVariableObject + JSVariableObjectData.
-        
-        JSActivation now relies on JSVariableObject for access to registers and
-        symbol table, and for some delete functionality, but not for anything
-        else yet.
-
-        (KJS::JSActivation::mark): Cleaned up the style here a little bit.
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Beth Dakin.
-        
-        Next step toward global code: store "rOffset" in JSVariableObjectData.
-
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData):
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::JSVariableObjectData::JSVariableObjectData):
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Next steps toward global code:
-        
-        * Moved access to the register file into JSVariableObject.
-        
-        * Added more ASSERTs to indicate obsolete APIs there are just hanging
-        around to stave off build failures.
-
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData):
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::registers):
-        (KJS::JSVariableObject::JSVariableObjectData::JSVariableObjectData):
-        (KJS::JSVariableObject::JSVariableObject):
-
-2008-03-31  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver. Tweaked somewhat by Maciej.
-        
-        - implement codegen for ReadModifyResolveNode
-
-        * kjs/nodes.cpp:
-        (KJS::emitReadModifyAssignment):
-        (KJS::ReadModifyResolveNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-31  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Geoff.
-
-        Fix the build -- r31492 removed activation tear-off, but r31493 used it.
-
-        * kjs/nodes.cpp:
-        (KJS::FuncExprNode::makeFunction):
-
-2008-03-31  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Add support for FuncExprNode to SquirrelFish.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeBlock.h:
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::addConstant):
-        (KJS::CodeGenerator::emitNewFunctionExpression):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::FuncExprNode::emitCode):
-        (KJS::FuncExprNode::makeFunction):
-        * kjs/nodes.h:
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        First step toward global code: removed some obsolete JSGlobalObject
-        APIs, changing clients to ASSERT_NOT_REACHED.
-        
-        Activation tear-off and scope chain pushing is obsolete because we
-        statically detect whether an activation + scope node is required.
-        
-        The variableObject() and activationObject() accessors are obsolete
-        because they haven't been maintained, and they're mostly used by
-        node evaluation code, anyway.
-        
-        The localStorage() accessor is obsolete because everything is in
-        registers now, and it's mostly used by node evaluation code, anyway.
-
-2008-03-31  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Darin.
-        
-        - implement codegen for bracket accessor and bracket assign
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitGetPropVal):
-        (KJS::CodeGenerator::emitPutPropVal):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::BracketAccessorNode::emitCode):
-        (KJS::AssignBracketNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Not reviewed.
-        
-        Removed FIXME that I just fixed.
-        
-        Added ASSERT to cover an error previously only covered by a FIXME.
-
-        * kjs/JSActivation.cpp:
-        (KJS::JSActivation::getOwnPropertySlot):
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Not reviewed.
-
-        Fixed indentation inside op_call. (I had left this code badly indented
-        to make the behavior-changing diff clearer.)
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Fixed up logging of jump instructions to follow the following style:
-        
-        jump    offset(->absoluteTarget)
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-
-2008-03-31  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Changed the SymbolTable API to use int instead of size_t. It has been
-        using int internally for a while now (since squirrelfish symbols can
-        have negative indices).
-
-2008-03-31  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Add support for FunctionCallValueNode.
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallValueNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-31  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        1) Implemented array literals
-        
-        2) Renamed op_object_get and op_object_put to op_get_prop_id and
-        op_put_prop_id in preparation for new variants.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitNewArray):
-        (KJS::CodeGenerator::emitGetPropId):
-        (KJS::CodeGenerator::emitPutPropId):
-        (KJS::CodeGenerator::emitPutPropIndex):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::CodeGenerator):
-        (KJS::CodeGenerator::propertyNames):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::ArrayNode::emitCode):
-        (KJS::PropertyListNode::emitCode):
-        (KJS::DotAccessorNode::emitCode):
-        (KJS::PostIncResolveNode::emitCode):
-        (KJS::PreIncResolveNode::emitCode):
-        (KJS::AssignResolveNode::emitCode):
-        (KJS::AssignDotNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Implemented native function calls. (Re-entering from native code back
-        to JS doesn't work yet, though.)
-
-        0.2% speedup overall, due to some inlining tweaks. 3.6% regression on
-        function-empty.js, since we're making a new virtual call and taking a
-        new branch inside every op_call.
-        
-        I adjusted the JavaScriptCore calling convention to minimize overhead,
-        like so:
-        
-        The machine calls a single virtual function, "getCallData", to get all
-        the data it needs for a function call. Native code still uses the old
-        "isObject()" check followed by an "implementsCall()" check, which
-        aliases to "getCallData". (We can optimize native code to use getCallData
-        at our leisure.)
-        
-        To supply a list of arguments, the machine calls a new List constructor
-        that just takes a pointer and a length, without copying. Native code
-        still appends to the list one argument at a time. (We can optimize
-        native code to use the new List constructor at our leisure.)
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Changed resize() call to grow() call,
-        to encourage the compiler to inline the Vector code.
-
-        * kjs/CallData.h: Added.
-        (KJS::): CallData is a union because eventually native calls will stuff
-        a function pointer into it, to eliminate the callAsFunction virtual call.
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction): Changed this to an ASSERT since
-        it's not implemented yet.
-        
-        * kjs/list.h: Made the List class two-faced, to support the old way and
-        the new way during this transition phase: lists can be made read-only
-        with just a pointer and a legnth, or you can append to them one item
-        at a time.
-
-        * kjs/value.h:
-        (KJS::jsUndefined): Marked this function ALWAYS_INLINE for the benefit
-        of a certain compiler that doesn't know what's best for it.
-
-2008-03-30  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-
-        Dump code that codegen can't handle yet, so it's easier to prioritize missing nodes.
-        
-        * kjs/nodes.h:
-        (KJS::Node::emitCode):
-
-2008-03-30  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-
-        Improve dumping of bytecode and fix coding style accordingly.
-        
-        Registers are printed as lr1 for locals, tr1 for temp registers. Identifiers print as
-        foobar(@id0) and constants print as "foo"(@k1) or 312.4(@k2) or the like. Constant and
-        identifier tables are dumped for reference.
-        
-        * VM/CodeBlock.cpp:
-        (KJS::escapeQuotes):
-        (KJS::valueToSourceString):
-        (KJS::registerName):
-        (KJS::constantName):
-        (KJS::idName):
-        (KJS::printUnaryOp):
-        (KJS::printBinaryOp):
-        (KJS::CodeBlock::dump):
-        * VM/Machine.cpp:
-        (KJS::resolve):
-        (KJS::resolveBase):
-        (KJS::Machine::privateExecute):
-
-2008-03-30  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        Implement StringNode and VoidNode (both pretty trivial).
-
-        * kjs/nodes.cpp:
-        (KJS::StringNode::emitCode):
-        (KJS::VoidNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-30  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Sam.
-
-        Implement CommaNode.
-        
-        * kjs/nodes.cpp:
-        (KJS::CommaNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-30  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Adds support for dot notation and object literals.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitNewObject):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::ObjectLiteralNode::emitCode):
-        (KJS::PropertyListNode::emitCode):
-        (KJS::DotAccessorNode::emitCode):
-        (KJS::AssignDotNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-29  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Mark the register file. 
-        
-        It's a conservative mark for now, but once registers are typed, we can
-        do an exact mark.
-        
-        1.4% regression regardless of whether we actually do the marking.
-        GCC is is worth every penny.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Most of the changes here are just for
-        the fact that "registers" is a pointer now.
-
-        * kjs/JSGlobalObject.cpp: The global object owns the register file now.
-
-2008-03-28  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18204: SquirrelFish: continue/break do not correctly handle scope popping
-        <http://bugs.webkit.org/show_bug.cgi?id=18204>
-
-        We now track the scope depth as part of a loop context, and add an
-        extra instruction op_jump_scopes that is used to perform a jump across
-        dynamic scope boundaries.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitJumpScopes):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::ContinueNode::emitCode):
-        (KJS::BreakNode::emitCode):
-
-2008-03-28  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Add emitCode support for ConditionalNode.
-
-        * kjs/nodes.cpp:
-        (KJS::ConditionalNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Responding to feedback, added some comments, fixed up a few names, and
-        clarified that "locals" always means all local variables, functions,
-        and parameters.
-
-2008-03-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Added support for "this".
-        
-        Supply an implicit "this" value as the first argument to every function.
-        Alias the "this" keyword to that argument.
-        
-        1% regression overall, 2.5% regression on empty function calls. Seems
-        like a reasonable cost for now, since we're doing more work.
-        (Eventually, we might decide to create a version of op_call specialized
-        for a known null "this" value.)
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitCall):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::CodeGenerator):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * kjs/CommonIdentifiers.cpp:
-        (KJS::CommonIdentifiers::CommonIdentifiers):
-        * kjs/CommonIdentifiers.h:
-        * kjs/nodes.cpp:
-        (KJS::ThisNode::emitCode):
-        (KJS::FunctionCallResolveNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-28  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 18192: Squirrelfish needs support for break and continue
-        <http://bugs.webkit.org/show_bug.cgi?id=18192>
-
-        Added a loop context stack to the code generator to provide the
-        correct jump labels for continue and goto.  Added logic to the
-        currently implemented loop constructs to manage entry and exit
-        from the loop contexts.  Finally, implemented codegen for break
-        and continue (and a pass through for LabelNode)
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::pushLoopContext):
-        (KJS::CodeGenerator::popLoopContext):
-        (KJS::CodeGenerator::loopContextForIdentifier):
-        (KJS::CodeGenerator::labelForContinue):
-        (KJS::CodeGenerator::labelForBreak):
-        * VM/CodeGenerator.h:
-        * kjs/nodes.cpp:
-        (KJS::DoWhileNode::emitCode):
-        (KJS::WhileNode::emitCode):
-        (KJS::ForNode::emitCode):
-        (KJS::ContinueNode::emitCode):
-        (KJS::BreakNode::emitCode):
-        (KJS::LabelNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-27  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Add emitCode support for UnaryPlusNode, NegateNode, BitwiseNotNode and LogicalNotNode.
-
-        * VM/CodeBlock.cpp:
-        (KJS::printUnaryOp):
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitToJSNumber):
-        (KJS::CodeGenerator::emitNegate):
-        (KJS::CodeGenerator::emitBitNot):
-        (KJS::CodeGenerator::emitNot):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::UnaryPlusNode::emitCode):
-        (KJS::NegateNode::emitCode):
-        (KJS::BitwiseNotNode::emitCode):
-        (KJS::LogicalNotNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-27  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej Stachowiak.
-
-        Add support for LogicalAndNode and LogicalOrNode.
-
-        * kjs/nodes.cpp:
-        (KJS::LogicalAndNode::emitCode):
-        (KJS::LogicalOrNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-27  Sam Weinig  <sam@webkit.org>
-
-        Clean up code and debug output.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-03-27  Geoffrey Garen  <ggaren@apple.com>
-
-        Moved an ASSERT to a more logical place.
-
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-03-27  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Add emitCode support for InstanceOfNode.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitInstanceOf):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::InstanceOfNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-27  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Bug 18142: squirrelfish needs to support dynamic scoping/with
-        <http://bugs.webkit.org/show_bug.cgi?id=18142>
-
-        Add support for dynamic scoping and add code to handle 'with'
-        statements.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeBlock.h:
-        (KJS::CodeBlock::CodeBlock):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::getRegister):
-        (KJS::CodeGenerator::emitPushScope):
-        (KJS::CodeGenerator::emitPopScope):
-        * VM/CodeGenerator.h:
-        (KJS::CodeGenerator::CodeGenerator):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::WithNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-27  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Add emitCode support for NullNode, FalseNode, TrueNode, IfNode, IfElseNode, DoWhileNode and WhileNode
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump): Dump op_jfalse opcode.
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitJumpIfFalse): Identical to emitJumpIfTrue except it emits the op_jfalse opcode.
-        (KJS::CodeGenerator::emitLoad): Add and emitLoad override for booleans.
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute): Adds execution of op_jfalse. It is identical to op_jtrue, except the
-        the condition is reversed.
-        * VM/Opcode.h: Add op_jfalse.
-        * kjs/nodes.cpp:
-        (KJS::NullNode::emitCode): Added.
-        (KJS::FalseNode::emitCode): Added.
-        (KJS::TrueNode::emitCode): Added.
-        (KJS::IfNode::emitCode): Added.
-        (KJS::IfElseNode::emitCode): Added.
-        (KJS::DoWhileNode::emitCode): Added.
-        (KJS::WhileNode::emitCode): Added.
-        * kjs/nodes.h:
-
-2008-03-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Nixed an unused List.
-        
-        The calm before my stormy war against the List class.
-
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct):
-
-2008-03-26  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Geoffrey Garen.
-
-        Adds support for EqualNode, NotEqualNode, StrictEqualNode, NotStrictEqualNode,
-        LessEqNode, GreaterNode, GreaterEqNode, MultNode, DivNode, ModNode, SubNode,
-        LeftShiftNode, RightShiftNode, UnsignedRightShiftNode, BitAndNode, BitXOrNode,
-        and BitOrNode.
-
-        * VM/CodeBlock.cpp:
-        (KJS::CodeBlock::dump):
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::emitEqual):
-        (KJS::CodeGenerator::emitNotEqual):
-        (KJS::CodeGenerator::emitStrictEqual):
-        (KJS::CodeGenerator::emitNotStrictEqual):
-        (KJS::CodeGenerator::emitLessEq):
-        (KJS::CodeGenerator::emitMult):
-        (KJS::CodeGenerator::emitDiv):
-        (KJS::CodeGenerator::emitMod):
-        (KJS::CodeGenerator::emitSub):
-        (KJS::CodeGenerator::emitLeftShift):
-        (KJS::CodeGenerator::emitRightShift):
-        (KJS::CodeGenerator::emitUnsignedRightShift):
-        (KJS::CodeGenerator::emitBitAnd):
-        (KJS::CodeGenerator::emitBitXOr):
-        (KJS::CodeGenerator::emitBitOr):
-        * VM/CodeGenerator.h:
-        * VM/Machine.cpp:
-        (KJS::jsLessEq):
-        (KJS::Machine::privateExecute):
-        * VM/Opcode.h:
-        * kjs/nodes.cpp:
-        (KJS::MultNode::emitCode):
-        (KJS::DivNode::emitCode):
-        (KJS::ModNode::emitCode):
-        (KJS::SubNode::emitCode):
-        (KJS::LeftShiftNode::emitCode):
-        (KJS::RightShiftNode::emitCode):
-        (KJS::UnsignedRightShiftNode::emitCode):
-        (KJS::GreaterNode::emitCode):
-        (KJS::LessEqNode::emitCode):
-        (KJS::GreaterEqNode::emitCode):
-        (KJS::EqualNode::emitCode):
-        (KJS::NotEqualNode::emitCode):
-        (KJS::StrictEqualNode::emitCode):
-        (KJS::NotStrictEqualNode::emitCode):
-        (KJS::BitAndNode::emitCode):
-        (KJS::BitXOrNode::emitCode):
-        (KJS::BitOrNode::emitCode):
-        * kjs/nodes.h:
-
-2008-03-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Only print debug dumps in debug builds.
-
-        * VM/CodeGenerator.cpp:
-        (KJS::CodeGenerator::generate):
-        * VM/Machine.cpp:
-        (KJS::Machine::privateExecute):
-
-2008-03-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Moved a few files around in the XCode project.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-03-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Made closures work.
-        
-        An activation object aliases to the register file until its associated
-        function returns, at which point it copies the registers for locals and
-        parameters into an independent storage buffer.
-
-2008-03-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed recent 25% regression on simple for loop test. GCC seems to be
-        very finicky about the code that gets inlined into
-        Machine::privateExecute.
-
-        Everything in this patch is simply the result of experiment.
-        
-        The resolve and resolve_base opcodes do not seem to have gotten slower
-        from this change.
-
-        * VM/Machine.cpp:
-        (KJS::resolve):
-        (KJS::resolveBase):
-        (KJS::Machine::privateExecute):
-        * kjs/nodes.h:
-
-2008-03-24  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff Garen.
-
-        Bug 18059: squirrelfish needs to compile on platforms without computed goto
-        <http://bugs.webkit.org/show_bug.cgi?id=18059>
-
-        "Standard" macro style support for conditionalising the use of computed goto.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * VM/Machine.cpp:
-        (KJS::Machine::isOpcode):
-        (KJS::Machine::privateExecute):
-        * VM/Machine.h:
-        (KJS::Machine::getOpcode):
-        (KJS::Machine::getOpcodeID):
-        * VM/Opcode.h:
-        * wtf/Platform.h:
-
-2008-03-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Moved my notes from nodes.h to the wiki.
-
-        * kjs/nodes.h:
-
-2008-03-24  Geoffrey Garen  <ggaren@apple.com>
-
-        SquirrelFish lives.
-        
-        Initial check-in of the code I've been carrying around. Lots of stuff
-        doesn't work. Plus a bunch of empty files.
-
-=== Start merge of squirrelfish ===
-
-2008-05-21  Darin Adler  <darin@apple.com>
-
-        - try to fix the Windows build
-
-        * profiler/Profiler.cpp:
-        (KJS::Profiler::stopProfiling): Use ptrdiff_t instead of the less-common but incredibly
-        similar ssize_t type.
-        * wtf/AVLTree.h:
-        (KJS::AVLTree::search): Added a typename for a dependent name that's a type.
-
-2008-05-21  Darin Adler  <darin@apple.com>
-
-        Reviewed by Anders.
-
-        - fix <rdar://problem/5952721> bug in JavaScript arguments object property lookup
-
-        Test: fast/js/arguments-bad-index.html
-
-        * kjs/function.cpp:
-        (KJS::IndexToNameMap::IndexToNameMap): Use unsigned instead of int.
-        (KJS::IndexToNameMap::isMapped): Use unsigned instead of int, and also use the
-        strict version of the numeric conversion function, since we don't want to allow
-        trailing junk.
-        (KJS::IndexToNameMap::unMap): Ditto.
-        (KJS::IndexToNameMap::operator[]): Ditto.
-        * kjs/function.h: Changed IndexToNameMap::size type from int to unsigned.
-
-2008-05-21  Timothy Hatcher  <timothy@apple.com>
-
-        Change the Profiler to allow multiple profiles to be running at
-        the same time. This can happen when you have nested console.profile()
-        calls. This required two changes. First, the Profiler needed to keep a
-        Vector of current profiles, instead of one. Second, a Profile needs
-        to keep track of the global ExecState it started in and the page group
-        identifier it is tracking.
-
-        The stopProfiling call now takes the same arguments as startProfiling.
-        This makes sure the correct profile is stopped. Passing a null UString
-        as the title will stop the last profile for the matching ExecState.
-
-        <rdar://problem/5951559> Multiple pages profiling can interfere with each other
-
-        Reviewed by Kevin McCullough.
-
-        * JavaScriptCore.exp: Added new exports. Removed old symbols.
-        * profiler/Profile.cpp:
-        (KJS::Profile::Profile): New constructor arguments for the
-        originatingGlobalExec and pageGroupIdentifier.
-        (KJS::Profile::stopProfiling): Set the m_originatingGlobalExec to null.
-        * profiler/Profile.h:
-        (KJS::Profile::create): Additional arguments.
-        (KJS::Profile::originatingGlobalExec): Return m_originatingGlobalExec.
-        (KJS::Profile::pageGroupIdentifier): Return m_pageGroupIdentifier.
-        * profiler/Profiler.cpp:
-        (KJS::Profiler::findProfile): Added. Finds a Profile that matches
-        the ExecState and title.
-        (KJS::Profiler::startProfiling): Return early if there is already
-        a Profile with the ExecState and title. If not, create a new profile
-        and append it to m_currentProfiles.
-        (KJS::Profiler::stopProfiling): Loops through m_currentProfiles
-        and find the one matching the ExecState and title. If one is found
-        call stopProfiling and return the Profile after removing it
-        from m_currentProfiles.
-        (KJS::dispatchFunctionToProfiles): Helper inline function to loop through
-        m_currentProfiles and call a Profile function.
-        (KJS::Profiler::willExecute): Call dispatchFunctionToProfiles.
-        (KJS::Profiler::didExecute): Ditto.
-        * profiler/Profiler.h:
-
-2008-05-21  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5908520> REGRESSION (3.1.1-r33033): Crash in WebKit when opening or
-        refreshing page on people.com
-
-        The problem was that STL algorithms do not work with non-conformant comparators, and the
-        site used sort(function() { return 0.5 - Math.random(); } to randomly shuffle an array.
-
-        https://bugs.webkit.org/show_bug.cgi?id=18687
-        REGRESSION(r32220): ecma/Array/15.4.4.5-3.js test now fails in GMT(BST)
-
-        Besides relying on sort stability, this test was just broken, and kept failing with the
-        new stable sort.
-
-        Tests: fast/js/sort-randomly.html
-               fast/js/sort-stability.html
-               fast/js/comparefn-sort-stability.html
-
-        * kjs/avl_tree.h: Added an AVL tree implementation.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * wtf/AVLTree.h: Added.
-        Added an AVL tree implementation.
-
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::increaseVectorLength):
-        (KJS::ArrayInstance::sort):
-        (KJS::AVLTreeAbstractorForArrayCompare::get_less):
-        (KJS::AVLTreeAbstractorForArrayCompare::set_less):
-        (KJS::AVLTreeAbstractorForArrayCompare::get_greater):
-        (KJS::AVLTreeAbstractorForArrayCompare::set_greater):
-        (KJS::AVLTreeAbstractorForArrayCompare::get_balance_factor):
-        (KJS::AVLTreeAbstractorForArrayCompare::set_balance_factor):
-        (KJS::AVLTreeAbstractorForArrayCompare::compare_key_key):
-        (KJS::AVLTreeAbstractorForArrayCompare::compare_key_node):
-        (KJS::AVLTreeAbstractorForArrayCompare::compare_node_node):
-        (KJS::AVLTreeAbstractorForArrayCompare::null):
-        (KJS::ArrayInstance::compactForSorting):
-        
-        * kjs/array_instance.h: increaseVectorLength() now returns a bool to indicate whether it was
-        successful.
-
-        * wtf/Vector.h:
-        (WTF::Vector::Vector):
-        (WTF::::operator=):
-        (WTF::::fill):
-        Make these methods fail instead of crash when allocation fails, matching resize() and
-        reserveCapacity(), which already had this behavior. Callers need to check for null buffer
-        after making any Vector call that can try to allocate.
-
-        * tests/mozilla/ecma/Array/15.4.4.5-3.js: Fixed the test to use a consistent sort function,
-        as suggested in comments to a Mozilla bug filed about it (I'll keep tracking the bug to see
-        what the final resolution is).
-
-2008-05-20  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5950867> JSProfiler: Allow the profiler to "Focus" a
-        profile node.
-        - Implements focus by adding the idea of a profileNode being visible and
-        adding the ability to reset all of the visible flags.
-
-        * profiler/Profile.h: 
-        (KJS::Profile::focus):
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::ProfileNode): Initialize the visible flag.
-        (KJS::ProfileNode::setTreeVisible): Set the visibility of this node and
-        all of its descendents.
-        (KJS::ProfileNode::focus): Determine if this node should be visible when
-        focusing, if the functionName matches this node's function name or if any
-        of this node's children are visible.
-        (KJS::ProfileNode::restoreAll): Restore all nodes' visible flag.
-        (KJS::ProfileNode::debugPrintData):
-        * profiler/ProfileNode.h:
-        (KJS::ProfileNode::visible):
-        (KJS::ProfileNode::setVisible):
-
-2008-05-20  Timothy Hatcher  <timothy@apple.com>
-
-        Fixes a couple performance issues with the profiler. Also fixes
-        a regression where some nodes wouldn't be added to the tree.
-
-        Reviewed by Kevin McCullough.
-
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::addChild): Compare callIdentifier instead
-        of functionName.
-        * profiler/ProfileNode.h: 
-        (CallIdentifier.operator==): Compare the CallIdentifiers in
-        an order that fails sooner for non-matches.
-        (CallIdentifier.callIdentifier): Return the CallIdentifier by
-        reference to prevent making a new copy each time.
-
-2008-05-20  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5950796> JSProfiler: dump functions are in the code
-        Removed dump and logging functions from the Release version of the code
-        and renamed them to be obviously for debugging only.
-
-        * JavaScriptCore.exp:
-        * profiler/Profile.cpp:
-        (KJS::Profile::debugPrintData):
-        (KJS::Profile::debugPrintDataSampleStyle):
-        * profiler/Profile.h:
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::debugPrintData):
-        (KJS::ProfileNode::debugPrintDataSampleStyle):
-        * profiler/ProfileNode.h:
-        * profiler/Profiler.cpp:
-        * profiler/Profiler.h:
-
-2008-05-20  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Adam.
-
-        <rdar://problem/5950538> JSProfiler: Keep track of non-JS execution time
-        We now have an extra node that represents the excess non-JS time.
-        - Also changed "SCRIPT" and "anonymous function" to be more consistent
-        with the debugger.
-
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::stopProfiling): If this ProfileNode is the head node
-        create a new child that has the excess execution time.
-        (KJS::ProfileNode::calculatePercentages): Moved calculation of the
-        percentages into a function since it's called from multiple places.
-        * profiler/ProfileNode.h: Add the newly needed functions used above.
-        (KJS::ProfileNode::setTotalTime):
-        (KJS::ProfileNode::setSelfTime):
-        (KJS::ProfileNode::setNumberOfCalls):
-        * profiler/Profiler.cpp: renamed "SCRIPT" and "anonymous function" to be
-        consistent with the debugger and use constants that can be localized
-        more easily.
-        (KJS::getCallIdentifiers):
-        (KJS::getCallIdentifierFromFunctionImp):
-
-2008-05-20  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        Removed only profiler-internal use of currentProfile since that concept
-        is changing.
-
-        * profiler/Profile.h: Now stopProfiling takes a time and bool as
-        arguments.  The time is used to calculate %s from and the bool tells
-        if this node is the head node and should be the one calculating the time.
-        (KJS::Profile::stopProfiling):
-        * profiler/ProfileNode.cpp: Ditto.
-        (KJS::ProfileNode::stopProfiling):
-        * profiler/ProfileNode.h: Ditto.
-
-2008-05-20  Kevin McCullough  <kmccullough@apple.com>
-
-        Accidentally turned on the profiler.
-
-        * kjs/config.h:
-
-
-2008-05-20  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        Split function name into 3 parts so that the Web Inspector can link it to
-        the resource location from whence it came.
-
-        * kjs/ustring.cpp: Implemented operator> for UStrings
-        (KJS::operator>):
-        * kjs/ustring.h:
-        * profiler/Profile.cpp:
-        (KJS::Profile::Profile): Initialize all 3 values.
-        (KJS::Profile::willExecute): Use CallIdentifier struct.
-        (KJS::Profile::didExecute): Ditto.
-        * profiler/Profile.h: Ditto and remove unused function.
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::ProfileNode): Use CallIdentifier struct.
-        (KJS::ProfileNode::willExecute): Ditto and fix an issue where we
-        restarted the m_startTime even though it was already started.
-        (KJS::ProfileNode::didExecute): Ditto.
-        (KJS::ProfileNode::findChild): Ditto.
-        (KJS::functionNameDescendingComparator): Ditto and use new comparator.
-        (KJS::functionNameAscendingComparator): Ditto.
-        (KJS::ProfileNode::printDataInspectorStyle): Use CallIdentifier struct.
-        (KJS::ProfileNode::printDataSampleStyle): Ditto.
-        * profiler/ProfileNode.h:
-        (KJS::CallIdentifier::CallIdentifier): Describe the CallIdentifier struct
-        (KJS::CallIdentifier::operator== ):
-        (KJS::ProfileNode::create): Use the CallIdentifier struct.
-        (KJS::ProfileNode::callIdentifier):
-        (KJS::ProfileNode::functionName): Now only return the function name, not
-        the url and line number too.
-        (KJS::ProfileNode::url):
-        (KJS::ProfileNode::lineNumber):
-        * profiler/Profiler.cpp: Use the CallIdentifier struct. 
-        (KJS::Profiler::startProfiling):
-        (KJS::Profiler::willExecute):
-        (KJS::Profiler::didExecute):
-        (KJS::getCallIdentifiers):
-        (KJS::getCallIdentifierFromFunctionImp):
-
-2008-05-20  Timothy Hatcher  <timothy@apple.com>
-
-        Rename sortFileName{Ascending,Descending} to
-        sortFunctionName{Ascending,Descending}.
-
-        Reviewed by Kevin McCullough.
-
-        * JavaScriptCore.exp:
-        * kjs/config.h:
-        * profiler/Profile.h:
-        * profiler/ProfileNode.cpp:
-        (KJS::functionNameDescendingComparator):
-        (KJS::ProfileNode::sortFunctionNameDescending):
-        (KJS::functionNameAscendingComparator):
-        (KJS::ProfileNode::sortFunctionNameAscending):
-        * profiler/ProfileNode.h:
-
-2008-05-19  Timothy Hatcher  <timothy@apple.com>
-
-        Make the profiler use higher than millisecond resolution time-stamps.
-
-        Reviewed by Kevin McCullough.
-
-        * kjs/DateMath.cpp:
-        (KJS::getCurrentUTCTime): Call getCurrentUTCTimeWithMicroseconds and
-        floor the result.
-        (KJS::getCurrentUTCTimeWithMicroseconds): Copied from the previous
-        implementation of getCurrentUTCTime without the floor call.
-        * kjs/DateMath.h: Addded getCurrentUTCTimeWithMicroseconds.
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::ProfileNode): Use getCurrentUTCTimeWithMicroseconds.
-
-2008-05-19  Timothy Hatcher  <timothy@apple.com>
-
-        Fixes a bug in the profiler where call and apply would show up
-        and double the time spent in a function. We don't want to show call
-        and apply at all in the profiles. This change excludes them.
-
-        Reviewed by Kevin McCullough.
-
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::stopProfiling): Remove a second for loop and
-        calculate self time in the existing loop.
-        * profiler/Profiler.cpp:
-        (KJS::shouldExcludeFunction): Helper inline function that returns
-        true in the current function in an InternalFunctionImp and it is 
-        has the functionName call or apply.
-        (KJS::Profiler::willExecute): Call shouldExcludeFunction and return
-        early if if returns true.
-        (KJS::Profiler::didExecute): Ditto.
-
-2008-05-19  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - Implement sorting by function name.
-
-        * JavaScriptCore.exp:
-        * profiler/Profile.h:
-        (KJS::Profile::sortFileNameDescending):
-        (KJS::Profile::sortFileNameAscending):
-        * profiler/ProfileNode.cpp:
-        (KJS::fileNameDescendingComparator):
-        (KJS::ProfileNode::sortFileNameDescending):
-        (KJS::fileNameAscendingComparator):
-        (KJS::ProfileNode::sortFileNameAscending):
-        * profiler/ProfileNode.h:
-
-2008-05-19  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Adam.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - Pass the exec state to profiler when calling startProfiling so that if
-        profiling is started within an execution context that location is
-        recorded correctly.
-
-        * JavaScriptCore.exp:
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::printDataInspectorStyle): Dump more info for debugging
-        purposes.
-        * profiler/Profiler.cpp:
-        (KJS::Profiler::startProfiling):
-        * profiler/Profiler.h:
-
-2008-05-19  Kevin McCullough  <kmccullough@apple.com>
-
-        Rubberstamped by Geoff.
-
-        Turn off the profiler because it is a performance regression.
-
-        * kjs/config.h:
-
-2008-05-19  Alp Toker  <alp@nuanti.com>
-
-        Reviewed by Anders and Beth.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16495
-        [GTK] Accessibility support with ATK/AT-SPI
-
-        Initial ATK/AT-SPI accessibility support for the GTK+ port.
-
-        * wtf/Platform.h:
-
-2008-05-19  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        -In an effort to make the profiler as efficient as possible instead of
-        prepending to a vector we keep the vector in reverse order and operate
-        over it backwards.
-
-        * profiler/Profile.cpp:
-        (KJS::Profile::willExecute):
-        (KJS::Profile::didExecute):
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::didExecute):
-        (KJS::ProfileNode::endAndRecordCall):
-        * profiler/ProfileNode.h:
-        * profiler/Profiler.cpp:
-        (KJS::getStackNames):
-
-2008-05-16  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        Implement sorting for the profiler.
-        I chose to sort the profileNodes in place since there is no reason they
-        need to retain their original order.
-
-        * JavaScriptCore.exp: Export the symbols.
-        * profiler/Profile.h: Add the different ways a profile can be sorted.
-        (KJS::Profile::sortTotalTimeDescending):
-        (KJS::Profile::sortTotalTimeAscending):
-        (KJS::Profile::sortSelfTimeDescending):
-        (KJS::Profile::sortSelfTimeAscending):
-        (KJS::Profile::sortCallsDescending):
-        (KJS::Profile::sortCallsAscending):
-        * profiler/ProfileNode.cpp: Implement those ways.
-        (KJS::totalTimeDescendingComparator):
-        (KJS::ProfileNode::sortTotalTimeDescending):
-        (KJS::totalTimeAscendingComparator):
-        (KJS::ProfileNode::sortTotalTimeAscending):
-        (KJS::selfTimeDescendingComparator):
-        (KJS::ProfileNode::sortSelfTimeDescending):
-        (KJS::selfTimeAscendingComparator):
-        (KJS::ProfileNode::sortSelfTimeAscending):
-        (KJS::callsDescendingComparator):
-        (KJS::ProfileNode::sortCallsDescending):
-        (KJS::callsAscendingComparator):
-        (KJS::ProfileNode::sortCallsAscending):
-        * profiler/ProfileNode.h: No longer use a Deque since it cannot be
-        sorted by std::sort and there was no reason not to use a Vector.  I
-        previously had though I would do prepending but am not.
-        (KJS::ProfileNode::selfTime):
-        (KJS::ProfileNode::totalPercent):
-        (KJS::ProfileNode::selfPercent):
-        (KJS::ProfileNode::children):
-        * profiler/Profiler.cpp: Removed these functions as they can be called
-        directoy on the Profile object after getting the Vector of them.
-        (KJS::getStackNames):
-        * profiler/Profiler.h:
-
-2008-05-15  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Reviewed by Simon.
-
-        Since WebKitGtk is fully using autotools now, clean-up the .pro/.pri files
-        from gtk-port.
-
-        * JavaScriptCore.pro:
-        * kjs/testkjs.pro:
-
-2008-05-15  Kevin McCullough  <kmccullough@apple.com>
-
-        - Build fix.
-
-        * JavaScriptCore.exp:
-
-2008-05-15  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - Cache some values to save on computing them repetitively. This will be
-        a big savings when we sort since we won't have to walk the tree for
-        every comparison!
-        - We cache these values when we end profiling because otherwise we won't
-        know which profile to get the totalTime for the whole profile from without
-        retaining a reference to the head profile or looking up the profile from
-        the list of all profiles.
-        - Also it's safe to assume we won't be asked for these values while we
-        are still profiling since the WebInspector only get's profileNodes from
-        profiles that are in the allProfiles() list and a profile is only added
-        to that list after it has finished and these values will no longer
-        change.
-
-        * JavaScriptCore.exp:
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::ProfileNode):
-        (KJS::ProfileNode::stopProfiling):
-        (KJS::ProfileNode::printDataInspectorStyle):
-        (KJS::ProfileNode::printDataSampleStyle):
-        (KJS::ProfileNode::endAndRecordCall):
-        * profiler/ProfileNode.h:
-        (KJS::ProfileNode::totalTime):
-        (KJS::ProfileNode::selfTime):
-        (KJS::ProfileNode::totalPercent):
-        (KJS::ProfileNode::selfPercent):
-        * profiler/Profiler.cpp:
-        (KJS::Profiler::stopProfiling):
-
-2008-05-15  Simon Hausmann  <shausman@trolltech.com>
-
-        Reviewed by Holger.
-
-        Fix compilation when compiling with MSVC and wchar_t support.
-
-        * wtf/unicode/qt4/UnicodeQt4.h:
-        (WTF::Unicode::foldCase):
-        (WTF::Unicode::umemcasecmp):
-
-2008-05-14  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - Turn on the profiler.
-
-        * kjs/config.h:
-
-2008-05-14  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - Expose the new profiler functions to the WebInspector.
-
-        * JavaScriptCore.exp:
-
-2008-05-14  Kevin McCullough  <kmccullough@apple.com>
-
-        Giving credit where credit is due.
-
-        * ChangeLog:
-
-2008-05-14  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Geoff and Sam.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        Add the ability to get percentages of total and self time for displaying
-        in the WebInspector.
-
-        * profiler/Profile.h:
-        (KJS::Profile::totalProfileTime):
-        * profiler/ProfileNode.cpp:
-        (KJS::ProfileNode::totalPercent):
-        (KJS::ProfileNode::selfPercent):
-        * profiler/ProfileNode.h:
-        * profiler/Profiler.h:
-        (KJS::Profiler::currentProfile):
-
-2008-05-14  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - Rename FunctionCallProfile to ProfileNode.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.exp:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * profiler/FunctionCallProfile.cpp: Removed.
-        * profiler/FunctionCallProfile.h: Removed.
-        * profiler/Profile.cpp:
-        (KJS::Profile::Profile):
-        (KJS::Profile::willExecute):
-        * profiler/Profile.h:
-        (KJS::Profile::callTree):
-        * profiler/ProfileNode.cpp: Copied from profiler/FunctionCallProfile.cpp.
-        (KJS::ProfileNode::ProfileNode):
-        (KJS::ProfileNode::willExecute):
-        (KJS::ProfileNode::didExecute):
-        (KJS::ProfileNode::addChild):
-        (KJS::ProfileNode::findChild):
-        (KJS::ProfileNode::stopProfiling):
-        (KJS::ProfileNode::selfTime):
-        (KJS::ProfileNode::printDataInspectorStyle):
-        (KJS::ProfileNode::printDataSampleStyle):
-        (KJS::ProfileNode::endAndRecordCall):
-        * profiler/ProfileNode.h: Copied from profiler/FunctionCallProfile.h.
-        (KJS::ProfileNode::create):
-        (KJS::ProfileNode::children):
-        * profiler/Profiler.cpp:
-
-2008-05-14  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by John.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - Have each FunctionCallProfile be able to return it's total and self time.
-
-        * JavaScriptCore.exp:
-        * profiler/FunctionCallProfile.cpp:
-        (KJS::FunctionCallProfile::selfTime):
-        * profiler/FunctionCallProfile.h:
-        (KJS::FunctionCallProfile::totalTime):
-
-2008-05-14  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5934376> REGRESSION: A script fails because of a straw BOM character in it.
-
-        <https://bugs.webkit.org/show_bug.cgi?id=4931>
-        Unicode format characters (Cf) should be removed from JavaScript source
-
-        Of all Cf characters, we are only removing BOM, because this is what Firefox trunk has
-        settled upon, after extensive discussion and investigation.
-
-        Based on Darin's work on this bug.
-
-        Test: fast/js/removing-Cf-characters.html
-
-        * kjs/lexer.cpp:
-        (KJS::Lexer::setCode): Tweak formatting. Use a call to shift(4) to read in the
-        first characters, instead of having special case code here.
-        (KJS::Lexer::shift): Add a loop when reading a character to skip BOM characters.
-
-2008-05-13  Matt Lilek  <webkit@mattlilek.com>
-
-        Not reviewed, build fix.
-
-        * kjs/date_object.cpp:
-        (KJS::DateObjectFuncImp::callAsFunction):
-
-2008-05-13  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Sam.
-
-        <rdar://problem/5933644> Implement Date.now
-        
-        Implement Date.now which returns the number of milliseconds since the epoch.
-        
-        * kjs/CommonIdentifiers.h:
-        * kjs/date_object.cpp:
-        (KJS::DateObjectFuncImp::):
-        (KJS::DateObjectImp::DateObjectImp):
-        (KJS::DateObjectFuncImp::callAsFunction):
-
-2008-05-13  Kevin McCullough  <kmccullough@apple.com>
-
-        Giving credit where credit is due.
-
-        * ChangeLog:
-
-2008-05-13  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Adam and Geoff.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        Use PassRefPtrs instead of RefPtrs when appropriate.
-
-        * profiler/FunctionCallProfile.cpp:
-        (KJS::FunctionCallProfile::addChild):
-        * profiler/FunctionCallProfile.h:
-        * profiler/Profile.h:
-        (KJS::Profile::callTree):
-
-2008-05-13  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - Made some functions static (as per Adam) and changed from using raw
-        pointers to RefPtr for making these JavaScript Objects.
-
-        * profiler/FunctionCallProfile.cpp:
-        (KJS::FunctionCallProfile::addChild):
-        (KJS::FunctionCallProfile::findChild):
-        * profiler/FunctionCallProfile.h:
-        (KJS::FunctionCallProfile::create):
-        * profiler/Profile.cpp:
-        (KJS::Profile::Profile):
-        (KJS::Profile::willExecute):
-        (KJS::Profile::didExecute):
-        (KJS::functionNameCountPairComparator):
-        * profiler/Profile.h:
-        (KJS::Profile::create):
-        (KJS::Profile::title):
-        (KJS::Profile::callTree):
-        * profiler/Profiler.cpp:
-        (KJS::Profiler::startProfiling):
-        * profiler/Profiler.h:
-        (KJS::Profiler::allProfiles):
-        (KJS::Profiler::clearProfiles):
-
-2008-05-13  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        <rdar://problem/4949018> JavaScriptCore API claims to work with UTF8 strings, but only works
-        with ASCII strings
-        
-        * kjs/ustring.h:
-        * kjs/ustring.cpp:
-        (KJS::UString::Rep::createFromUTF8):
-        Added. Implementation adapted from JSStringCreateWithUTF8CString().
-
-        * API/JSStringRef.cpp:
-        (JSStringCreateWithUTF8CString):
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::OpaqueJSClass):
-        Use UString::Rep::createFromUTF8().
-
-2008-05-12  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Tim Hatcher.
-
-        <rdar://problem/4859666> WebKit needs availability macros in order to deprecate APIs
-
-        Create WebKit availability macros that key off the Mac OS X version being targeted to
-        determine the WebKit version being targeted.  Applications can define
-        WEBKIT_VERSION_MIN_REQUIRED before including WebKit headers in order to target a specific
-        version of WebKit.
-
-        The availability header is being added to JavaScriptCore rather than WebKit as JavaScriptCore
-        is the lowest-level portion of the public WebKit API.
-
-        * API/WebKitAvailability.h: Added.
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-05-12  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Maciej.
-
-        https://bugs.webkit.org/show_bug.cgi?id=18828
-        Reproducible crash with PAC file
-
-        Naively moving JavaScriptCore into thread-specific data was inappropriate in the face of
-        exiting JavaScriptCore API clients, which expect a different therading model. Temporarily
-        disabling ThreadSpecific implementation until this can be sorted out.
-
-        * wtf/ThreadSpecific.h:
-        (WTF::::ThreadSpecific):
-        (WTF::::~ThreadSpecific):
-        (WTF::::get):
-        (WTF::::set):
-
-2008-05-12  Alexey Proskuryakov  <ap@webkit.org>
-
-        Roll out recent  threading changes (r32807, r32810, r32819, r32822) to simplify
-        SquirrelFish merging.
-
-        * API/JSBase.cpp:
-        (JSGarbageCollect):
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::staticFunctionGetter):
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::prototype):
-        * API/JSObjectRef.cpp:
-        (JSObjectMake):
-        (JSObjectMakeFunctionWithCallback):
-        (JSObjectMakeConstructor):
-        (JSObjectMakeFunction):
-        * API/JSValueRef.cpp:
-        (JSValueMakeNumber):
-        (JSValueMakeString):
-        * JavaScriptCore.exp:
-        * kjs/ExecState.h:
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreadingOnce):
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::~JSGlobalObject):
-        (KJS::JSGlobalObject::init):
-        (KJS::JSGlobalObject::put):
-        (KJS::JSGlobalObject::reset):
-        (KJS::JSGlobalObject::tearOffActivation):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::head):
-        (KJS::JSGlobalObject::perThreadData):
-        * kjs/JSLock.cpp:
-        (KJS::JSLock::registerThread):
-        * kjs/JSLock.h:
-        (KJS::JSLock::JSLock):
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::ArrayInstance):
-        (KJS::ArrayInstance::lengthGetter):
-        * kjs/array_object.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::ArrayObjectImp::ArrayObjectImp):
-        (KJS::ArrayObjectImp::construct):
-        * kjs/bool_object.cpp:
-        (KJS::BooleanPrototype::BooleanPrototype):
-        (KJS::booleanProtoFuncToString):
-        (KJS::BooleanObjectImp::BooleanObjectImp):
-        (KJS::BooleanObjectImp::construct):
-        * kjs/collector.cpp:
-        (KJS::allocateBlock):
-        (KJS::Collector::recordExtraCost):
-        (KJS::Collector::heapAllocate):
-        (KJS::Collector::allocate):
-        (KJS::Collector::allocateNumber):
-        (KJS::Collector::registerAsMainThread):
-        (KJS::onMainThread):
-        (KJS::PlatformThread::PlatformThread):
-        (KJS::getCurrentPlatformThread):
-        (KJS::Collector::Thread::Thread):
-        (KJS::destroyRegisteredThread):
-        (KJS::initializeRegisteredThreadKey):
-        (KJS::Collector::registerThread):
-        (KJS::Collector::markStackObjectsConservatively):
-        (KJS::Collector::markCurrentThreadConservativelyInternal):
-        (KJS::Collector::markCurrentThreadConservatively):
-        (KJS::suspendThread):
-        (KJS::resumeThread):
-        (KJS::getPlatformThreadRegisters):
-        (KJS::otherThreadStackPointer):
-        (KJS::Collector::markOtherThreadConservatively):
-        (KJS::protectedValues):
-        (KJS::Collector::protect):
-        (KJS::Collector::unprotect):
-        (KJS::Collector::collectOnMainThreadOnly):
-        (KJS::Collector::markProtectedObjects):
-        (KJS::Collector::markMainThreadOnlyObjects):
-        (KJS::Collector::sweep):
-        (KJS::Collector::collect):
-        (KJS::Collector::size):
-        (KJS::Collector::globalObjectCount):
-        (KJS::Collector::protectedGlobalObjectCount):
-        (KJS::Collector::protectedObjectCount):
-        (KJS::Collector::protectedObjectTypeCounts):
-        (KJS::Collector::isBusy):
-        (KJS::Collector::reportOutOfMemoryToAllExecStates):
-        * kjs/collector.h:
-        (KJS::Collector::cellBlock):
-        (KJS::Collector::cellOffset):
-        (KJS::Collector::isCellMarked):
-        (KJS::Collector::markCell):
-        (KJS::Collector::reportExtraMemoryCost):
-        * kjs/date_object.cpp:
-        (KJS::formatLocaleDate):
-        (KJS::DatePrototype::DatePrototype):
-        (KJS::DateObjectImp::DateObjectImp):
-        (KJS::DateObjectImp::construct):
-        (KJS::DateObjectImp::callAsFunction):
-        (KJS::DateObjectFuncImp::DateObjectFuncImp):
-        (KJS::DateObjectFuncImp::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::ErrorObjectImp::ErrorObjectImp):
-        (KJS::ErrorObjectImp::construct):
-        (KJS::NativeErrorPrototype::NativeErrorPrototype):
-        (KJS::NativeErrorImp::NativeErrorImp):
-        (KJS::NativeErrorImp::construct):
-        * kjs/function.cpp:
-        (KJS::FunctionImp::lengthGetter):
-        (KJS::FunctionImp::construct):
-        (KJS::Arguments::Arguments):
-        (KJS::ActivationImp::createArgumentsObject):
-        (KJS::encode):
-        (KJS::decode):
-        (KJS::globalFuncParseInt):
-        (KJS::globalFuncParseFloat):
-        (KJS::globalFuncEscape):
-        (KJS::globalFuncUnescape):
-        (KJS::PrototypeFunction::PrototypeFunction):
-        (KJS::PrototypeReflexiveFunction::PrototypeReflexiveFunction):
-        * kjs/function_object.cpp:
-        (KJS::FunctionPrototype::FunctionPrototype):
-        (KJS::functionProtoFuncToString):
-        (KJS::FunctionObjectImp::FunctionObjectImp):
-        (KJS::FunctionObjectImp::construct):
-        * kjs/internal.cpp:
-        (KJS::StringImp::toObject):
-        * kjs/internal.h:
-        (KJS::StringImp::StringImp):
-        (KJS::NumberImp::operator new):
-        * kjs/list.cpp:
-        (KJS::List::markSet):
-        (KJS::List::markProtectedListsSlowCase):
-        (KJS::List::expandAndAppend):
-        * kjs/list.h:
-        (KJS::List::List):
-        (KJS::List::~List):
-        (KJS::List::markProtectedLists):
-        * kjs/lookup.h:
-        (KJS::staticFunctionGetter):
-        (KJS::cacheGlobalObject):
-        * kjs/math_object.cpp:
-        (KJS::MathObjectImp::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/nodes.cpp:
-        (KJS::ParserRefCounted::ParserRefCounted):
-        (KJS::ParserRefCounted::ref):
-        (KJS::ParserRefCounted::deref):
-        (KJS::ParserRefCounted::refcount):
-        (KJS::ParserRefCounted::deleteNewObjects):
-        (KJS::Node::handleException):
-        (KJS::NumberNode::evaluate):
-        (KJS::StringNode::evaluate):
-        (KJS::ArrayNode::evaluate):
-        (KJS::PostIncResolveNode::evaluate):
-        (KJS::PostIncLocalVarNode::evaluate):
-        (KJS::PostDecResolveNode::evaluate):
-        (KJS::PostDecLocalVarNode::evaluate):
-        (KJS::PostDecLocalVarNode::inlineEvaluateToNumber):
-        (KJS::PostIncBracketNode::evaluate):
-        (KJS::PostDecBracketNode::evaluate):
-        (KJS::PostIncDotNode::evaluate):
-        (KJS::PostDecDotNode::evaluate):
-        (KJS::typeStringForValue):
-        (KJS::LocalVarTypeOfNode::evaluate):
-        (KJS::TypeOfResolveNode::evaluate):
-        (KJS::TypeOfValueNode::evaluate):
-        (KJS::PreIncLocalVarNode::evaluate):
-        (KJS::PreIncResolveNode::evaluate):
-        (KJS::PreDecLocalVarNode::evaluate):
-        (KJS::PreDecResolveNode::evaluate):
-        (KJS::PreIncConstNode::evaluate):
-        (KJS::PreDecConstNode::evaluate):
-        (KJS::PostIncConstNode::evaluate):
-        (KJS::PostDecConstNode::evaluate):
-        (KJS::PreIncBracketNode::evaluate):
-        (KJS::PreDecBracketNode::evaluate):
-        (KJS::PreIncDotNode::evaluate):
-        (KJS::PreDecDotNode::evaluate):
-        (KJS::NegateNode::evaluate):
-        (KJS::BitwiseNotNode::evaluate):
-        (KJS::MultNode::evaluate):
-        (KJS::DivNode::evaluate):
-        (KJS::ModNode::evaluate):
-        (KJS::addSlowCase):
-        (KJS::add):
-        (KJS::AddNumbersNode::evaluate):
-        (KJS::AddStringsNode::evaluate):
-        (KJS::AddStringLeftNode::evaluate):
-        (KJS::AddStringRightNode::evaluate):
-        (KJS::SubNode::evaluate):
-        (KJS::LeftShiftNode::evaluate):
-        (KJS::RightShiftNode::evaluate):
-        (KJS::UnsignedRightShiftNode::evaluate):
-        (KJS::BitXOrNode::evaluate):
-        (KJS::BitOrNode::evaluate):
-        (KJS::valueForReadModifyAssignment):
-        (KJS::ForInNode::execute):
-        (KJS::TryNode::execute):
-        (KJS::FuncDeclNode::makeFunction):
-        (KJS::FuncExprNode::evaluate):
-        * kjs/nodes.h:
-        * kjs/number_object.cpp:
-        (KJS::NumberPrototype::NumberPrototype):
-        (KJS::numberProtoFuncToString):
-        (KJS::numberProtoFuncToLocaleString):
-        (KJS::numberProtoFuncToFixed):
-        (KJS::numberProtoFuncToExponential):
-        (KJS::numberProtoFuncToPrecision):
-        (KJS::NumberObjectImp::NumberObjectImp):
-        (KJS::NumberObjectImp::getValueProperty):
-        (KJS::NumberObjectImp::construct):
-        (KJS::NumberObjectImp::callAsFunction):
-        * kjs/object.cpp:
-        (KJS::JSObject::call):
-        (KJS::JSObject::get):
-        (KJS::JSObject::put):
-        (KJS::JSObject::defineGetter):
-        (KJS::JSObject::defineSetter):
-        (KJS::JSObject::putDirect):
-        (KJS::Error::create):
-        * kjs/object.h:
-        * kjs/object_object.cpp:
-        (KJS::ObjectPrototype::ObjectPrototype):
-        (KJS::objectProtoFuncToLocaleString):
-        (KJS::objectProtoFuncToString):
-        (KJS::ObjectObjectImp::ObjectObjectImp):
-        (KJS::ObjectObjectImp::construct):
-        * kjs/property_map.h:
-        (KJS::SavedProperty::SavedProperty):
-        (KJS::SavedProperty::init):
-        (KJS::SavedProperty::~SavedProperty):
-        (KJS::SavedProperty::name):
-        (KJS::SavedProperty::value):
-        (KJS::SavedProperty::attributes):
-        * kjs/protect.h:
-        (KJS::gcProtect):
-        (KJS::gcUnprotect):
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpPrototype::RegExpPrototype):
-        (KJS::regExpProtoFuncToString):
-        (KJS::RegExpImp::getValueProperty):
-        (KJS::RegExpObjectImp::RegExpObjectImp):
-        (KJS::RegExpObjectImp::arrayOfMatches):
-        (KJS::RegExpObjectImp::getBackref):
-        (KJS::RegExpObjectImp::getLastParen):
-        (KJS::RegExpObjectImp::getLeftContext):
-        (KJS::RegExpObjectImp::getRightContext):
-        (KJS::RegExpObjectImp::getValueProperty):
-        (KJS::RegExpObjectImp::createRegExpImp):
-        * kjs/regexp_object.h:
-        * kjs/string_object.cpp:
-        (KJS::StringInstance::StringInstance):
-        (KJS::StringInstance::lengthGetter):
-        (KJS::StringInstance::indexGetter):
-        (KJS::stringInstanceNumericPropertyGetter):
-        (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::StringObjectImp::StringObjectImp):
-        (KJS::StringObjectImp::construct):
-        (KJS::StringObjectImp::callAsFunction):
-        (KJS::StringObjectFuncImp::StringObjectFuncImp):
-        (KJS::StringObjectFuncImp::callAsFunction):
-        * kjs/string_object.h:
-        (KJS::StringInstanceThatMasqueradesAsUndefined::StringInstanceThatMasqueradesAsUndefined):
-        * kjs/testkjs.cpp:
-        (GlobalObject::GlobalObject):
-        (functionGC):
-        (functionRun):
-        (functionReadline):
-        (kjsmain):
-        * kjs/ustring.h:
-        * kjs/value.cpp:
-        (KJS::JSCell::operator new):
-        (KJS::jsString):
-        (KJS::jsOwnedString):
-        (KJS::jsNumberCell):
-        * kjs/value.h:
-        (KJS::jsNaN):
-        (KJS::jsNumber):
-        (KJS::jsNumberFromAnd):
-        (KJS::JSCell::marked):
-        (KJS::JSCell::mark):
-        (KJS::JSValue::toJSNumber):
-        * wtf/ThreadSpecific.h:
-        (WTF::T):
-
-2008-05-10  Julien Chaffraix  <jchaffraix@webkit.org>
-
-        Qt & wx build fix.
-
-        * JavaScriptCore.pri: Add profiler/Profile.cpp.
-        * JavaScriptCoreSources.bkl: Ditto.
-
-2008-05-10  Jan Michael Alonzo  <jmalonzo@unpluggable.com>
-
-        Reviewed by Maciej.
-
-        Gtk+ build fix
-
-        * GNUmakefile.am: Add Profile.cpp in _sources
-
-2008-05-09  Brady Eidson  <beidson@apple.com>
-
-        Build Fix.  Kevin is an idiot.  
-        ("My name is Kevin McCullough and I approve this message.")
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-05-09  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Tim.
-
-        -<rdar://problem/5770054> JavaScript profiler (10928)
-        -Add Profile class so that all profiles can be stored and retrieved by
-        the WebInspector when that time comes.
-
-        * JavaScriptCore.exp: Export the new function signatures.
-        * JavaScriptCore.xcodeproj/project.pbxproj: Add the new files to the
-        project
-        * profiler/Profile.cpp: Added. This class represents a single run of the
-        profiler.
-        (KJS::Profile::Profile):
-        (KJS::Profile::willExecute):
-        (KJS::Profile::didExecute):
-        (KJS::Profile::printDataInspectorStyle):
-        (KJS::functionNameCountPairComparator):
-        (KJS::Profile::printDataSampleStyle):
-        * profiler/Profile.h: Added. Ditto
-        (KJS::Profile::stopProfiling):
-        * profiler/Profiler.cpp: Now the profiler keeps track of many profiles
-        but only runs one at a time.
-        (KJS::Profiler::startProfiling):
-        (KJS::Profiler::stopProfiling):
-        (KJS::Profiler::willExecute):
-        (KJS::Profiler::didExecute):
-        (KJS::Profiler::printDataInspectorStyle):
-        (KJS::Profiler::printDataSampleStyle):
-        * profiler/Profiler.h: Ditto.
-        (KJS::Profiler::~Profiler):
-        (KJS::Profiler::allProfiles):
-        (KJS::Profiler::clearProfiles):
-
-2008-05-08  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Mark.
-
-        Enable NPAPI plug-ins on 64-bit.
-        
-        * wtf/Platform.h:
-
-2008-05-07  Julien Chaffraix  <jchaffraix@webkit.org>
-
-        Reviewed by Adam Roben.
-
-        wx & Gtk build fix.
-
-        Add SIZE_MAX definition for the wx port.
-
-        * os-win32/stdint.h:
-
-2008-05-07  Ariya Hidayat  <ariya.hidayat@trolltech.com>
-
-        Reviewed by Simon.
-
-        Support for isMainThread in the Qt port.
-
-        * wtf/ThreadingQt.cpp:
-        (WTF::initializeThreading): Adjusted.
-        (WTF::isMainThread): Added.
-
-2008-05-05  Darin Adler  <darin@apple.com>
-
-        Reviewed by John Sullivan.
-
-        - fix debug-only leak seen on buildbot
-
-        * wtf/HashTable.h:
-        (WTF::HashTable::checkKey): After writing an empty value in, but before constructing a
-        deleted value on top of it, call the destructor so the empty value doesn't leak.
-
-2008-05-02  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Get rid of static data in nodes.cpp (well, at least of non-debug one).
-
-        No measurable change on SunSpider.
-
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreadingOnce):
-        * kjs/nodes.cpp:
-        (KJS::newTrackedObjects):
-        (KJS::trackedObjectExtraRefCounts):
-        (KJS::initializeNodesThreading):
-        (KJS::ParserRefCounted::ParserRefCounted):
-        (KJS::ParserRefCounted::ref):
-        (KJS::ParserRefCounted::deref):
-        (KJS::ParserRefCounted::refcount):
-        (KJS::ParserRefCounted::deleteNewObjects):
-        * kjs/nodes.h:
-        Made newTrackedObjects and trackedObjectExtraRefCounts per-thread.
-
-2008-05-02  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Move call stack depth counter to global object.
-
-        * kjs/ExecState.h: (KJS::ExecState::functionCallDepth): Added a recursion depth counter to
-        per-thread data.
-        * kjs/JSGlobalObject.cpp: (KJS::JSGlobalObject::init): Initialize PerThreadData.functionCallDepth.
-        * kjs/JSGlobalObject.h: (KJS::JSGlobalObject::perThreadData): Made the result non-const.
-
-        * kjs/object.cpp:
-        (KJS::throwStackSizeExceededError): Moved throwError to a separate function, since it is now
-        the only thing in JSObject::call that needs a PIC branch.
-        (KJS::JSObject::call): Use a per-thread variable instead of local static for recursion depth
-        tracking.
-
-2008-05-02  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Make JavaScriptGlue and JavaScriptCore API functions implicitly call initializeThreading
-        for the sake of non-WebKit clients.
-
-        * API/JSBase.cpp:
-        (JSGarbageCollect):
-        * API/JSContextRef.cpp:
-        (JSGlobalContextCreate):
-        These are the JavaScriptCore API bottlenecks. There are a few other JSStringRef
-        and JSClassRef functions that can be called earlier, but they do not do anything that
-        requires initializeThreading.
-
-        * kjs/InitializeThreading.cpp:
-        (KJS::doInitializeThreading):
-        (KJS::initializeThreading):
-        On Darwin, make the initialization happen under pthread_once, since there is no guarantee
-        that non-WebKit clients won't try to call this function re-entrantly.
-
-        * kjs/InitializeThreading.h:
-        * wtf/Threading.h:
-        Spell out initializeThreading contract.
-
-        * wtf/ThreadingPthreads.cpp: (WTF::isMainThread): Make sure that results are correct on
-        Darwin, even if threading was initialized from a secondary thread.
-
-2008-05-02  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        https://bugs.webkit.org/show_bug.cgi?id=18826
-        Make JavaScript heap per-thread
-
-        * wtf/ThreadSpecific.h: Make sure to initialize POD thread-specific varaibles, too
-        (replaced "new T" with "new T()").
-
-        * kjs/collector.h: Renamed Collector to Heap, made the heap per-thread. Removed support for
-        multithreaded access to a heap.
-        (KJS::CollectorBlock): Removed collectOnMainThreadOnly bitmap, added a reference to owner heap.
-        (KJS::SmallCellCollectorBlock): Ditto.
-        (KJS::Heap::markListSet): Moved from a static variable in List.cpp to a per-thread one here.
-        (KJS::Heap::heap): Added a method to find which heap a JSValue is allocated in.
-
-        * kjs/collector.cpp: Changed "const size_t" constants to #defines, to avoid a PIC branch
-        (gcc was using one to access a constant used in std::max(), because it takes a reference,
-        even though std::max() itself was inlined).
-        (KJS::Heap::threadHeap): JS heap is now per-thread.
-        (KJS::Heap::Heap): Zero-initialize the heap.
-        (KJS::allocateBlock): Added NEVER_INLINE, because this function uses a PIC branch, so
-        inlining it in Heap::heapAllocate() is bad for performance, now that the latter doesn't
-        use any global data.
-        (KJS::Heap::heapAllocate): Initialize Block::heap.
-        (KJS::Heap::markCurrentThreadConservatively): Moved into markStackObjectsConservatively(),
-        as GC only works with a current thread's heap now.
-        (KJS::Heap::sweep): Removed collectOnMainThreadOnly checks.
-        (KJS::Heap::collect): Ditto.
-
-        * kjs/JSLock.cpp:
-        * kjs/JSLock.h:
-        (KJS::JSLock::JSLock):
-        Removed registerThread(), as the heap no longer cares.
-
-        * kjs/InitializeThreading.cpp: (KJS::initializeThreading): Initialize new per-thread
-        variables in Heap and JSGlobalObject.
-
-        * kjs/ExecState.h: (KJS::ExecState::heap): Added a heap pointer for faster access to
-        per-thread heap, and an accessor for it.
-
-        * kjs/JSGlobalObject.h: Made JSGlobalObject linked list per-thread.
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::~JSGlobalObject): Fixed a bug in linked list handling. It only worked
-        right if the removed object was the head one!
-        (KJS::JSGlobalObject::head): Return a per-thread list head.
-        (KJS::JSGlobalObject::init): Store a reference to per-thread heap.
-        (KJS::JSGlobalObject::reset): Pass ExecState to functions that need it.
-        (KJS::JSGlobalObject::tearOffActivation): Ditto.
-        (KJS::JSGlobalObject::operator new): JSGlobalObject allocation cannot use an ExecState,
-        so it needs a custom operator new that directly accesses per-thread heap.
-
-        * kjs/list.h:
-        (KJS::List::List): Replaced m_isInMarkSet boolean with an actual pointer to the set, since it
-        is no longer a single static object.
-        (KJS::List::~List): Ditto.
-        * kjs/list.cpp:
-        (KJS::List::markSet): Removed, this is now stored in Heap.
-        (KJS::List::markProtectedLists): Take a reference to the list.
-        (KJS::List::expandAndAppend): Ask the current thread heap for a mark set reference.
-
-        * kjs/protect.h:
-        (KJS::gcProtect):
-        (KJS::gcUnprotect):
-        Use the newly added Heap::heap() method to find out which heap the value to be (un)protected
-        belongs to.
-
-        * kjs/property_map.h: Removed unused SavedProperty class.
-
-        * JavaScriptCore.exp:
-        * API/JSBase.cpp:
-        (JSGarbageCollect):
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::staticFunctionGetter):
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::prototype):
-        * API/JSObjectRef.cpp:
-        (JSObjectMake):
-        (JSObjectMakeFunctionWithCallback):
-        (JSObjectMakeConstructor):
-        (JSObjectMakeFunction):
-        * API/JSValueRef.cpp:
-        (JSValueMakeNumber):
-        (JSValueMakeString):
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::ArrayInstance):
-        (KJS::ArrayInstance::lengthGetter):
-        * kjs/array_object.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::ArrayObjectImp::ArrayObjectImp):
-        (KJS::ArrayObjectImp::construct):
-        * kjs/bool_object.cpp:
-        (KJS::BooleanPrototype::BooleanPrototype):
-        (KJS::booleanProtoFuncToString):
-        (KJS::BooleanObjectImp::BooleanObjectImp):
-        (KJS::BooleanObjectImp::construct):
-        * kjs/date_object.cpp:
-        (KJS::formatLocaleDate):
-        (KJS::DatePrototype::DatePrototype):
-        (KJS::DateObjectImp::DateObjectImp):
-        (KJS::DateObjectImp::construct):
-        (KJS::DateObjectImp::callAsFunction):
-        (KJS::DateObjectFuncImp::DateObjectFuncImp):
-        (KJS::DateObjectFuncImp::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::ErrorObjectImp::ErrorObjectImp):
-        (KJS::ErrorObjectImp::construct):
-        (KJS::NativeErrorPrototype::NativeErrorPrototype):
-        (KJS::NativeErrorImp::NativeErrorImp):
-        (KJS::NativeErrorImp::construct):
-        * kjs/function.cpp:
-        (KJS::FunctionImp::lengthGetter):
-        (KJS::FunctionImp::construct):
-        (KJS::Arguments::Arguments):
-        (KJS::ActivationImp::createArgumentsObject):
-        (KJS::encode):
-        (KJS::decode):
-        (KJS::globalFuncParseInt):
-        (KJS::globalFuncParseFloat):
-        (KJS::globalFuncEscape):
-        (KJS::globalFuncUnescape):
-        (KJS::PrototypeFunction::PrototypeFunction):
-        (KJS::PrototypeReflexiveFunction::PrototypeReflexiveFunction):
-        * kjs/function_object.cpp:
-        (KJS::FunctionPrototype::FunctionPrototype):
-        (KJS::functionProtoFuncToString):
-        (KJS::FunctionObjectImp::FunctionObjectImp):
-        (KJS::FunctionObjectImp::construct):
-        * kjs/internal.cpp:
-        (KJS::StringImp::toObject):
-        * kjs/internal.h:
-        (KJS::StringImp::StringImp):
-        (KJS::NumberImp::operator new):
-        * kjs/lookup.h:
-        (KJS::staticFunctionGetter):
-        (KJS::cacheGlobalObject):
-        * kjs/math_object.cpp:
-        (KJS::MathObjectImp::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/nodes.cpp:
-        (KJS::Node::handleException):
-        (KJS::NumberNode::evaluate):
-        (KJS::StringNode::evaluate):
-        (KJS::ArrayNode::evaluate):
-        (KJS::PostIncResolveNode::evaluate):
-        (KJS::PostIncLocalVarNode::evaluate):
-        (KJS::PostDecResolveNode::evaluate):
-        (KJS::PostDecLocalVarNode::evaluate):
-        (KJS::PostDecLocalVarNode::inlineEvaluateToNumber):
-        (KJS::PostIncBracketNode::evaluate):
-        (KJS::PostDecBracketNode::evaluate):
-        (KJS::PostIncDotNode::evaluate):
-        (KJS::PostDecDotNode::evaluate):
-        (KJS::typeStringForValue):
-        (KJS::LocalVarTypeOfNode::evaluate):
-        (KJS::TypeOfResolveNode::evaluate):
-        (KJS::TypeOfValueNode::evaluate):
-        (KJS::PreIncLocalVarNode::evaluate):
-        (KJS::PreIncResolveNode::evaluate):
-        (KJS::PreDecLocalVarNode::evaluate):
-        (KJS::PreDecResolveNode::evaluate):
-        (KJS::PreIncConstNode::evaluate):
-        (KJS::PreDecConstNode::evaluate):
-        (KJS::PostIncConstNode::evaluate):
-        (KJS::PostDecConstNode::evaluate):
-        (KJS::PreIncBracketNode::evaluate):
-        (KJS::PreDecBracketNode::evaluate):
-        (KJS::PreIncDotNode::evaluate):
-        (KJS::PreDecDotNode::evaluate):
-        (KJS::NegateNode::evaluate):
-        (KJS::BitwiseNotNode::evaluate):
-        (KJS::MultNode::evaluate):
-        (KJS::DivNode::evaluate):
-        (KJS::ModNode::evaluate):
-        (KJS::addSlowCase):
-        (KJS::add):
-        (KJS::AddNumbersNode::evaluate):
-        (KJS::AddStringsNode::evaluate):
-        (KJS::AddStringLeftNode::evaluate):
-        (KJS::AddStringRightNode::evaluate):
-        (KJS::SubNode::evaluate):
-        (KJS::LeftShiftNode::evaluate):
-        (KJS::RightShiftNode::evaluate):
-        (KJS::UnsignedRightShiftNode::evaluate):
-        (KJS::BitXOrNode::evaluate):
-        (KJS::BitOrNode::evaluate):
-        (KJS::valueForReadModifyAssignment):
-        (KJS::ForInNode::execute):
-        (KJS::TryNode::execute):
-        (KJS::FuncDeclNode::makeFunction):
-        (KJS::FuncExprNode::evaluate):
-        * kjs/number_object.cpp:
-        (KJS::NumberPrototype::NumberPrototype):
-        (KJS::numberProtoFuncToString):
-        (KJS::numberProtoFuncToLocaleString):
-        (KJS::numberProtoFuncToFixed):
-        (KJS::numberProtoFuncToExponential):
-        (KJS::numberProtoFuncToPrecision):
-        (KJS::NumberObjectImp::NumberObjectImp):
-        (KJS::NumberObjectImp::getValueProperty):
-        (KJS::NumberObjectImp::construct):
-        (KJS::NumberObjectImp::callAsFunction):
-        * kjs/object.cpp:
-        (KJS::JSObject::defineGetter):
-        (KJS::JSObject::defineSetter):
-        (KJS::JSObject::putDirect):
-        (KJS::Error::create):
-        * kjs/object.h:
-        * kjs/object_object.cpp:
-        (KJS::ObjectPrototype::ObjectPrototype):
-        (KJS::objectProtoFuncToLocaleString):
-        (KJS::objectProtoFuncToString):
-        (KJS::ObjectObjectImp::ObjectObjectImp):
-        (KJS::ObjectObjectImp::construct):
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpPrototype::RegExpPrototype):
-        (KJS::regExpProtoFuncToString):
-        (KJS::RegExpImp::getValueProperty):
-        (KJS::RegExpObjectImp::RegExpObjectImp):
-        (KJS::RegExpObjectImp::arrayOfMatches):
-        (KJS::RegExpObjectImp::getBackref):
-        (KJS::RegExpObjectImp::getLastParen):
-        (KJS::RegExpObjectImp::getLeftContext):
-        (KJS::RegExpObjectImp::getRightContext):
-        (KJS::RegExpObjectImp::getValueProperty):
-        (KJS::RegExpObjectImp::createRegExpImp):
-        * kjs/regexp_object.h:
-        * kjs/string_object.cpp:
-        (KJS::StringInstance::StringInstance):
-        (KJS::StringInstance::lengthGetter):
-        (KJS::StringInstance::indexGetter):
-        (KJS::stringInstanceNumericPropertyGetter):
-        (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::StringObjectImp::StringObjectImp):
-        (KJS::StringObjectImp::construct):
-        (KJS::StringObjectImp::callAsFunction):
-        (KJS::StringObjectFuncImp::StringObjectFuncImp):
-        (KJS::StringObjectFuncImp::callAsFunction):
-        * kjs/string_object.h:
-        (KJS::StringInstanceThatMasqueradesAsUndefined::StringInstanceThatMasqueradesAsUndefined):
-        * kjs/testkjs.cpp:
-        (GlobalObject::GlobalObject):
-        (functionGC):
-        (functionRun):
-        (functionReadline):
-        (kjsmain):
-        * kjs/ustring.h:
-        * kjs/value.cpp:
-        (KJS::JSCell::operator new):
-        (KJS::jsString):
-        (KJS::jsOwnedString):
-        (KJS::jsNumberCell):
-        * kjs/value.h:
-        (KJS::jsNaN):
-        (KJS::jsNumber):
-        (KJS::jsNumberFromAnd):
-        (KJS::JSCell::marked):
-        (KJS::JSCell::mark):
-        (KJS::JSValue::toJSNumber):
-        Removed collectOnMainThreadOnly, as this is the only way to collect now. Replaced calls to
-        static Collector methods with calls to per-thread Heap ones.
-
-2008-05-02  Dan Bernstein  <mitz@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        - Mac build fix
-
-        * wtf/StrHash.h: Added header guards and removed #include "config.h".
-
-2008-05-01  Ada Chan  <adachan@apple.com>
-
-        #include <wtf/StrHash.h> in identifier.cpp.
-
-        Reviewed by Maciej.
-
-        * kjs/identifier.cpp:
-
-2008-05-01  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-05-01  Sam Weinig  <sam@webkit.org>
-
-        Fix build.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-05-01  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - Fix "sample" output so that it can be imported into Instruments
-        - Also keep track of number of times a function is profiled.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Add StrHash.h which needed
-        to be pulled out of identifier.cpp so that it could be used by the
-        profiler and identifiers.
-        * kjs/identifier.cpp: Ditto.
-        * profiler/FunctionCallProfile.cpp:
-        (KJS::FunctionCallProfile::printDataInspectorStyle): Inspector style
-        printing should show microseconds.
-        (KJS::FunctionCallProfile::printDataSampleStyle): Sample style printing
-        now counts the number of times a function is in the stack tree and does
-        not print microseconds since that does not make sense for a sampler.
-        * profiler/FunctionCallProfile.h: Keep track of number of times a
-        function is profiled.
-        (KJS::FunctionCallProfile::numberOfCalls):
-        * profiler/Profiler.cpp:
-        (KJS::functionNameCountPairComparator): Comparator for sort function in
-        printDataSampleStyle.
-        (KJS::Profiler::printDataSampleStyle): Print the number of times that a
-        function is listed in the stack tree in order of most times listed.
-        * wtf/HashCountedSet.h: Added copyToVector since it didn't exist and is
-        a more standard way to copy a HashSet to a Vector. I added on variant
-        that takes a pair as the Vector's type and so the HashCountedSet simply
-        fills in that pair with its internal pair, and another variant that
-        takes a Vector of the type of the HashCountedSet and only fills in the
-        Vector with the first element of the pair.
-        (WTF::copyToVector):
-        * wtf/StrHash.h: Added.
-        (WTF::):
-
-2008-04-29  David Kilzer  <ddkilzer@apple.com>
-
-        BUILD FIX for ENABLE(DASHBOARD_SUPPORT)
-
-        * wtf/Platform.h: Defined ENABLE(DASHBOARD_SUPPORT) to 1 only for
-        PLATFORM(MAC) and PLATFORM(WIN).  Changed default to 0 for other
-        ports.
-
-2008-04-29  Greg Bolsinga  <bolsinga@apple.com>
-
-        Reviewed by Darin.
-
-        Wrapped Dashboard code with ENABLE(DASHBOARD_SUPPORT)
-
-        * wtf/Platform.h:
-
-2008-04-29  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Geoff.
-
-        -<rdar://problem/5770054> JavaScript profiler (10928)
-        -Keep call count.
-
-        * profiler/FunctionCallProfile.cpp:
-        (KJS::FunctionCallProfile::FunctionCallProfile):
-        (KJS::FunctionCallProfile::didExecute): Implements call count and fixed a bug where a stackIndex
-        of 0 was causing the assert to be hit.
-        (KJS::FunctionCallProfile::stopProfiling):
-        (KJS::FunctionCallProfile::endAndRecordCall):
-        * profiler/FunctionCallProfile.h:
-
-2008-04-29  Simon Hausmann  <hausmann@webkit.org>
-
-        Qt/Windows build fix. The externally declared hash tables are actually
-        declared const and the const is mangled in the symbol name, so when
-        importing they also need to be marked const.
-
-        When compiling without MULTIPLE_THREADS use a const HashTable&
-        instead of a HashTable& in ThreadClassInfoHashTables to avoid
-        initializing the latter with a const reference.
-
-        * kjs/JSGlobalObject.cpp:
-
-2008-04-28  Alexey Proskuryakov  <ap@webkit.org>
-
-        Windows build fix.
-
-        * kjs/ExecState.h: For whatever reason, MSVC couldn't generate a default constructor for
-        a struct that had a "const List" member. Removing the const qulifier makes the problem go away.
-
-2008-04-28  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Fix run-webkit-tests --threading
-        and provisionally fix <https://bugs.webkit.org/show_bug.cgi?id=18661>
-        Proxy server issue in Sunday's Nightly
-
-        Changed ClassInfo objects for built-in objects to hold a getter function returning
-        a per-thread instance. This makes it safe to share these ClassInfo objects between threads -
-        and these are the only ones that need to be shared.
-
-        * kjs/lexer.cpp:
-        (KJS::Lexer::Lexer):
-        (KJS::Lexer::~Lexer):
-        * kjs/lexer.h:
-        Made mainTable a member of Lexer, so that it no longer needs to be shared between threads.
-
-        * kjs/object.cpp:
-        (KJS::JSObject::deleteProperty):
-        (KJS::JSObject::findPropertyHashEntry):
-        (KJS::JSObject::propertyIsEnumerable):
-        (KJS::JSObject::getPropertyAttributes):
-        (KJS::JSObject::getPropertyNames):
-        * kjs/object.h:
-        (KJS::ClassInfo::propHashTable):
-        Added a new classPropHashTableGetterFunction field to ClassInfo. If it is non-zero, the
-        static table is not used.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::ThreadClassInfoHashTables::ThreadClassInfoHashTables): This new class holds per-thread
-        HashTables for built-in classes. The old static structs are copied to create per-thread
-        instances.
-        (KJS::JSGlobalObject::threadClassInfoHashTables): An accessor/initializer for the above.
-        (KJS::JSGlobalObject::init): Copy per-thread data into a single structure for faster access.
-        Also, construct globalExec.
-        (KJS::JSGlobalObject::reset): Adapted for globalExec now being an OwnPtr.
-        (KJS::JSGlobalObject::mark): Ditto.
-        (KJS::JSGlobalObject::globalExec): Ditto.
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData): Made JSGlobalObject::JSGlobalObjectData::globalExec an OwnPtr, so that it can
-        be initialized from JSGlobalObject::init() after them. Otherwise, ExecState constructor was
-        trying to access half-initialized JSGlobalObject to make its own copy of these table
-        references, and failed.
-        (KJS::JSGlobalObject::JSGlobalObject): Pass "this" value to init() to create globalExec.
-        (KJS::JSGlobalObject::perThreadData): An accessor for per-thread data.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        * kjs/ExecState.h:
-        (KJS::ExecState::propertyNames):
-        (KJS::ExecState::emptyList):
-        (KJS::ExecState::arrayTable):
-        (KJS::ExecState::dateTable):
-        (KJS::ExecState::mathTable):
-        (KJS::ExecState::numberTable):
-        (KJS::ExecState::RegExpImpTable):
-        (KJS::ExecState::RegExpObjectImpTable):
-        (KJS::ExecState::stringTable):
-        * kjs/ExecStateInlines.h:
-        (KJS::ExecState::ExecState):
-        Each ExecState holds its own reference to per-thread data, for even faster access. Moved
-        m_emptyList and m_propertyNames to the same structure, making ExecState faster to construct
-        and take less space on the stack.
-
-        * kjs/InitializeThreading.cpp: (KJS::initializeThreading): Initialize thread-static data
-        added to JSGlobalObject.
-
-        * API/JSCallbackConstructor.cpp:
-        * API/JSCallbackFunction.cpp:
-        * API/JSCallbackObject.cpp:
-        * JavaScriptCore.exp:
-        * kjs/JSVariableObject.cpp:
-        (KJS::JSVariableObject::getPropertyAttributes):
-        * kjs/JSVariableObject.h:
-        * kjs/array_instance.cpp:
-        * kjs/array_object.cpp:
-        (KJS::ArrayPrototype::getOwnPropertySlot):
-        * kjs/bool_object.cpp:
-        * kjs/create_hash_table:
-        * kjs/date_object.cpp:
-        (KJS::DatePrototype::getOwnPropertySlot):
-        (KJS::DateObjectImp::DateObjectImp):
-        * kjs/error_object.cpp:
-        * kjs/function.cpp:
-        * kjs/function_object.cpp:
-        (KJS::FunctionPrototype::FunctionPrototype):
-        * kjs/internal.cpp:
-        * kjs/lookup.h:
-        * kjs/math_object.cpp:
-        (KJS::MathObjectImp::getOwnPropertySlot):
-        * kjs/number_object.cpp:
-        (KJS::NumberObjectImp::getOwnPropertySlot):
-        * kjs/object_object.cpp:
-        (KJS::ObjectPrototype::ObjectPrototype):
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpPrototype::RegExpPrototype):
-        (KJS::RegExpImp::getOwnPropertySlot):
-        (KJS::RegExpImp::put):
-        (KJS::RegExpObjectImp::getOwnPropertySlot):
-        (KJS::RegExpObjectImp::put):
-        * kjs/string_object.cpp:
-        (KJS::StringPrototype::getOwnPropertySlot):
-        Adjust for the above changes.
-
-2008-04-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Adam.
-
-        - make sure RefPtr's default hash doesn't ref/deref when computing the hash
-        - remove remnants of the hash table storage type optimization
-
-        * wtf/HashFunctions.h: Used "using" to get the hash and equal functions
-        from PtrHash<P*> into PtrHash<RefPtr<P>>.
-
-        * wtf/HashMap.h: Replaced uses of PairBaseHashTraits with PairHashTraits.
-        Eliminated storage-related typedefs. Removed constructor, destructor,
-        copy constructor, and destructor since the compiler-generated ones are
-        fine. Removed refAll and derefAll. Took out unnnecessary typecasts.
-        Removed use of RefCounter.
-
-        * wtf/HashSet.h: Eliminated storage-related typedefs. Removed constructor,
-        destructor, copy constructor, and destructor since the compiler-generated
-        ones are fine. Removed refAll and derefAll. Removed unneeded template
-        arguents from HashSetTranslatorAdapter. Eliminated unneeded HashSetTranslator
-        template.
-
-        * wtf/HashTable.h: Tweaked formatting. Removed NeedsRef, RefCounterBase,
-        RefCounter, HashTableRefCounterBase, HashTableRefCounter, and Assigner
-        class templates.
-
-        * wtf/HashTraits.h: Removed StorageTraits, needsRef, PairBaseHashTraits,
-        and HashKeyStorageTraits.
-
-        * wtf/RefPtrHashMap.h: Made all the same fixes as in HashMap. Also made
-        the corresponding changes to RefPtrHashMapRawKeyTranslator.
-
-2008-04-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Mitz.
-
-        - fix assertion hit every time you view www.apple.com
-
-        * kjs/PropertyNameArray.cpp:
-        (KJS::PropertyNameArray::add): Changed assertion to allow null and empty strings.
-        Now to find out why we have a property named "" and if that's a bug!
-
-2008-04-27  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Fix crash inside PtrHash::hash when loading a page.
-
-        * wtf/HashFunctions.h: Explicitly use the superclass implementation of hash to avoid infinite recursion.
-
-2008-04-27  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - fix <rdar://problem/5657459> REGRESSION: JavaScriptCore no longer builds with
-          GCC 4.2 due to pointer aliasing warnings
-
-        Fix this by removing the HashTable optimizations that allowed us to share a back end
-        implementation between hash tables with integers, pointers, RefPtr, and String objects
-        as keys. The way it worked was incompatible with strict aliasing.
-
-        This increases code size. On Mac OS X we'll have to regenerate .order files to avoid
-        slowing down Safari startup times.
-
-        This creates a slight slowdown in SunSpider, mitigated by the following four speedups:
-
-        - speed up array put slightly by moving a branch (was already done for get)
-
-        - speed up symbol table access by adding a function named inlineGet to HashMap
-          and using that in symbolTableGet/Put
-
-        - speed up PropertyNameArray creation by reducing the amount of reference count
-          churn and uniqueness checking when adding names and not doing any allocation at
-          all when building small arrays
-
-        - speed up conversion of strings to floating point numbers by eliminating the
-          malloc/free of the buffer for the ASCII copy of the string; a way to make
-          things even faster would be to change strtod to take a UTF-16 string
-
-        Note that there is considerable unused complexity now in HashSet/Map/Table to support
-        "storage types", which is no longer used. Will do in a separate patch.
-
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::JSCallbackObject<Base>::getPropertyNames): Removed explicit cast to Identifier to
-        take advantage of the new PropertyNameArray::add overload and avoid reference count churn.
-        * API/JSObjectRef.cpp:
-        (JSPropertyNameAccumulatorAddName): Ditto.
-        * JavaScriptCore.exp: Updated PropertyNameArray::add entry point name.
-
-        * kjs/JSVariableObject.cpp: Removed now-unneeded IdentifierRepHashTraits::nullRepPtr
-        definition (see below).
-        (KJS::JSVariableObject::getPropertyNames): Removed explicit cast to Identifier.
-
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTableGet): Use inlineGet for speed. Also changed to do
-        early exit instead of nesting the body inside an if.
-        (KJS::JSVariableObject::symbolTablePut): Ditto.
-
-        * kjs/PropertyNameArray.cpp:
-        (KJS::PropertyNameArray::add): Changed implementation to take a raw pointer instead of
-        a reference to an identifier. Do uniqueness checking by searching the vector when the
-        vector is short, only building the set once the vector is large enough.
-
-        * kjs/PropertyNameArray.h: Added an overload of add for a raw pointer, and made the old
-        add function call that one. Added an addKnownUnique function for use when the new
-        name is known to be different from any other in the array. Changed the vector to have
-        an inline capacity of 20.
-
-        * kjs/SymbolTable.h: Changed IdentifierRepHash to inherit from the default hash for
-        a RefPtr so we don't have to define so much. Added an overload of the hash function for
-        a raw pointer as required by the new RefPtrHashMap. Got rid of the now-unneeded
-        IdentifierRepHashTraits -- the default traits now work fine. Added a definition of
-        empthValueIsZero to SymbolTableIndexHashTraits; not having it was incorrect, but harmless.
-
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::put): Move the maxArrayIndex check inside the branch that checks
-        the index against the length, as done in the get function.
-
-        * kjs/function.cpp:
-        (KJS::globalFuncKJSPrint): Changed to use the new getCString instead of cstring.
-
-        * kjs/internal.cpp: Removed printInfo debugging function, a client of cstring.
-        If we need a debugging function we can easily make a better one and we haven't
-        used this one in a long time.
-        * kjs/internal.h: Ditto.
-
-        * kjs/object.cpp:
-        (KJS::JSObject::getPropertyNames): Removed explicit cast to Identifier.
-        * kjs/property_map.cpp:
-        (KJS::PropertyMap::getEnumerablePropertyNames): Ditto. Also added a special case for
-        the case where the propertyNames array is empty -- in that case we know we're adding
-        a set of names that are non-overlapping so we can use addKnownUnique.
-        * kjs/ustring.cpp:
-        (KJS::UString::getCString): Replaces cstring. Puts the C string into a CStringBuffer,
-        which is a char Vector with an inline capacity. Also returns a boolean to indicate if
-        the converion was lossy, which eliminates the need for a separate is8Bit call.
-        (KJS::UString::toDouble): Changed to call getCString instead of cstring.
-        * kjs/ustring.h: Ditto.
-
-        * wtf/HashFunctions.h: Overload the hash and equal functions for RefPtr's default
-        hash to take raw pointers. This works with the changes to RefPtrHashMap to avoid
-        introducing refcount churn.
-
-        * wtf/HashMap.h: Removed special code to convert the deleted value to the empty value
-        when writing a new value into the map. This is now handled elsewhere.
-        (WTF::HashMap::get): Removed code that checks for an empty hash table before calling
-        HashTable::lookup; it's slightly more efficient to do this check inside lookup.
-
-        * wtf/HashTable.h:
-        (WTF::HashTable::isDeletedBucket): Changed to use isDeletedValue instead of using
-        deletedValue and the equality operator.
-        (WTF::HashTable::deleteBucket): Changed to use constructDeletedValue instead of
-        using deletedValue and the assignment operator.
-        (WTF::HashTable::checkKey): Added. Factors out the check for values that are empty
-        or deleted keys that's used in various functions below.
-        (WTF::HashTable::lookup): Changed to use checkKey, check for a 0 table, and also
-        made public for use by RefPtrHashMap.
-        (WTF::HashTable::lookupForWriting): Changed to use checkKey.
-        (WTF::HashTable::fullLookupForWriting): Changed to use checkKey.
-        (WTF::HashTable::add): Changed to use checkKey, and call initializeBucket on a
-        deleted bucket before putting a new entry into it.
-        (WTF::HashTable::addPassingHashCode): Ditto.
-        (WTF::HashTable::deallocateTable): Check isDeletedBucket before calling ~ValueType.
-
-        * wtf/HashTraits.h: Got ridd of all the HashTraits specialization for the integer
-        types, since GeneicHashTraitsBase already deals with integers separately. Put the
-        deleted value support into GenericHashTraitsBase. Changed FloatHashTraits to
-        inherit from GenericHashTraits, and define construct/isDeletedValue rather than
-        deletedValue. Removed the ref and deref functions from RefPtr's HashTraits, and
-        defined construct/isDeletedValue. Eliminated DeletedValueAssigner. Changed
-        PairHashTraits to define construct/isDeletedValue, and also merged
-        PairBaseHashTraits in with PairHashTraits. Got rid of all specialization of
-        HashKeyStorageTraits. We'll remove that, and the needsRef data member, later.
-
-        * wtf/RefPtr.h: Added HashTableDeletedValueType, an enum type with a single value,
-        HashTableDeletedValue. Used that type to make a new constructor to construct
-        deleted values and also added an isHashTableDeletedValue function.
-
-        * wtf/RefPtrHashMap.h: Added RefPtrHashMapRawKeyTranslator and used it to implement
-        the raw pointer functions. This is a way to continue to avoid refcount thrash. We
-        can't use the old way because it depended on the underlying map using a non-RefPtr
-        type.
-        (WTF::HashMap::find): Use find with RefPtrHashMapRawKeyTranslator.
-        (WTF::HashMap::contains): Use contains with RefPtrHashMapRawKeyTranslator.
-        (WTF::HashMap::inlineAdd): Use add with RefPtrHashMapRawKeyTranslator.
-        (WTF::HashMap::get): Removed code that checks for an empty hash table before calling
-        HashTable::lookup; it's slightly more efficient to do this check inside lookup.
-        (WTF::HashMap::inlineGet): Added. Just like get, but marked inline for use in the
-        symbol table code.
-
-2008-04-25  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Mark Rowe.
-
-        Remove SavedBuiltins and SavedProperties classes and the methods used to
-        save data to them.  The CachedPage now stores a the JSGlobalObject in full.
-
-        * JavaScriptCore.exp:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSGlobalObject.h:
-        * kjs/JSVariableObject.cpp:
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::localStorage):
-        * kjs/SavedBuiltins.h: Removed.
-        * kjs/object.h:
-        * kjs/property_map.cpp:
-        * kjs/property_map.h:
-
-2008-04-25  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Sam Weinig.
-
-        Add some content to an empty ICU header file to prevent verification errors.
-
-        * icu/unicode/utf_old.h:
-
-2008-04-25  David Kilzer  <ddkilzer@apple.com>
-
-        <rdar://problem/5819422> REGRESSION: Wrong line number passed to -willLeaveCallFrame
-
-        Patch by George Dicker and Michael Kahl.  Reviewed by Darin.
-
-        When -[NSObject(WebScriptDebugDelegate) webView:willLeaveCallFrame:sourceId:line:forWebFrame:]
-        is invoked, the first line number of the function is returned instead of the last
-        line number.  This regressed in r28458.
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionBodyNodeWithDebuggerHooks::execute): Pass lastLine() instead of lineNo()
-        when calling Debugger::returnEvent().
-
-2008-04-25  Darin Adler  <darin@apple.com>
-
-        Done with Stephanie Lewis.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Prepare for compilation with gcc 4.2 by
-        adding -fno-strict-aliasing to CollatorICU.cpp.
-
-2008-04-24  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Add a #define to easily enable collecting on every allocation to aid
-        debugging GC bugs.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::heapAllocate):
-
-2008-04-24  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Adam and Sam.
-
-        -<rdar://problem/5770054> JavaScript profiler (10928)
-        -Only profile the page group that starts profiling to avoid profiling
-        tools that shouldn't be profiled unless explicitly requested to.
-
-        * JavaScriptCore.exp: Export new signature.
-        * kjs/JSGlobalObject.cpp: Add unique identifiers to the JSGlobalObject.
-        (KJS::JSGlobalObject::init):
-        * kjs/JSGlobalObject.h: Ditto.
-        (KJS::JSGlobalObject::setPageGroupIdentifier):
-        (KJS::JSGlobalObject::pageGroupIdentifier):
-        * profiler/Profiler.cpp: Check the identifier of the page group of the
-        lexical global exec state and only profile if it matches the given page
-        group identifier.
-        (KJS::Profiler::startProfiling):
-        (KJS::Profiler::willExecute):
-        (KJS::Profiler::didExecute):
-        * profiler/Profiler.h: Ditto.
-        (KJS::Profiler::Profiler):
-
-2008-04-24  Julien Chaffraix  <jchaffraix@webkit.org>
-
-        Reviewed by Simon.
-
-        Bug 15940: Implement threading API for Qt
-        https://bugs.webkit.org/show_bug.cgi?id=15940
-
-        Original patch by Justin Haygood, tweaked by me.
-
-        * JavaScriptCore.pri:
-        * wtf/ThreadingQt.cpp: Added.
-        (WTF::threadMapMutex):
-        (WTF::threadMap):
-        (WTF::establishIdentifierForThread):
-        (WTF::clearThreadForIdentifier):
-        (WTF::threadForIdentifier):
-        (WTF::initializeThreading):
-        (WTF::ThreadPrivate::getReturnValue):
-        (WTF::ThreadPrivate::ThreadPrivate):
-        (WTF::ThreadPrivate::run):
-        (WTF::createThread):
-        (WTF::waitForThreadCompletion): return !res to return
-        0 on success (to match the pthreads implementation).
-        (WTF::detachThread):
-        (WTF::identifierByQthreadHandle):
-        (WTF::currentThread):
-        (WTF::Mutex::Mutex):
-        (WTF::Mutex::~Mutex):
-        (WTF::Mutex::lock):
-        (WTF::Mutex::tryLock):
-        (WTF::Mutex::unlock):
-        (WTF::ThreadCondition::ThreadCondition):
-        (WTF::ThreadCondition::~ThreadCondition):
-        (WTF::ThreadCondition::wait):
-        (WTF::ThreadCondition::timedWait):
-        (WTF::ThreadCondition::signal):
-
-2008-04-22  Darin Adler  <darin@apple.com>
-
-        Reviewed by Anders.
-
-        - simplify use of HashTraits to prepare for some upcoming hash table changes
-
-        * kjs/SymbolTable.h: Made SymbolTableIndexHashTraits derive from HashTraits<size_t>
-        and specialize only the empty value.
-
-2008-04-23  Holger Hans Peter Freyther  <zecke@selfish.org>
-
-        Reviewed by Simon.
-
-        Removed the #define for USE_SYSTEM_MALLOC that we set in WebKit.pri
-        already.
-
-        * wtf/Platform.h:
-
-2008-04-21  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Adam.
-
-        <rdar://problem/5770054> JavaScript profiler (10928)
-        - When stop profiling is called we need to stop the timers on all the
-        functions that are still running.
-
-        * profiler/FunctionCallProfile.cpp:
-        (KJS::FunctionCallProfile::didExecute):
-        (KJS::FunctionCallProfile::stopProfiling):
-        * profiler/FunctionCallProfile.h:
-        * profiler/Profiler.cpp:
-        (KJS::Profiler::stopProfiling):
-
-2008-04-21  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Move collector main thread initialization from WebKit/win to KJS::initializeThreading.
-
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreading):
-
-2008-04-21  Adam Roben  <aroben@apple.com>
-
-        MSVC build fix
-
-        Reviewed by Alexey Proskuryakov.
-
-        * kjs/ustring.h:
-        (KJS::UString::cost): Disable a warning about assigning a 32-bit
-        size_t into a 31-bit size_t.
-
-2008-04-21  Simon Hausmann  <hausmann@webkit.org>
-
-        Reviewed by Lars.
-
-        Made convertValueToQVariant accessible from within WebKit/qt/Api
-
-        * bindings/qt/qt_runtime.h:
-
-2008-04-21  Holger Hans Peter Freyther  <holger.freyther@trolltech.com>
-
-        Reviewed by Simon.
-
-        Build fix for Qt 4.3
-
-        * When building WebCore/internal make sure the QT_[BEGIN,END]_NAMESPACE is
-        always defined. Do this by adding defines to the compiler line
-        * For users of our API this is not feasible. Every public header file should
-        include qwebkitglobal.h. Define the QT_BEGIN_NAMESPACE and QT_END_NAMESPACE
-        when we are building everything < 4.4.0 and don't have them defined.
-
-        * kjs/testkjs.pro:
-
-2008-04-19  Matt Lilek  <webkit@mattlilek.com>
-
-        Not reviewed, Windows build fix - copy the profiler headers in all
-        configurations, not just Debug_Internal.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-04-19  Mike Hommey  <glandium@debian.org>
-
-        Reviewed by Alp Toker.
-
-        Don't build testkjs with rpath.
-
-        * GNUmakefile.am:
-
-2008-04-18  Kevin Ollivier  <kevino@theolliviers.com>
-
-        wx build fixes. Rename LocalStorage.h to LocalStorageEntry.h
-        to avoid header detection issues between WebCore/storage/LocalStorage.h 
-        and it, and add $(PROFILER_SOURCES) to the wx JSCore build.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * jscore.bkl:
-        * kjs/ExecState.h:
-        * kjs/JSVariableObject.h:
-        * kjs/LocalStorage.h: Removed.
-        * kjs/LocalStorageEntry.h: Copied from JavaScriptCore/kjs/LocalStorage.h.
-        * kjs/function.h:
-
-2008-04-18 Jan  Michael Alonzo  <jmalonzo@unpluggable.com>
-
-        Reviewed by Alp Toker.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16620
-        [GTK] Autotools make dist and make check support
-
-        Cleanups.
-
-        * GNUmakefile.am:
-
-2008-04-18  Jon Honeycutt  <jhoneycutt@apple.com>
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Windows
-        build fix.
-
-2008-04-11  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Antti Koivisto.
-
-        Silence GCC 4.3 warnings by removing extraneous consts.
-
-        * kjs/ustring.cpp:
-        * kjs/ustring.h:
-
-2008-04-18  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam.
-
-        -<rdar://problem/5770054> JavaScript profiler (10928)
-        - Use Deque instead of Vector since the profiler uses prepend a lot
-        and deque is faster at that.
-
-        * profiler/FunctionCallProfile.h:
-        (KJS::FunctionCallProfile::milliSecs): Corrected the name to match
-        its output.
-        * wtf/Deque.h:
-        (WTF::deleteAllValues):
-
-2008-04-18  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam and Adam.
-
-        -<rdar://problem/5770054> JavaScript profiler (10928)
-        - Cleaned up the header file and made some functions static, added
-        a new, sane, printing function, and fixed a few minor bugs.
-
-        * JavaScriptCore.exp:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * profiler/FunctionCallProfile.cpp:
-        (KJS::FunctionCallProfile::didExecute): Removed assertion that time is
-        > 0 because at ms resolution that may not be true and only cross-
-        platform way to get time differences is in ms.
-        (KJS::FunctionCallProfile::printDataInspectorStyle): Added a new
-        printing function for dumping data in a sane style.
-        (KJS::FunctionCallProfile::printDataSampleStyle): Fixed a bug where we
-        displayed too much precision when printing our floats. Also added logic
-        to make sure we don't display 0 because that doesn't make sense for a
-        sampling profile.
-        * profiler/FunctionCallProfile.h:
-        * profiler/Profiler.cpp: Moved functions that could be static into the
-        implementation, and chaned the ASSERTs to early returns.  I did this
-        because console.profile() is a JS function and so was being profiled
-        but asserting because the profiler had not been started! In the future
-        I would like to put the ASSERTs back and not profile the calls to
-        console.profile() and console.profileEnd().
-        (KJS::Profiler::willExecute):
-        (KJS::Profiler::didExecute):
-        (KJS::getStackNames): Fixed a bug where the wrong ExecState was being
-        used.
-        (KJS::getFunctionName):
-        (KJS::Profiler::printDataInspectorStyle):
-        * profiler/Profiler.h:
-
-2008-04-18  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Fix leaks during plugin tests (which actually excercise background JS), and potential
-        PAC brokenness that was not reported, but very likely.
-
-        The leaks shadowed a bigger problem with Identifier destruction. Identifier::remove involves
-        an IdentifierTable lookup, which is now a per-thread instance. Since garbage collection can
-        currently happen on a different thread than allocation, a wrong table was used.
-
-        No measurable change on SunSpider total, ~1% variation on individual tests.
-
-        * kjs/ustring.cpp:
-        (KJS::UString::Rep::create):
-        (KJS::UString::Rep::destroy):
-        * kjs/ustring.h:
-        Replaced isIdentifier with a pointer to IdentifierTable, so that destruction can be done
-        correctly. Took one bit from reportedCost, to avoid making UString::Rep larger (performance
-        effect was measurable on SunSpider).
-
-        * kjs/identifier.cpp:
-        (KJS::IdentifierTable::IdentifierTable):
-        (KJS::IdentifierTable::~IdentifierTable):
-        (KJS::IdentifierTable::add):
-        (KJS::IdentifierTable::remove):
-        Make IdentifierTable a real class. Its destructor needs to zero out outstanding references,
-        because some identifiers may briefly outlive it during thread destruction, and we don't want
-        them to use their stale pointers.
-
-        (KJS::LiteralIdentifierTable):
-        (KJS::Identifier::add):
-        Now that LiteralIdentifierTable is per-thread and can be destroyed not just during application
-        shutdown, it is not appropriate to simply bump refcount for strings that get there; changed
-        the table to hold RefPtrs.
-
-        (KJS::CStringTranslator::translate):
-        (KJS::UCharBufferTranslator::translate):
-        (KJS::Identifier::addSlowCase):
-        (KJS::Identifier::remove):
-        * kjs/identifier.h:
-        (KJS::Identifier::add):
-        Use and update UString::Rep::identifierTable as appropriate. Updating it is now done in
-        IdentifierTable::add, not in translators.
-
-2008-04-18  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Get rid of static compareWithCompareFunctionArguments in array_instance.cpp.
-
-        No change on SunSpider, CelticKane or iBench JavaScript. It is probable that in some cases,
-        merge sort is still faster, but more investigation is needed to determine a new cutoff.
-        Or possibly, it would be better to do what FIXME says (change to tree sort).
-
-        Also, made arguments a local variable - not sure why it was a member of
-        CompareWithCompareFunctionArguments.
-
-        * kjs/array_instance.cpp:
-        (KJS::CompareWithCompareFunctionArguments::CompareWithCompareFunctionArguments):
-        (KJS::CompareWithCompareFunctionArguments::operator()):
-        (KJS::ArrayInstance::sort):
-
-2008-04-18  Simon Hausmann  <hausmann@webkit.org>
-
-        Build fix for gcc 4.3. Include stdio.h for printf.
-
-        * profiler/FunctionCallProfile.cpp:
-        * profiler/Profiler.cpp:
-
-2008-04-17  Jon Honeycutt  <jhoneycutt@apple.com>
-
-        Reviewed by mrowe.
-
-        * wtf/Platform.h: Add HAVE_ACCESSIBILITY to Platform.h.
-
-2008-04-17  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Maciej.
-
-        Thread static data destructors are not guaranteed to be called in any particular order;
-        turn ThreadSpecific into a phoenix-style singleton to avoid accessing freed memory when
-        deleted objects are interdependent (e.g. CommonIdentifiers and internal identifier tables).
-
-        No change on SunSpider.
-
-        * wtf/ThreadSpecific.h:
-        (WTF::ThreadSpecific::Data::Data):
-        (WTF::::get):
-        (WTF::::set):
-        (WTF::::destroy):
-
-2008-04-15  Srinivas Rao. M Hamse  <msrinirao@gmail.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        - gcc 3.x build fix
-
-        * kjs/nodes.h: CallerType definition made public for gcc 3.x compilation
-
-2008-04-16  Brady Eidson  <beidson@apple.com>
-
-        Reviewed by Sam Weinig
-
-        Change ThreadSafeShared to act like RefCounted by starting out with a single ref by default
-
-        * wtf/Threading.h:
-        (WTF::ThreadSafeShared::ThreadSafeShared):
-
-2008-04-16  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        - To keep the behavior of the WebKit and JavaScriptCore API's the same,
-          we need to hide the fact that the global object and the window object
-          are no longer the same thing, and the the global object now changes on
-          navigations.  To do this, only the wrapper should ever be exposed.  This
-          fixes the two remaining spots where the internal global object is exposed,
-          the windowScriptObject returned from [WebFrame windowObject] and the object
-          return by calling JSContextGetGlobalObject on [WebFrame globalContext].
-
-        * API/JSContextRef.cpp:
-        (JSContextGetGlobalObject):
-        This is a bit of a hack, this returns the "this" representation of the globalObject
-        which will be the WrapperWindow for WebCore and the globalObject for non-WebCore.
-
-        * API/JSObjectRef.cpp:
-        (JSObjectSetProperty):
-        Call the new putWithAttributes method instead of relying on lower-level calls.
-        This is needed so that the window wrapper can forward the calls.
-
-        * JavaScriptCore.exp:
-        * kjs/Activation.h:
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::putWithAttributes):
-        * kjs/JSGlobalObject.h:
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTablePutWithAttributes):
-        * kjs/function.cpp:
-        (KJS::ActivationImp::putWithAttributes):
-        * kjs/nodes.cpp:
-        (KJS::ConstDeclNode::handleSlowCase):
-        (KJS::ConstDeclNode::evaluateSingle):
-        (KJS::EvalNode::processDeclarations):
-        * kjs/object.cpp:
-        (KJS::JSObject::putWithAttributes):
-        * kjs/object.h:
-        Rename initializeVariable to putWithAttributes and move it down to JSObject so it
-        can be used for JSObjectSetProperty.
-
-2008-04-16  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam and Geoff.
-
-        -<rdar://problem/5770054> JavaScript profiler (10928)
-        Inital profiler prototype
-
-        * GNUmakefile.am: Added new files to project
-        * JavaScriptCore.pri: Ditto
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto
-        * JavaScriptCore.xcodeproj/project.pbxproj: Ditto
-        * JavaScriptCoreSources.bkl: Ditto
-        * kjs/config.h: Put compiling flag in here.
-        * kjs/function.cpp: Instrument calling the function eval().
-        (KJS::eval):
-        * kjs/interpreter.cpp: Instrument evaluating global scopes.
-        (KJS::Interpreter::evaluate):
-        * kjs/object.cpp: Instrument JS function calls.
-        (KJS::JSObject::call):
-        * profiler: Added.
-        * profiler/FunctionCallProfile.cpp: Added.
-        (KJS::FunctionCallProfile::FunctionCallProfile):
-        (KJS::FunctionCallProfile::~FunctionCallProfile):
-        (KJS::FunctionCallProfile::willExecute): Call right before the JS function or executing context is executed to start the profiler's timer.
-        (KJS::FunctionCallProfile::didExecute): Call right after the JS function or executing context is executed to stop the profiler's timer.
-        (KJS::FunctionCallProfile::addChild): Add a child to the current FunctionCallProfile if it isn't already a child of the current FunctionalCallProfile.
-        (KJS::FunctionCallProfile::findChild): Return the child that matches the given name if there is one.
-        (KJS::FunctionCallProfile::printDataSampleStyle): Print the current profiled information in a format that matches sample's output.
-        * profiler/FunctionCallProfile.h: Added.
-        (KJS::FunctionCallProfile::FunctionCallProfile):
-        (KJS::FunctionCallProfile::~FunctionCallProfile):
-        (KJS::FunctionCallProfile::functionName):
-        (KJS::FunctionCallProfile::microSecs):
-        * profiler/Profiler.cpp: Added.
-        (KJS::Profiler::profiler):
-        (KJS::Profiler::sharedProfiler): Return global singleton (may change due to multi-threading concerns)
-        (KJS::Profiler::startProfiling): Don't start collecting profiling information until the user starts the profiler. Also don't clear old prfiled data until the profiler is restarted.
-        (KJS::Profiler::stopProfiling): Stop collecting profile information.
-        (KJS::Profiler::willExecute): Same as above. 
-        (KJS::Profiler::didExecute): Same as above.
-        (KJS::Profiler::insertStackNamesInTree): Follow the stack of the given names and if a sub-stack is not in the current tree, add it.
-        (KJS::Profiler::getStackNames): Get the names from the different passed in parameters and order them as a stack.
-        (KJS::Profiler::getFunctionName): Get the function name from the given parameter.
-        (KJS::Profiler::printDataSampleStyle): Print the current profiled information in a format that matches sample's output.
-        (KJS::Profiler::debugLog):
-        * profiler/Profiler.h: Added.
-        (KJS::Profiler::Profiler):
-
-2008-04-16  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Darin Adler.
-
-        - Remove kjs_ prefix from strtod, dtoa, and freedtoa and put it
-          in the KJS namespace.
-        - Make strtod, dtoa, and freedtoa c++ functions instead of extern "C".
-        - Remove mode switching from dtoa.  ~2% improvement on test 26. 
-        - Removes all unnecessary #defines from dtoa code.
-
-        * JavaScriptCore.exp:
-        * kjs/dtoa.cpp:
-        (KJS::ulp):
-        (KJS::b2d):
-        (KJS::d2b):
-        (KJS::ratio):
-        (KJS::strtod):
-        (KJS::freedtoa):
-        (KJS::dtoa):
-        * kjs/dtoa.h:
-        * kjs/function.cpp:
-        (KJS::parseInt):
-        * kjs/lexer.cpp:
-        (KJS::Lexer::lex):
-        * kjs/number_object.cpp:
-        (KJS::integer_part_noexp):
-        (KJS::numberProtoFuncToExponential):
-        * kjs/ustring.cpp:
-        (KJS::UString::from):
-        (KJS::UString::toDouble):
-
-2008-04-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Get rid of static execForCompareByStringForQSort in array_instance.cpp.
-
-        No change on SunSpider, CelticKane or iBench JavaScript.
-
-        * kjs/array_instance.cpp:
-        (KJS::ArraySortComparator::ArraySortComparator):
-        (KJS::ArraySortComparator::operator()):
-        (KJS::ArrayInstance::sort):
-        Switch slow case to std::sort, so that ExecState can be passed in a comparator.
-
-2008-04-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Adam Roben.
-
-        MSVC build fix.
-
-        * kjs/CommonIdentifiers.cpp:
-        * kjs/CommonIdentifiers.h:
-        * kjs/Parser.cpp:
-        * kjs/Parser.h:
-        * kjs/identifier.cpp:
-        * kjs/lexer.h:
-        * wtf/ThreadSpecific.h:
-
-2008-04-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Build fix.
-
-        * kjs/date_object.cpp:
-        * kjs/date_object.h:
-        Don't include DateMath.h from date_object.h, as the latter is used from WebCore, while
-        where the former is not available.
-
-2008-04-16  Holger Hans Peter Freyther  <zecke@selfish.org>
-
-        Unreviewed build fix for MSVC. It does not want to have
-        WTF in the KJS namespace.
-
-        * kjs/CommonIdentifiers.h:
-
-2008-04-16  Holger Hans Peter Freyther  <zecke@selfish.org>
-
-        Unreviewed build fix for gcc.
-
-        ::msToGregorianDateTime  is not known to it.
-
-        * kjs/date_object.cpp:
-        (KJS::DateInstance::msToGregorianDateTime):
-
-2008-04-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Initialize threadMapMutex safely (as already done in ThreadingWin).
-
-        * wtf/ThreadingGtk.cpp:
-        (WTF::threadMapMutex):
-        (WTF::initializeThreading):
-        * wtf/ThreadingPthreads.cpp:
-        (WTF::threadMapMutex):
-        (WTF::initializeThreading):
-
-2008-04-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Adam Roben.
-
-        Cache Gregorian date/time structure on DateInstance objects for 1.027x SunSpider speedup
-        (1.65x on date-format-xparb, 1.13x on date-format-tofte).
-
-        * kjs/DateMath.h:
-        (KJS::GregorianDateTime::copyFrom): Added. It presumably makes sense to keep GregorianDateTime
-        Noncopyable, so it's not just operator=.
-
-        * kjs/date_object.h: Added a per-object cache.
-
-        * kjs/date_object.cpp:
-        (KJS::DateInstance::DateInstance):
-        (KJS::DateInstance::msToGregorianDateTime):
-        (KJS::dateProtoFuncToString):
-        (KJS::dateProtoFuncToUTCString):
-        (KJS::dateProtoFuncToDateString):
-        (KJS::dateProtoFuncToTimeString):
-        (KJS::dateProtoFuncToLocaleString):
-        (KJS::dateProtoFuncToLocaleDateString):
-        (KJS::dateProtoFuncToLocaleTimeString):
-        (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::dateProtoFuncGetTimezoneOffset):
-        (KJS::setNewValueFromTimeArgs):
-        (KJS::setNewValueFromDateArgs):
-        (KJS::dateProtoFuncSetYear):
-        (KJS::dateProtoFuncGetYear):
-        Use the cache when converting.
-
-2008-04-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Implement an abstraction for thread-specific storage, use it to get rid of some static objects.
-
-        SunSpider results were not conclusive, possibly up to 0.2% slowdown.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        Added ThreadSpecific.h
-
-        * wtf/ThreadSpecific.h: Added.
-        (WTF::::ThreadSpecific):
-        (WTF::::~ThreadSpecific):
-        (WTF::::get):
-        (WTF::::set):
-        (WTF::::destroy):
-        (WTF::T):
-        (WTF::::operator):
-        Only implemented for platforms that use pthreads.
-
-        * kjs/CommonIdentifiers.cpp:
-        (KJS::CommonIdentifiers::shared):
-        * kjs/CommonIdentifiers.h:
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreading):
-        * kjs/Parser.cpp:
-        (KJS::parser):
-        * kjs/Parser.h:
-        * kjs/identifier.cpp:
-        (KJS::identifierTable):
-        (KJS::literalIdentifierTable):
-        (KJS::Identifier::initializeIdentifierThreading):
-        * kjs/identifier.h:
-        * kjs/lexer.cpp:
-        (KJS::lexer):
-        * kjs/lexer.h:
-        Make static instances per-thread.
-
-2008-04-15  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Adam.
-
-        Add ENABLE_OFFLINE_WEB_APPLICATIONS to FEATURE_DEFINES.
-        
-        * Configurations/JavaScriptCore.xcconfig:
-
-2008-04-15  Andre Poenitz  <andre.poenitz@trolltech.com>
-
-        Reviewed by Simon.
-
-        Fix compilation with Qt namespaces
-
-        Qt can be configured to have all of its classes inside a specified namespaces.
-        This is for example used in plugin/component environments like Eclipse.
-
-        This change makes it possible to let the Qt port compile against a namespaced
-        Qt by the use of macros Qt provides to properly forward declare Qt classes in
-        the namespace.
-
-        * wtf/unicode/qt4/UnicodeQt4.h:
-
-2008-04-14  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Adam.
-
-        Don't leak the prototype class.
-        
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::create):
-
-2008-04-14  Steve Falkenburg  <sfalken@apple.com>
-
-        Fix build.
-
-        * wtf/ThreadingWin.cpp:
-
-2008-04-14  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Adam Roben.
-
-        https://bugs.webkit.org/show_bug.cgi?id=18488
-        FastMalloc doesn't release thread-specific data on Windows
-
-        * wtf/ThreadingWin.cpp:
-        (WTF::threadMapMutex): (WTF::initializeThreading): Call threadMapMutex once to initialize the static safely.
-        (WTF::ThreadFunctionInvocation::ThreadFunctionInvocation): Added a structure to wrap thread entry point and arguments.
-        (WTF::wtfThreadEntryPoint): Make sure to end all WTF threads with pthread_exit(), to give pthreads-win32 a chance to call
-        destructors of thread-specific data.
-        (WTF::createThread): Use _beginthreadex instead of CreateThread, because MSDN says so. Also removed a call to CreateEvent,
-        for which I could see no reason at all.
-
-2008-04-14  Alexey Proskuryakov  <ap@webkit.org>
-
-        Touched a file to make JavaScriptCore.vcproj rebuild.
-
-        * wtf/MathExtras.h:
-
-2008-04-14  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        Rubberstamped by Alexey Proskuryakov.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Disable
-        the "potentially uninitialized variable" warning for grammar.cpp, as
-        it seems to be incorrect. yylval gets initialized by the lexer, but
-        MSVC doesn't seem to understand this.
-
-2008-04-11  Antti Koivisto  <antti@apple.com>
-
-        Reviewed by Maciej.
-        
-        Add default hash for pairs of hashable types.
-
-        * wtf/HashFunctions.h:
-        (WTF::PairHash::hash):
-        (WTF::PairHash::equal):
-        (WTF::):
-
-2008-04-11  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff.
-
-        Make DateMath.cpp thread safe.
-
-        No measurable change on SunSpider (should be a very small speedup).
-
-        * kjs/DateMath.cpp:
-        (KJS::mimimumYearForDST): (KJS::equivalentYearForDST): Got rid of double caching of the
-        same precomputed value.
-        (KJS::calculateUTCOffset): (KJS::getUTCOffset): Factored actual UTC offset calculation code
-        out of getUTCOffset(), and notification setup into initDateMath().
-
-        (KJS::initDateMath): Added.
-
-        * kjs/DateMath.h:
-        * kjs/InitializeThreading.cpp:
-        (KJS::initializeThreading):
-        Added initDateMath().
-
-2008-04-11  Alexey Proskuryakov  <ap@webkit.org>
-
-        Windows build fix.
-
-        * kjs/grammar.y:
-
-2008-04-11  Alexey Proskuryakov  <ap@webkit.org>
-
-        Tiger build fix. Forward declaring a union didn't work for whatever reason, make the
-        parameters void*.
-
-        * kjs/grammar.y:
-        * kjs/lexer.cpp:
-        (kjsyylex):
-        (KJS::Lexer::lex):
-        * kjs/lexer.h:
-
-2008-04-11  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff.
-
-        Generate a pure (re-entrant) parser with Bison.
-
-        No change on SunSpider.
-
-        * kjs/Parser.cpp:
-        (KJS::Parser::parse):
-        * kjs/grammar.y:
-        * kjs/lexer.cpp:
-        (kjsyylex):
-        (KJS::Lexer::lex):
-        * kjs/lexer.h:
-        Pass state as function arguments, instead of global data. Don't call lexer() as often as
-        before, as this function is about to become slower due to thread-specific storage.
-
-        * kjs/function.cpp:
-        (KJS::isStrWhiteSpace): Don't call isSeparatorSpace() for 8-bit characters, as these are
-        already taken care of. This is a small speedup, compensating for a small slowdown caused
-        by switching Bison mode.
-
-2008-04-10  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Geoff.
-
-        https://bugs.webkit.org/show_bug.cgi?id=18402
-        REGRESSION: visited element handling is incorrect in nested join/toString calls
-
-        No change on SunSpider total, possibly a tiny improvement (about 0.1%).
-
-        Test: fast/js/array-tostring-and-join.html
-
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::visitedElements): Store visited elements HashSet here, making it
-        common to toString/toLocalizedString/join again.
-
-        * kjs/array_object.cpp:
-        (KJS::arrayProtoFuncToString):
-        (KJS::arrayProtoFuncToLocaleString):
-        (KJS::arrayProtoFuncJoin):
-        Got rid of static variables. Replaced UString with Vector to avoid O(n^2) behavior and
-        regain performance.
-
-        * wtf/Vector.h:
-        (WTF::::resize):
-        (WTF::::grow):
-        (WTF::::reserveCapacity):
-        (WTF::::append):
-        (WTF::::insert):
-        Added null checks, so that Vector methods don't crash when out of memory. The caller should
-        check that data pointer is not null before proceeding.
-
-2008-04-10  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Fix https://bugs.webkit.org/show_bug.cgi?id=18367 and the many dupes.
-        Bug 18367: Crash during celtic kane js speed 2007 test
-
-        GCC 4.2 on x86_64 Linux decided to reorder the local variables in markCurrentThreadConservatively's
-        stack frame.  This lead to the range of addresses the collector treated as stack to exclude the
-        contents of volatile registers that markCurrentThreadConservatively forces onto the stack.  This was
-        leading to objects being prematurely collected if the only reference to them was via a register at
-        the time a collection occurred.
-
-        The fix for this is to move the calculation of the top of the stack into a NEVER_INLINE function
-        that is called from markCurrentThreadConservatively.  This forces the dummy variable we use for
-        determining the top of stack to be in a different stack frame which prevents the compiler from
-        reordering it relative to the registers that markCurrentThreadConservatively forces onto the stack.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::markCurrentThreadConservativelyInternal):
-        (KJS::Collector::markCurrentThreadConservatively):
-        * kjs/collector.h:
-
-2008-04-10  Adam Roben  <aroben@apple.com>
-
-        VC++ Express build fix
-
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj: Link against user32.lib so
-        that anyone who links against WTF.lib will get user32.lib
-        automatically.
-
-2008-04-09  Adam Roben  <aroben@apple.com>
-
-        VC++ Express build fix
-
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj: Link against
-        user32.lib.
-
-2008-04-09  Adam Roben  <aroben@apple.com>
-
-        Build fix
-
-        * JavaScriptCore.exp: Export isMainThread.
-
-2008-04-09  Adam Roben  <aroben@apple.com>
-
-        Build fix
-
-        * wtf/AlwaysInline.h: Make sure to #include Platform.h before using
-        the macros it defines.
-
-2008-04-08  Mark Rowe  <mrowe@apple.com>
-
-        Export WTF::initializeThreading() from JavaScriptCore.
-
-        * JavaScriptCore.exp:
-
-2008-04-04  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        First step in implementing the "split window"
-
-        - Add a GlobalThisValue to ExecState which should be used 
-          in places that used to implement the "use the global object
-          as this if null" rule.
-        - Factor out lookupGetter/lookupSetter into virtual methods 
-          on JSObject so that they can be forwarded.
-        - Make defineGetter/defineSetter virtual methods for the same
-          reason.
-        - Have PrototypeReflexiveFunction store the globalObject used
-          to create it so that it can be used to get the correct thisObject
-          for eval.
-
-        * API/JSObjectRef.cpp:
-        (JSObjectCallAsFunction):
-        * JavaScriptCore.exp:
-        * kjs/Activation.h:
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        (KJS::GlobalExecState::GlobalExecState):
-        * kjs/ExecState.h:
-        (KJS::ExecState::globalThisValue):
-        * kjs/ExecStateInlines.h:
-        (KJS::ExecState::ExecState):
-        (KJS::FunctionExecState::FunctionExecState):
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset):
-        (KJS::JSGlobalObject::toGlobalObject):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData):
-        (KJS::JSGlobalObject::JSGlobalObject):
-        * kjs/array_instance.cpp:
-        (KJS::CompareWithCompareFunctionArguments::CompareWithCompareFunctionArguments):
-        (KJS::compareWithCompareFunctionForQSort):
-        * kjs/array_object.cpp:
-        (KJS::arrayProtoFuncSort):
-        (KJS::arrayProtoFuncFilter):
-        (KJS::arrayProtoFuncMap):
-        (KJS::arrayProtoFuncEvery):
-        (KJS::arrayProtoFuncForEach):
-        (KJS::arrayProtoFuncSome):
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-        (KJS::ActivationImp::toThisObject):
-        (KJS::globalFuncEval):
-        (KJS::PrototypeReflexiveFunction::PrototypeReflexiveFunction):
-        (KJS::PrototypeReflexiveFunction::mark):
-        * kjs/function.h:
-        (KJS::PrototypeReflexiveFunction::cachedGlobalObject):
-        * kjs/function_object.cpp:
-        (KJS::functionProtoFuncApply):
-        (KJS::functionProtoFuncCall):
-        * kjs/nodes.cpp:
-        (KJS::ExpressionNode::resolveAndCall):
-        (KJS::FunctionCallValueNode::evaluate):
-        (KJS::LocalVarFunctionCallNode::inlineEvaluate):
-        (KJS::ScopedVarFunctionCallNode::inlineEvaluate):
-        (KJS::FunctionCallBracketNode::evaluate):
-        (KJS::FunctionCallDotNode::inlineEvaluate):
-        * kjs/object.cpp:
-        (KJS::JSObject::call):
-        (KJS::JSObject::put):
-        (KJS::tryGetAndCallProperty):
-        (KJS::JSObject::lookupGetter):
-        (KJS::JSObject::lookupSetter):
-        (KJS::JSObject::toThisObject):
-        (KJS::JSObject::toGlobalObject):
-        (KJS::JSObject::fillGetterPropertySlot):
-        * kjs/object.h:
-        * kjs/object_object.cpp:
-        (KJS::objectProtoFuncLookupGetter):
-        (KJS::objectProtoFuncLookupSetter):
-        * kjs/string_object.cpp:
-        (KJS::replace):
-
-2008-04-08  Brady Eidson  <beidson@apple.com>
-
-        Encourage Windows to rebuild - AGAIN...
-
-        * kjs/DateMath.cpp:
-
-2008-04-08  Adam Roben  <aroben@apple.com>
-
-        Mac build fix
-
-        * JavaScriptCore.exp: Add callOnMainThread, and sorted the list.
-
-2008-04-08  Brady Eidson  <beidson@apple.com>
-
-        Rubberstamped by Adam Roben
-        
-        Touch some files to *strongly* encourage Windows to rebuilt with DOM_STORAGE enabled
-
-        * kjs/DateMath.cpp:
-
-2008-04-08  Adam Roben  <aroben@apple.com>
-
-        Move callOnMainThread to WTF
-
-        Reviewed by Alexey Proskuryakov.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        Added new files.
-
-        * wtf/MainThread.cpp:
-        * wtf/MainThread.h:
-        * wtf/gtk/MainThreadGtk.cpp:
-        * wtf/mac/MainThreadMac.mm:
-        * wtf/qt/MainThreadQt.cpp:
-        * wtf/win/MainThreadWin.cpp:
-        * wtf/wx/MainThreadWx.cpp:
-        Moved here from WebCore/platform. Replaced all instances of "WebCore"
-        with "WTF".
-
-        * kjs/bool_object.cpp: Touched to force JavaScriptCore.vcproj to
-        build.
-        to the WTF namespace.
-        * wtf/ThreadingWin.cpp:
-        (WTF::initializeThreading): Call initializeMainThread.
-
-2008-04-07  Brady Eidson  <beidson@apple.com>
-
-        Add "ENABLE_DOM_STORAGE" to keep in sync with the rest of the project
-
-        * Configurations/JavaScriptCore.xcconfig:
-
-2008-04-07  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * wtf/ThreadingWin.cpp: Back out some changes I didn't mean to land.
-
-2008-04-07  Adam Roben  <aroben@apple.com>
-
-        Add WTF::isMainThread
-
-        Reviewed by Alexey Proskuryakov.
-
-        * wtf/Threading.h: Declare the new function.
-        * wtf/ThreadingGtk.cpp:
-        (WTF::initializeThreading): Initialize the main thread identifier.
-        (WTF::isMainThread): Added.
-        * wtf/ThreadingNone.cpp: Ditto ThreadingGtk.cpp.
-        (WTF::initializeThreading):
-        (WTF::isMainThread):
-        * wtf/ThreadingPthreads.cpp: Ditto.
-        (WTF::initializeThreading):
-        (WTF::isMainThread):
-        * wtf/ThreadingWin.cpp: Ditto.
-        (WTF::initializeThreading):
-        (WTF::isMainThread):
-
-2008-04-06  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Make UString thread-safe.
-
-        No change on SunSpider total, although individual tests have changed a lot, up to 3%.
-
-        * kjs/InitializeThreading.cpp: (KJS::initializeThreading): Call UString::null() to initialize
-        a static.
-        
-        * kjs/identifier.cpp:
-        (KJS::CStringTranslator::translate):
-        (KJS::UCharBufferTranslator::translate):
-        Use "true" for a boolean value instead of 1, because it's C++.
-
-        * kjs/ustring.h:
-        (KJS::CString::adopt): Added a method to create from a char* buffer without copying.
-        (KJS::UString::Rep::ref): Removed an assertion for JSLock::lockCount, as it's no longer
-        necessary to hold JSLock when working with strings.
-        (KJS::UString::Rep::deref): Ditto.
-        (KJS::UString::Rep::isStatic): Added a field to quickly determine that this is an empty
-        or null static string.
-
-        * kjs/ustring.cpp:
-        (KJS::): Removed normalStatBufferSize and statBufferSize, as there is no reason to have such
-        an advanced implementation of a debug-only ascii() method. Removed a long-obsolete comment
-        about UChar.
-        (KJS::UString::Rep::createCopying): Removed an assertion for JSLock::lockCount.
-        (KJS::UString::Rep::create): Ditto.
-        (KJS::UString::Rep::destroy): Ditto. Do not do anything for static null and empty strings,
-        as refcounting is not reliable for those. Reordered branches for a noticeable speed gain -
-        apparently this functiton is hot enough for SunSpider to see an effect from this!
-        (KJS::UString::null): Moved a star, added a comment.
-        (KJS::UString::cstring): Reimplemented to not call ascii(), which is not thread-safe.
-        (KJS::UString::ascii): Simplified statBuffer handling logic.
-        (KJS::UString::toDouble): Use cstring() instead of ascii().
-
-2008-04-02  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Ensure that debug symbols are generated for x86_64 and ppc64 builds.
-
-        * Configurations/Base.xcconfig:
-
-2008-04-01  Christian Dywan  <christian@imendio.com>
-
-        Build fix for GCC 4.3.
-
-        * wtf/unicode/icu/CollatorICU.cpp: include string.h
-
-2008-04-01  Alexey Proskuryakov  <ap@webkit.org>
-
-        Rubber-stamped by Darin.
-
-        Turn off using 64-bit arithmetic on 32-bit hardware, as dtoa own code is faster than
-        compiler-provided emulation.
-
-        1% speedup on Acid3 test 26.
-
-        * kjs/dtoa.cpp:
-
-2008-04-01  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Make MathExtras.h thread safe.
-
-        * kjs/math_object.cpp:
-        (KJS::mathProtoFuncRandom): If threading is enabled, rely on initializeThreading to call
-        wtf_random_init().
-
-        * wtf/Threading.h:
-        * wtf/ThreadingGtk.cpp:
-        (WTF::initializeThreading):
-        * wtf/ThreadingNone.cpp:
-        (WTF::initializeThreading):
-        * wtf/ThreadingPthreads.cpp:
-        (WTF::initializeThreading):
-        * wtf/ThreadingWin.cpp:
-        (WTF::initializeThreading):
-        Call wtf_random_init(); made the function non-inline to avoid having to include too many
-        headers in Threading.h.
-
-2008-03-31  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-
-        Make matching of regexps using ^ much faster
-        http://bugs.webkit.org/show_bug.cgi?id=18086
-
-        * pcre/pcre_compile.cpp:
-        (compileBranch):
-        (branchNeedsLineStart):
-        * pcre/pcre_exec.cpp:
-        (match):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2008-03-29  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        <rdar://problem/5829556> REGRESSION: Leak in KJS::initializeThreading()
-
-        * kjs/InitializeThreading.cpp: (KJS::initializeThreading): There is no guarantee that
-        initializeThreading() is called only once; check that the mutex hasn't been already allocated.
-
-2008-03-29  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Bug 17924: Crash in KJS::ConstDeclNode::evaluate with |with| and |const|
-        <http://bugs.webkit.org/show_bug.cgi?id=17924>
-        <rdar://problem/5806933>
-
-        It turns out this is trivially avoidable if we just match firefox's
-        semantics and ensure that an assignment in a const declaration always
-        writes to the variable object.
-
-        * kjs/nodes.cpp:
-        (KJS::ConstDeclNode::handleSlowCase):
-
-2008-03-28  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Sam Weinig.
-
-        Fix a dtoa thread safety issue.
-
-        WebCore can call kjs_strtod without holding JS lock, but we didn't have thread safety
-        compiled in for dtoa.
-
-        This is a 0.5% regression on SunSpider, which Sam Weinig has volunteered to cover with
-        his recent improvement.
-
-        * kjs/dtoa.cpp:
-        (Bigint::Balloc):
-        (Bigint::Bfree):
-        Changed to use fastMalloc/fastDelete - they are much faster than the dtoa custom version was
-        in the presence of locking (but somewhat slower in single-threaded case).
-        (Bigint::pow5mult): Got rid of the dreaded double-checked locking anti-pattern (had to
-        restructure the code to avoid significant performance implications).
-        (Bigint::lshift): Rewrote to avoid an allocation, if possible.
-
-        (Bigint::rv_alloc):
-        (Bigint::kjs_freedtoa):
-        (Bigint::kjs_dtoa):
-        Check for USE(MULTIPLE_THREADS), not dtoa legacy MULTIPLE_THREADS.
-
-        * kjs/InitializeThreading.cpp: Added.
-        (KJS::initializeThreading):
-        * kjs/InitializeThreading.h: Added.
-        Initialize threading at KJS level, if enabled.
-
-        * kjs/dtoa.h: Expose dtoa mutex for KJS::initializeThreading.
-
-        * kjs/testkjs.cpp: (kjsmain): Call initializeThreading.
-
-        * JavaScriptCore.exp: Export KJS::initializeThreading.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.exp:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCoreSources.bkl:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        Added InitializeThreading.{h,cpp}.
-
-        * wtf/Threading.h: Removed a using directive for WTF::initializeThreading - it is only
-        to be called from KJS::initializeThreading, and having it in the global namespace is useless.
-
-2008-03-28  Brady Eidson  <beidson@apple.com>
-
-        Reviewed by Darin
-
-        Export Unicode/UTF8.h and convertUTF16ToUTF8() for more flexible conversion in WebCore
-
-        * JavaScriptCore.exp:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-03-27  Darin Adler  <darin@apple.com>
-
-        Reviewed by Mark Rowe.
-
-        <rdar://problem/5826236> Regular expressions with large nested repetition counts can have their
-        compiled length calculated incorrectly.
-
-        * pcre/pcre_compile.cpp:
-        (multiplyWithOverflowCheck):
-        (calculateCompiledPatternLength): Check for overflow when dealing with nested repetition counts
-        and bail with an error rather than returning incorrect results.
-
-2008-03-26  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Brady Eidson.
-
-        Update FEATURE_DEFINES to be consistent with the other locations in which it is defined.
-
-        * Configurations/JavaScriptCore.xcconfig:
-
-2008-03-26  Adam Roben  <aroben@apple.com>
-
-        Fix Bug 18060: Assertion failure (JSLock not held) beneath
-        JSCallbackObject<Base>::toString
-
-        <http://bugs.webkit.org/show_bug.cgi?id=18060>
-
-        Reviewed by Geoff Garen.
-
-        Bug fix:
-
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::JSCallbackObject<Base>::toString): Make the DropAllLocks
-        instance only be in scope while calling convertToType.
-
-        Test:
-
-        * API/testapi.c:
-        (MyObject_convertToType): Implement type conversion to string.
-        * API/testapi.js: Add a test for type conversion to string.
-
-2008-03-26  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * kjs/array_instance.cpp: Touched this.
-        * wtf/HashFunctions.h:
-        (WTF::intHash): Added 8- and 16-bit versions of intHash.
-
-2008-03-26  Adam Roben  <aroben@apple.com>
-
-        Force JSC headers to be copied by touching a file
-
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::getPropertyNames):
-
-2008-03-26  Adam Roben  <aroben@apple.com>
-
-        Windows build fix after r31324
-
-        Written with Darin.
-
-        Added HashTable plumbing to support using wchar_t as a key type.
-
-        * wtf/HashFunctions.h:
-        * wtf/HashTraits.h:
-        (WTF::):
-
-2008-03-26  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Darin.
-
-        - JSC part of fix for "SVG multichar glyph matching matches longest instead of first (affects Acid3 test 79)"
-        http://bugs.webkit.org/show_bug.cgi?id=18118
-
-        * wtf/HashFunctions.h:
-        (WTF::):
-        * wtf/HashTraits.h:
-        (WTF::):
-
-2008-03-26  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Cache C string identifiers by address, not value, assuming that C strings can only
-        be literals.
-
-        1% speedup on Acid3 test 26.
-
-        * kjs/identifier.cpp:
-        (KJS::literalIdentifierTable):
-        (KJS::Identifier::add):
-        Added a new table to cache UString::Reps created from C strings by address. Elements are
-        never removed from this cache, as only predefined identifiers can get there.
-
-        * kjs/identifier.h:
-        (KJS::Identifier::Identifier): Added a warning.
-
-2008-03-26  Alexey Proskuryakov  <ap@webkit.org>
-
-        Rubber-stamped by Maciej.
-
-        An assertion was failing in function-toString-object-literals.html when parsing 1e-500.
-        The condition existed before, and got uncovered by turning compiled-out dtoa checks into
-        ASSERTs.
-
-        The assertion was verifying that the caller wasn't constructing a Bigint from 0.
-        This might have had some reason behind it originally, but I couldn't find any,
-        and this doesn't look like a reasonable requirement.
-
-        * kjs/dtoa.cpp: (d2b): Removed the assertion (two copies in different code paths).
-
-2008-03-25  Adam Roben  <aroben@apple.com>
-
-        Fix Bug 18077: Integrate testapi.c into the Windows build
-
-        <http://bugs.webkit.org/show_bug.cgi?id=18077>
-
-        Reviewed by Steve Falkenburg.
-
-        * JavaScriptCore.vcproj/testapi/testapi.vcproj: Added.
-
-2008-03-25  Adam Roben  <aroben@apple.com>
-
-        Make testapi.c compile under MSVC
-
-        Currently you must compile testapi.c as C++ code since MSVC does not
-        support many C features that GCC does.
-
-        Reviewed by Steve Falkenburg.
-
-        * API/testapi.c:
-        (nan): Added an implementation of this for MSVC.
-        (assertEqualsAsUTF8String): Use malloc instead of dynamically-sized
-        stack arrays.
-        (assertEqualsAsCharactersPtr): Ditto.
-        (print_callAsFunction): Ditto.
-        (main): Ditto, and explicitly cast from UniChar* to JSChar*.
-
-2008-03-25  Adam Roben  <aroben@apple.com>
-
-        Stop using JavaScriptCore's custom stdbool.h and stdint.h on Windows
-
-        We can't remove the os-win32 directory yet because other ports (at
-        least wx) are still relying on it.
-
-        Reviewed by Steve Falkenburg.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-          - Made all the include paths match the one for the Debug
-            configuration (these got out of sync in r30797)
-          - Removed os-win32 from the include path
-          - Removed os-win32 from the directories we copy to $WebKitOutputDir.
-          - Removed stdint.h from the project
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
-        Delete the files that we may have previously copied from the os-win32
-        directory.
-
-2008-03-25  Alexey Proskuryakov  <ap@webkit.org>
-
-        Windows build fix.
-
-        * kjs/dtoa.cpp: Include stdint.h.
-
-2008-03-25  Alexey Proskuryakov  <ap@webkit.org>
-
-        Rubber-stamped by Darin.
-
-        Cleanup dtoa.cpp style.
-
-        * kjs/dtoa.cpp:
-        (Bigint::Balloc):
-        (Bigint::Bfree):
-        (Bigint::multadd):
-        (Bigint::s2b):
-        (Bigint::hi0bits):
-        (Bigint::lo0bits):
-        (Bigint::i2b):
-        (Bigint::mult):
-        (Bigint::pow5mult):
-        (Bigint::lshift):
-        (Bigint::cmp):
-        (Bigint::diff):
-        (Bigint::ulp):
-        (Bigint::b2d):
-        (Bigint::d2b):
-        (Bigint::ratio):
-        (Bigint::):
-        (Bigint::match):
-        (Bigint::hexnan):
-        (Bigint::kjs_strtod):
-        (Bigint::quorem):
-        (Bigint::rv_alloc):
-        (Bigint::nrv_alloc):
-        (Bigint::kjs_freedtoa):
-        (Bigint::kjs_dtoa):
-        * kjs/dtoa.h:
-
-2008-03-24  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        - convert a JavaScript immediate number to a string more efficiently
-
-        2% speedup of Acid3 test 26
-
-        * kjs/JSImmediate.cpp:
-        (KJS::JSImmediate::toString): Take advantage of the fact that all immediate
-        numbers are integers, and use the faster UString function for formatting integers
-        instead of the slower one that works for floating point. I think this is a leftover
-        from when immediate numbers were floating point.
-
-2008-03-23  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Darin Adler.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=18048
-        The "thisObject" parameter to JSEvaluateScript is not used properly
-
-        Making passing a thisObject to JSEvaluateScript actually set the thisObject of the created
-        ExecState.
-
-        * API/testapi.c:
-        (main): Add tests for setting the thisObject when calling JSEvaluateScript.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState): Assign the thisObject to m_thisValue and remove the comment. 
-
-2008-03-22  Jesse Ruderman  <jruderman@gmail.com>
-
-        Reviewed by Sam Weinig.  Landed by eseidel.
-        
-        Make testkjs flush stdout after printing.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/testkjs.cpp:
-        (functionPrint):
-
-2008-03-21  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Optimise lookup of Math, undefined, NaN and Infinity
-
-        Added a method to JSVariableObject to allow us to inject DontDelete properties
-        into the symbol table and localStorage.  This results in a 0.4% progression in
-        SunSpider, with a 8% gain in math-partial-sums.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset):
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTableInsert):
-
-2008-03-21  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff Garen.
-
-        Global properties that use LocalStorage are not correctly listed as enumerable.
-
-        The problem was caused by JSObject::getPropertyAttributes not being aware
-        of the JSVariableObject SymbolTable.  The fix is to make getPropertyAttributes
-        virtual and override in JSVariableObject.  This does not produce any performance
-        regression.
-
-        * JavaScriptCore.exp:
-        * kjs/JSVariableObject.cpp:
-        (KJS::JSVariableObject::getPropertyNames):
-        (KJS::JSVariableObject::getPropertyAttributes):
-        * kjs/JSVariableObject.h:
-        * kjs/object.h:
-
-2008-03-21  Arkadiusz Miskiewicz  <arekm@maven.pl>
-
-        Webkit does not build on linux powerpc
-
-        <http://bugs.webkit.org/show_bug.cgi?id=17019>
-
-        Reviewed by David Kilzer.
-
-        * wtf/TCSpinLock.h:
-        (TCMalloc_SpinLock::Unlock):
-
-2008-03-21  Rodney Dawes  <dobey@wayofthemonkey.com>
-
-        Reviewed by Holger.
-
-        http://bugs.webkit.org/show_bug.cgi?id=17981
-
-        Add javascriptcore_cppflags to Programs_minidom_CPPFLAGS.
-
-        * GNUmakefile.am:
-
-2008-03-21  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Consolidate static identifier initializers within CommonIdentifiers.
-
-        No reliably measurable change on SunSpider; maybe a tiny improvement (within 0.2%).
-
-        * kjs/CommonIdentifiers.h: Added static identifiers that were lazily initialized
-        throughout the code.
-
-        * kjs/date_object.cpp:
-        (KJS::DateObjectImp::DateObjectImp):
-        * kjs/function_object.cpp:
-        (KJS::FunctionPrototype::FunctionPrototype):
-        * kjs/object_object.cpp:
-        (KJS::ObjectPrototype::ObjectPrototype):
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpPrototype::RegExpPrototype):
-        Use the values from CommonIdentifiers. 
-
-        * kjs/lookup.h: Caching the identifier in a static wasn't a win on SunSpider, removed it.
-
-        * kjs/value.h:
-        (KJS::jsNaN): We already have a shared NaN value, no need for a duplicate here.
-
-        * wtf/MathExtras.h:
-        (wtf_atan2): Having local variables for numeric_limits constants is good for readability,
-        but there is no reason to keep them static.
-
-        * JavaScriptCore.exp: Don't needlessly export JSGlobalObject::s_head.
-
-2008-03-20  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Fix for leak introduced by inline ScopeChainNode use
-
-        To avoid any extra branches when managing an inline ScopeChainNode
-        in the ScopeChain the inline node gets inserted with a refcount of
-        2.  This meant than when the ScopeChain was destroyed the ScopeChainNodes
-        above the inline node would be leaked.
-
-        We resolve this by manually popping the inline node in the
-        FunctionExecState destructor.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/ExecStateInlines.h:
-        (KJS::FunctionExecState::~FunctionExecState):
-        * kjs/scope_chain.h:
-        (KJS::ScopeChain::popInlineScopeNode):
-
-2008-03-20  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Ensure that the defines in FEATURE_DEFINES are sorted so that they will match the default settings of build-webkit.
-        This will prevent the world from being rebuilt if you happen to switch between building in Xcode and with build-webkit on the
-        command-line.
-
-        * Configurations/JavaScriptCore.xcconfig:
-
-2008-03-20  David Krause  <david.krause@gmail.com>
-
-        Reviewed by David Kilzer.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=17923
-        Bug 17923: ARM platform endian defines inaccurate
-
-        * wtf/Platform.h: 
-        Replaced !defined(__ARMEL__) check with !defined(__VFP_FP__)
-        for PLATFORM(MIDDLE_ENDIAN)
-
-2008-03-20  Maciej Stachowiak  <mjs@apple.com>
-
-        - fix build
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: install Activation.h as private
-
-2008-03-20  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - reduce function call overhead for 1.014x speedup on SunSpider
-
-        I moved some functions from ExecState.cpp to ExecStateInline.h and
-        from JSGlobalObject.cpp to JSGlobalObject.h, and declared them
-        inline; machine function call overhead for these was hurting JS
-        funcion call overhead.
-        
-        * kjs/ExecState.cpp:
-        * kjs/ExecStateInlines.h: Added.
-        (KJS::ExecState::ExecState):
-        (KJS::ExecState::~ExecState):
-        (KJS::FunctionExecState::FunctionExecState):
-        (KJS::FunctionExecState::~FunctionExecState):
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::pushActivation):
-        (KJS::JSGlobalObject::checkActivationCount):
-        (KJS::JSGlobalObject::popActivation):
-        * kjs/function.cpp:
-
-2008-03-19  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Avoid heap allocating the root scope chain node for eval and closure free functions
-
-        Maciej suggested using an inline ScopeChainNode for functions that don't use eval
-        or closures as they are unable to ever capture the scope chain.  This gives us a 2.4%
-        win in sunspider, a 15% win in controlflow-recursive, and big (>5%) wins in a number 
-        of other tests.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        * kjs/ExecState.h:
-        * kjs/scope_chain.h:
-        (KJS::ScopeChain::push):
-
-2008-03-19  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Fix release build.
-
-        * kjs/JSGlobalObject.cpp:  Add missing #include.
-
-2008-03-19  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Anders Carlsson.
-
-        Fix for <rdar://problem/5785694>
-        Crash occurs at KJS::Collector::collect() when loading web clip widgets with a PAC file
-
-        Make the activeExecStates stack per JSGlobalObject instead of static to ensure
-        thread safety.
-
-        * JavaScriptCore.exp:
-        * kjs/ExecState.cpp:
-        (KJS::InterpreterExecState::InterpreterExecState):
-        (KJS::InterpreterExecState::~InterpreterExecState):
-        (KJS::EvalExecState::EvalExecState):
-        (KJS::EvalExecState::~EvalExecState):
-        (KJS::FunctionExecState::FunctionExecState):
-        (KJS::FunctionExecState::~FunctionExecState):
-        * kjs/ExecState.h:
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::mark):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::activeExecStates):
-        * kjs/collector.cpp:
-        (KJS::Collector::collect):
-        (KJS::Collector::reportOutOfMemoryToAllExecStates): Iterate all JSGlobalObjects and report
-        the OutOfMemory condition to all the ExecStates in each.
-
-2008-03-19  Jasper Bryant-Greene  <jasper@unix.geek.nz>
-
-        Reviewed by Maciej Stachowiak.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=17941
-        Bug 17941: C++-style comments in JavaScriptCore API
-
-        * API/JSBase.h:
-        Remove C++-style comments from public JavaScriptCore API, replacing
-        with standard C90 block comments.
-
-2008-03-19  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=17939
-        Bug 17939: Crash decompiling "const a = 1, b;"
-
-        * kjs/nodes2string.cpp:
-        (KJS::ConstDeclNode::streamTo): Null-check the correct variable.
-
-2008-03-18  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Mark Rowe.
-
-        Bug 17929: Incorrect decompilation with |const|, comma
-        http://bugs.webkit.org/show_bug.cgi?id=17929
-
-        There were actually two bugs here. First we weren't correctly handling const
-        nodes with multiple declarations. The second issue was caused by us not 
-        giving the correct precedence to the initialisers.
-
-        * kjs/nodes2string.cpp:
-        (KJS::ConstDeclNode::streamTo):
-
-2008-03-18  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - Speed up JavaScript built-in properties by changing the
-          hash table to take advantage of the identifier objects
-
-        5% speedup for Acid3 test 26
-
-        * JavaScriptCore.exp: Updated.
-        * kjs/create_hash_table: Compute size of hash table large enough so that there
-        are no collisions, but don't generate the hash table.
-        * kjs/identifier.h: Made the add function that returns a PassRefPtr public.
-        * kjs/lexer.cpp:
-        (KJS::Lexer::lex): Updated for change to HashTable interface.
-        * kjs/lookup.cpp:
-        (KJS::HashTable::changeKeysToIdentifiers): Added. Finds the identifier for
-        each property so the equality comparision can be done with pointer comparision.
-        * kjs/lookup.h: Made the key be a union of char* with UString::Rep* so it can
-        hold identifiers. Added a keysAreIdentifiers flag to the HashTable. Changed
-        the Lookup functions to be member functions of HashTable instead.
-        * kjs/object.cpp:
-        (KJS::JSObject::deleteProperty): Update for change to HashTable.
-        (KJS::JSObject::findPropertyHashEntry): Ditto.
-        (KJS::JSObject::getPropertyAttributes): Ditto.
-        (KJS::JSObject::getPropertyNames): Ditto.
-
-2008-03-18  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=17925 and http://bugs.webkit.org/show_bug.cgi?id=17927.
-        - Bug 17925: Crash in KJS::JSObject::put after setting this.__proto__
-        - Bug 17927: Hang after attempting to create circular __proto__
-
-        * kjs/object.cpp:
-        (KJS::JSObject::put): Silently ignore attempts to set __proto__ to a non-object, non-null value.
-        Return after setting the exception when an attempt to set a cyclic __proto__ is detected so that
-        the cyclic value is not set.
-
-2008-03-18  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - inline ActivationImp::init for 0.8% SunSpider speedup
-
-        * kjs/Activation.h:
-        (KJS::ActivationImp::init): Moved here from function.cpp
-        * kjs/function.cpp:
-
-2008-03-18  Simon Hausmann  <hausmann@webkit.org>
-
-        Fix the Qt build.
-
-        Including config.h like in the other .cpp files gets the #ifdeffery
-        correct for rand_s.
-
-        * kjs/JSWrapperObject.cpp:
-
-2008-03-17  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        JavaScriptCore changes to support a WebCore speedup.
-
-        * JavaScriptCore.exp: Export the UString::Rep::computeHash function.
-        * wtf/HashSet.h: Added a find and contains function that take a translator,
-        like the add function.
-
-2008-03-18  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - a few micro-optimizations for 1.2% SunSpider speedup
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction): check for Return completion before Throw,
-        it is more likely.
-        * kjs/object.cpp:
-        (KJS::JSObject::put): When walking prototype chain, instead of
-        checking isObject (a virtual call), compare to jsNull (compare to
-        a constant) since null is the only non-object that can be in a
-        prototype chain.
-
-2008-03-17  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Optimise multi-scope function call resolution
-
-        Refactor multiscope variable resolution and use to add
-        optimised FunctionCallResolveNode subclasses.  
-
-        2.6% gain in sunspider performance, *25%* gain in controlflow-recursive
-
-        * kjs/nodes.cpp:
-        (KJS::getSymbolTableEntry):
-        (KJS::ResolveNode::optimizeVariableAccess):
-        (KJS::getNonLocalSymbol):
-        (KJS::ExpressionNode::resolveAndCall):
-        (KJS::FunctionCallResolveNode::optimizeVariableAccess):
-        (KJS::FunctionCallResolveNode::inlineEvaluate):
-        (KJS::ScopedVarFunctionCallNode::inlineEvaluate):
-        (KJS::ScopedVarFunctionCallNode::evaluate):
-        (KJS::ScopedVarFunctionCallNode::evaluateToNumber):
-        (KJS::ScopedVarFunctionCallNode::evaluateToBoolean):
-        (KJS::ScopedVarFunctionCallNode::evaluateToInt32):
-        (KJS::ScopedVarFunctionCallNode::evaluateToUInt32):
-        (KJS::NonLocalVarFunctionCallNode::inlineEvaluate):
-        (KJS::NonLocalVarFunctionCallNode::evaluate):
-        (KJS::NonLocalVarFunctionCallNode::evaluateToNumber):
-        (KJS::NonLocalVarFunctionCallNode::evaluateToBoolean):
-        (KJS::NonLocalVarFunctionCallNode::evaluateToInt32):
-        (KJS::NonLocalVarFunctionCallNode::evaluateToUInt32):
-        * kjs/nodes.h:
-        (KJS::ScopedVarFunctionCallNode::):
-        (KJS::NonLocalVarFunctionCallNode::):
-
-2008-03-17  David Kilzer  <ddkilzer@apple.com>
-
-        Don't define PLATFORM(MIDDLE_ENDIAN) on little endian ARM.
-
-        Reviewed by Darin.
-
-        See <http://bugs.webkit.org/show_bug.cgi?id=15416#c13>.
-
-        * wtf/Platform.h: Added check for !defined(__ARMEL__) when defining
-        PLATFORM(MIDDLE_ENDIAN).
-
-2008-03-17  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff, Darin and Weinig.
-
-        Add fast multi-level scope lookup
-        
-        Add logic and AST nodes to provide rapid variable resolution across
-        static scope boundaries.  This also adds logic that allows us to skip
-        any static scopes that do not contain the variable to be resolved.
-        
-        This results in a ~2.5% speedup in SunSpider, and gives a 25-30% speedup
-        in some simple and ad hoc closure and global variable access tests.
-
-        * JavaScriptCore.exp:
-        * kjs/Activation.h:
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSGlobalObject.h:
-        * kjs/JSVariableObject.cpp:
-        * kjs/JSVariableObject.h:
-        * kjs/function.cpp:
-        (KJS::ActivationImp::isDynamicScope):
-        * kjs/nodes.cpp:
-        (KJS::ResolveNode::optimizeVariableAccess):
-        (KJS::ScopedVarAccessNode::inlineEvaluate):
-        (KJS::ScopedVarAccessNode::evaluate):
-        (KJS::ScopedVarAccessNode::evaluateToNumber):
-        (KJS::ScopedVarAccessNode::evaluateToBoolean):
-        (KJS::ScopedVarAccessNode::evaluateToInt32):
-        (KJS::ScopedVarAccessNode::evaluateToUInt32):
-        (KJS::NonLocalVarAccessNode::inlineEvaluate):
-        (KJS::NonLocalVarAccessNode::evaluate):
-        (KJS::NonLocalVarAccessNode::evaluateToNumber):
-        (KJS::NonLocalVarAccessNode::evaluateToBoolean):
-        (KJS::NonLocalVarAccessNode::evaluateToInt32):
-        (KJS::NonLocalVarAccessNode::evaluateToUInt32):
-        (KJS::IfElseNode::optimizeVariableAccess):
-        (KJS::ScopeNode::optimizeVariableAccess):
-        * kjs/nodes.h:
-        (KJS::ScopedVarAccessNode::):
-        (KJS::NonLocalVarAccessNode::):
-        * kjs/object.h:
-
- 2008-03-16  weihongzeng  <weihong.zeng@hotmail.com>
-         Reviewed by Darin Adler.
-         http://bugs.webkit.org/show_bug.cgi?id=15416
-         Add support for mixed-endian processors
-         * kjs/dtoa.cpp: Add IEEE_ARM, triggered by PLATFORM(MIDDLE_ENDIAN).
-2008-03-16  Kevin Ollivier  <kevino@theolliviers.com>
-
-        Rubber stamped by Darin.
-
-        Add set-webkit-configuration support for wx port, and centralize
-        build dir location setting.
-
-        http://bugs.webkit.org/show_bug.cgi?id=17790
-
-        * jscore.bkl:
-
-2008-03-14  Steve Falkenburg  <sfalken@apple.com>
-
-        PGO build fixes.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-03-14  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Add logic to track whether a function uses a locally scoped eval or requires a closure
-        
-        Now that we limit eval we can track those uses of eval that operate
-        in the local scope and functions that require a closure.  We track
-        this information during initial parsing to avoid yet another tree
-        walk.
-
-        * JavaScriptCore.exp:
-        * kjs/NodeInfo.h:
-        * kjs/Parser.cpp:
-        (KJS::Parser::didFinishParsing):
-        * kjs/Parser.h:
-        (KJS::Parser::parse):
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::ScopeNode::ScopeNode):
-        (KJS::ProgramNode::ProgramNode):
-        (KJS::ProgramNode::create):
-        (KJS::EvalNode::EvalNode):
-        (KJS::EvalNode::create):
-        (KJS::FunctionBodyNode::FunctionBodyNode):
-        (KJS::FunctionBodyNode::create):
-        * kjs/nodes.h:
-        (KJS::ScopeNode::):
-        (KJS::ScopeNode::usesEval):
-        (KJS::ScopeNode::needsClosure):
-
-2008-03-14  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Beth Dakin.
-
-        Fixed another problem with Vector::shrinkCapacity.
-        
-        moveOverlapping isn't good enough for the case where the buffer hasn't
-        changed, because it still destroys the contents of the buffer.
-
-        * wtf/Vector.h:
-        (WTF::::shrinkCapacity): Changed to explicitly check whether the call
-        to allocateBuffer produced a new buffer. If it didn't, there's no need
-        to move.
-
-2008-03-14  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Beth Dakin.
-        
-        Fixed a few problems with Vector::shrinkCapacity that I noticed in testing.
-
-        * wtf/Vector.h:
-        (WTF::VectorBufferBase::deallocateBuffer): Clear our m_buffer pointer
-        when we deallocate m_buffer, in case we're not asked to reallocate a new
-        buffer. (Otherwise, we would use a stale m_buffer if we were asked to
-        perform any operations after shrinkCapacity was called.)
-        
-        (WTF::VectorBuffer::allocateBuffer): Made VectorBuffer with inline
-        capacity aware that calls to allocateBuffer might be shrinks, rather
-        than grows, so we shouldn't allocate a new buffer on the heap unless
-        our inline buffer is too small.
-        
-        (WTF::::shrinkCapacity): Call resize() instead of just setting m_size,
-        so destructors run. Call resize before reallocating the buffer to make
-        sure that we still have access to the objects we need to destroy. Call
-        moveOverlapping instead of move, since a call to allocateBuffer on an
-        inline buffer may produce identical storage.
-
-2008-03-14  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Get rid of a localime() call on platforms that have better alternatives.
-
-        * kjs/DateMath.h: Added getLocalTime();
-
-        * kjs/DateMath.cpp:
-        (KJS::getLocalTime):
-        (KJS::getDSTOffsetSimple):
-        Implementation moved from getDSTOffsetSimple().
-
-        * kjs/date_object.cpp:
-        (KJS::DateObjectImp::callAsFunction): Switched to getLocalTime().
-
-2008-03-14  David D. Kilzer  <ddkilzer@apple.com>
-
-        Unify concept of enabling the Mac Java bridge.
-
-        Reviewed by Darin and Anders.
-
-        * wtf/Platform.h: Define ENABLE_MAC_JAVA_BRIDGE here.
-
-2008-03-13  Mark Mentovai  <mark@moxienet.com>
-
-        Reviewed by eseidel.  Landed by eseidel.
-
-        * wtf/FastMalloc.cpp: #include <wtf/HashSet.h> outside of any
-        namespaces.
-
-2008-03-13  Mark Mentovai  <mark@moxienet.com>
-
-        Reviewed by eseidel.  Landed by eseidel.
-
-        * pcre/pcre_exec.cpp: Fix misnamed variable, allowing -DDEBUG build
-        to succeed.
-        * wtf/ThreadingPthreads.cpp: #include <sys/time.h> for gettimeofday
-        in non-pch build.
-
-2008-03-13  Steve Falkenburg  <sfalken@apple.com>
-
-        PGO build fixes.
-        
-        Disable PGO for normal release builds.
-        Added work-in-progress Release_PGOInstrument/Release_PGOOptimize targets.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-03-13  Beth Dakin  <bdakin@apple.com>
-
-        Reviewed by Geoff.
-
-        Adding new functionality to Vector. Currently all of the shrink and 
-        resize functions on Vector only shrink the size of the Vector, not 
-        the capacity. For the Vector to take up as little memory as 
-        possible, though, it is necessary to be able to shrink the capacity 
-        as well. So this patch adds that functionality. 
-
-        I need this for a speed up I am working on, and Geoff wants to use 
-        it in a speed up he is working on also, so he asked me to commit it 
-        now. 
-
-        * wtf/Vector.h:
-        (WTF::VectorBufferBase::allocateBuffer):
-        (WTF::::shrinkCapacity):
-
-2008-03-13  Simon Hausmann  <hausmann@webkit.org>
-
-        Reviewed by Adam Roben.
-
-        Attempt at fixing the Qt/Windows build bot. Quote using double-quotes
-        instead of single quotes.
-
-        * pcre/dftables:
-
-2008-03-12  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-
-2008-03-12  Alp Toker  <alp@atoker.com>
-
-        Another autotools testkjs build fix attempt.
-
-        * GNUmakefile.am:
-
-2008-03-12  Alp Toker  <alp@atoker.com>
-
-        Attempt to fix the autotools testkjs build on systems with
-        non-standard include paths.
-
-        * GNUmakefile.am:
-
-2008-03-11  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5787743> REGRESSION: Crash at WTF::Collator::CreateCollator() running fast/js/kde/StringObject.html on Windows
-
-        * wtf/unicode/icu/CollatorICU.cpp:
-        (WTF::Collator::createCollator): Check for null (== user default) m_locale before calling strcmp.
-
-2008-03-11  Steve Falkenburg  <sfalken@apple.com>
-
-        Disable LTCG/PGO for grammar.cpp and nodes.cpp.
-        PGO on these files causes us to hang.
-        
-        Copy newer vsprops files from relative WebKitLibraries path to environment variable based path.
-        
-        Reviewed by Oliver.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
-
-2008-03-10  Darin Adler  <darin@apple.com>
-
-        - Windows build fix
-
-        * kjs/function.cpp: (KJS::decode): Initialize variable.
-
-2008-03-10  Brent Fulgham  <bfulgham@gmail.com>
-
-        Windows build fix
-
-        Reviewed by Adam.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
-        Set the PATH to include Cygwin before running touch.
-
-2008-03-10  Eric Seidel  <eric@webkit.org>
-
-        Build fix for JSC on windows.
-
-        * API/JSStringRefCF.cpp:
-        (JSStringCreateWithCFString):
-        * kjs/function.cpp:
-        (KJS::decode):
-        * kjs/nodes2string.cpp:
-        (KJS::escapeStringForPrettyPrinting):
-
-2008-03-10  Eric Seidel  <eric@webkit.org>
-        
-        No review, build fix only.
-        
-        Attempt to fix the windows build?
-
-        * kjs/ustring.h: change unsigned short to UChar
-
-2008-03-10  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Darin.
-
-        Remove KJS::UChar, use ::UChar instead
-        http://bugs.webkit.org/show_bug.cgi?id=17017
-
-        * API/JSStringRef.cpp:
-        (JSStringCreateWithCharacters):
-        (JSStringCreateWithUTF8CString):
-        * API/JSStringRefCF.cpp:
-        (JSStringCreateWithCFString):
-        * JavaScriptCore.exp:
-        * kjs/Parser.h:
-        * kjs/function.cpp:
-        (KJS::decode):
-        (KJS::parseInt):
-        (KJS::parseFloat):
-        (KJS::globalFuncEscape):
-        (KJS::globalFuncUnescape):
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct):
-        * kjs/identifier.cpp:
-        (KJS::Identifier::equal):
-        (KJS::CStringTranslator::translate):
-        * kjs/interpreter.h:
-        * kjs/lexer.cpp:
-        (KJS::Lexer::setCode):
-        (KJS::Lexer::shift):
-        (KJS::Lexer::lex):
-        (KJS::Lexer::convertUnicode):
-        (KJS::Lexer::makeIdentifier):
-        * kjs/lookup.cpp:
-        (KJS::keysMatch):
-        * kjs/nodes2string.cpp:
-        (KJS::escapeStringForPrettyPrinting):
-        (KJS::SourceStream::operator<<):
-        * kjs/regexp.cpp:
-        (KJS::RegExp::RegExp):
-        (KJS::RegExp::match):
-        * kjs/string_object.cpp:
-        (KJS::substituteBackreferences):
-        (KJS::stringProtoFuncCharCodeAt):
-        (KJS::stringProtoFuncToLowerCase):
-        (KJS::stringProtoFuncToUpperCase):
-        (KJS::stringProtoFuncToLocaleLowerCase):
-        (KJS::stringProtoFuncToLocaleUpperCase):
-        * kjs/ustring.cpp:
-        (KJS::UString::Rep::computeHash):
-        (KJS::UString::UString):
-        (KJS::UString::append):
-        (KJS::UString::ascii):
-        (KJS::UString::operator=):
-        (KJS::UString::is8Bit):
-        (KJS::UString::toStrictUInt32):
-        (KJS::UString::find):
-        (KJS::operator==):
-        (KJS::operator<):
-        (KJS::compare):
-        (KJS::UString::UTF8String):
-        * kjs/ustring.h:
-        * pcre/pcre.h:
-
-2008-03-09  Steve Falkenburg  <sfalken@apple.com>
-
-        Stop Windows build if an error occurs in a prior project.
-
-        Rubber stamped by Darin.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj:
-
-2008-03-09  J¸rg Billeter  <j@bitron.ch>
-
-        Reviewed by Alp Toker.
-
-        Conditionalise ICU for Unicode in the GTK+ port.
-
-        * wtf/Platform.h:
-
-2008-03-07  David D. Kilzer  <ddkilzer@apple.com>
-
-        Unify concept of enabling Netscape Plug-in API (NPAPI).
-
-        Reviewed by Darin.
-
-        * wtf/Platform.h: Define ENABLE_NETSCAPE_PLUGIN_API here.
-
-2008-03-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Fixed <rdar://problem/5689093> Stricter (ES4) eval semantics
-        
-        The basic rule is:
-        
-        - "eval(s)" is treated as an operator that gives the ES3 eval behavior.
-            ... but only if there is no overriding declaration of "eval" in scope.
-        - All other invocations treat eval as a function that evaluates a
-        script in the context of its "this" object.
-            ... but if its "this" object is not the global object it was
-            originally associated with, eval throws an exception.
-        
-        Because only expressions of the form "eval(s)" have access to local
-        scope, the compiler can now statically determine whether a function
-        needs local scope to be dynamic.
-
-        * kjs/nodes.h: Added FunctionCallEvalNode. It works just like
-        FuncationCallResolveNode, except it statically indicates that the node
-        may execute eval in the ES3 way.
-        * kjs/nodes.cpp:
-        * kjs/nodes2string.cpp:
-
-        * tests/mozilla/expected.html: This patch happens to fix a Mozilla JS
-        test, but it's a bit of a pyrrhic victory. The test intends to test
-        Mozilla's generic API for calling eval on any object, but, in reality,
-        we only support calling eval on the global object.
-
-2008-03-06  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj:
-
-2008-03-06  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-
-2008-03-06  Alp Toker  <alp@atoker.com>
-
-        Fix the build fix in r30845 to support out-of-tree builds.
-
-        * GNUmakefile.am:
-
-2008-03-06  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-
-        * wtf/ThreadingWin.cpp:
-        (WTF::ThreadCondition::timedWait):
-
-2008-03-06  Darin Adler  <darin@apple.com>
-
-        - another small step towards fixing the Qt build
-
-        * JavaScriptCore.pri: Remove more references to the now-obsolete bindings directory.
-
-2008-03-06  Darin Adler  <darin@apple.com>
-
-        - a small step towards fixing the Qt build
-
-        * JavaScriptCore.pri: Remove references to files no longer present in JavaScriptCore/bindings.
-
-2008-03-06  Brady Eidson  <beidson@apple.com>
-
-        Gtk Build fix
-
-        * wtf/ThreadingGtk.cpp:
-        (WTF::ThreadCondition::timedWait):
-
-2008-03-06  Alexey Proskuryakov  <ap@webkit.org>
-
-        Wx build fix.
-
-        * wtf/unicode/icu/CollatorICU.cpp:
-        (WTF::Collator::userDefault): Put ICU workaround under both PLATFORM(DARWIN) and
-        PLATFORM(CF) checks, so that each port can decide if it wants to use CF on Mac for it.
-
-2008-03-06  Brady Eidson <beidson@apple.com>
-
-        Reviewed by Darin
-
-        Add a timedWait() method to ThreadCondition
-
-        * JavaScriptCore.exp:
-
-        * wtf/Threading.h:
-
-        * wtf/ThreadingGtk.cpp:
-        (WTF::ThreadCondition::timedWait):
-
-        * wtf/ThreadingNone.cpp:
-        (WTF::ThreadCondition::timedWait):
-
-        * wtf/ThreadingPthreads.cpp:
-        (WTF::ThreadCondition::timedWait):
-
-        * wtf/ThreadingWin.cpp:
-        (WTF::ThreadCondition::timedWait): Needs implementation
-
-2008-03-06  Alexey Proskuryakov  <ap@webkit.org>
-
-        More build fixes.
-
-        * jscore.bkl: Add the wtf/unicode directory.
-        * wtf/unicode/CollatorDefault.cpp:
-        (WTF::Collator::userDefault): Use a constructor that does exist.
-        * wtf/unicode/icu/CollatorICU.cpp: Mac build fix for case-sensitive file systems.
-
-2008-03-06  Darin Adler  <darin@apple.com>
-
-        - try to fix the Qt build
-
-        * JavaScriptCore.pri: Add the wtf/unicode directory.
-
-2008-03-06  Darin Adler  <darin@apple.com>
-
-        - try to fix the GTK build
-
-        * GNUmakefile.am: Add a -I for the wtf/unicode directory.
-
-2008-03-06  Darin Adler  <darin@apple.com>
-
-        - try to fix the Mac build
-
-        * icu/unicode/parseerr.h: Copied from ../WebCore/icu/unicode/parseerr.h.
-        * icu/unicode/ucol.h: Copied from ../WebCore/icu/unicode/ucol.h.
-        * icu/unicode/uloc.h: Copied from ../WebCore/icu/unicode/uloc.h.
-        * icu/unicode/unorm.h: Copied from ../WebCore/icu/unicode/unorm.h.
-        * icu/unicode/uset.h: Copied from ../WebCore/icu/unicode/uset.h.
-
-2008-03-06  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5687269> Need to create a Collator abstraction for WebCore and JavaScriptCore
-
-        * wtf/Threading.h:
-        (WTF::initializeThreading):
-        * wtf/ThreadingGtk.cpp:
-        (WTF::initializeThreading):
-        * wtf/ThreadingNone.cpp:
-        * wtf/ThreadingPthreads.cpp:
-        * wtf/ThreadingWin.cpp:
-        Added AtomicallyInitializedStatic.
-
-        * kjs/string_object.cpp: (KJS::localeCompare): Changed to use Collator.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.exp:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        Added new fiiles to projects.
-
-        * wtf/unicode/Collator.h: Added.
-        (WTF::Collator::):
-        * wtf/unicode/CollatorDefault.cpp: Added.
-        (WTF::Collator::Collator):
-        (WTF::Collator::~Collator):
-        (WTF::Collator::setOrderLowerFirst):
-        (WTF::Collator::collate):
-        * wtf/unicode/icu/CollatorICU.cpp: Added.
-        (WTF::cachedCollatorMutex):
-        (WTF::Collator::Collator):
-        (WTF::Collator::~Collator):
-        (WTF::Collator::setOrderLowerFirst):
-        (WTF::Collator::collate):
-        (WTF::Collator::createCollator):
-        (WTF::Collator::releaseCollator):
-
-2008-03-05  Kevin Ollivier  <kevino@theolliviers.com>
-
-        Fix the wx build after the bindings move.
-
-        * JavaScriptCoreSources.bkl:
-        * jscore.bkl:
-
-2008-03-05  Alp Toker  <alp@atoker.com>
-
-        GTK+ build fix for breakage introduced in r30800.
-
-        Track moved bridge sources from JavaScriptCore to WebCore.
-
-        * GNUmakefile.am:
-
-2008-03-05  Brent Fulgham  <bfulgham@gmail.com>
-
-        Reviewed by Adam Roben.
-
-        Remove definition of WTF_USE_SAFARI_THEME from wtf/Platform.h
-        because the PLATFORM(CG) flag is not set until config.h has
-        already included this file.
-
-        * wtf/Platform.h:  Remove useless definition of WTF_USE_SAFARI_THEME
-
-2008-03-05  Brady Eidson  <beidson@apple.com>
-
-        Reviewed by Alexey and Mark Rowe
-
-        Fix for <rdar://problem/5778247> - Reproducible crash on storage/execute-sql-args.html
-
-        DatabaseThread::unscheduleDatabaseTasks() manually filters through a MessageQueue,
-        removing particular items for Databases that were shutting down.
-
-        This filtering operation is not atomic, and therefore causes a race condition with the
-        MessageQueue waking up and reading from the message queue.  
-
-        The end result was an attempt to dereference a null DatabaseTask.  Timing-wise, this never
-        seemed to happen in a debug build, otherwise an assertion would've caught it.  Replacing that
-        assertion with a crash in a release build is what revealed this bug.
-
-        * wtf/MessageQueue.h:
-        (WTF::::waitForMessage): Tweak the waiting logic to check the queue's empty state then go back
-          to sleep if the queue was empty - checking m_killed each time it wakes up.
-
-2008-03-05  David D. Kilzer  <ddkilzer@apple.com>
-
-        Remove unused header includes from interpreter.cpp.
-
-        Reviewed by Darin.
-
-        * kjs/interpreter.cpp: Remove unused header includes.
-
-2008-03-05  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Sam.
-        
-        Remove bindings/.
-
-        * bindings: Removed.
-
-2008-03-05  Anders Carlsson  <andersca@apple.com>
-
-        Don't build bindings/ anymore.
-        
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2008-03-05  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Geoff.
-
-        Don't build JavaScriptCore/bindings.
-        
-        * JavaScriptCore.exp:
-        Export a couple of new functions. 
-        
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        Remove bindings/
-        
-        * kjs/config.h:
-        No need to define HAVE_JNI anymore.
-        
-        * kjs/interpreter.cpp:
-        Remove unnecessary include.
-
-2008-03-05  David D. Kilzer  <ddkilzer@apple.com>
-
-        Allow override of default script file name using command-line argument.
-
-        Reviewed by Adele.
-
-        * API/minidom.c:
-        (main): Allow first command-line argument to override the default script
-        file name of "minidom.js".
-        * API/testapi.c:
-        (main): Allow first command-line argument to override the default script
-        file name of "testapi.js".
-
-2008-03-04  Mark Rowe  <mrowe@apple.com>
-
-        Mac build fix.
-
-        * JavaScriptCore.exp:  Add new symbol to exports file.
-
-2008-03-03  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Anders.
-
-        Make ForInNode check for the timeout interrupt
-
-        * kjs/nodes.cpp:
-        (KJS::ForInNode::execute):
-
-2008-03-02  Brent Fulgham  <bfulgham@gmail.com>
-
-        Reviewed by Alp Toker.
-
-        http://bugs.webkit.org/show_bug.cgi?id=17415
-        GTK Build (using autotools) on Mac OS (DarwinPorts) Fails
-
-        Add -lstdc++ to link flags for minidom program.  This corrects
-        a build error for the GTK+ on Mac OS.
-
-        * GNUmakefile.am:
-
-2008-03-01  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Tim Hatcher.
-
-        Update Xcode configuration to support building debug and release from the mysterious future.
-
-        * Configurations/Base.xcconfig:
-        * Configurations/DebugRelease.xcconfig:
-
-2008-02-29  Brent Fulgham  <bfulgham@gmail.com>
-
-        http://bugs.webkit.org/show_bug.cgi?id=17483
-        Implement scrollbars on Windows (Cairo)
-
-        Reviewed by Adam Roben.
-
-        * wtf/Platform.h:
-
-2008-02-29  Adam Roben  <aroben@apple.com>
-
-        Remove unused DebuggerImp::abort and DebuggerImp::aborted
-
-        Reviewed by Tim and Sam.
-
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct):
-        * kjs/internal.h:
-        (KJS::DebuggerImp::DebuggerImp):
-        * kjs/nodes.cpp:
-        (KJS::Node::handleException):
-        (KJS::FunctionBodyNodeWithDebuggerHooks::execute):
-
-2008-02-28  Eric Christopher  <echristo@apple.com>
-
-        Reviewed by Geoffrey Garen.
-
-        ** TOTAL **:          1.005x as fast    2867.6ms +/- 0.4%  2853.2ms +/- 0.3%    significant
-
-        * kjs/nodes.cpp: Tell the compiler that exceptions are unexpected (for
-        the sake of branch prediction and code organization).
-
-2008-02-27  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Sam Weinig.
-
-        http://bugs.webkit.org/show_bug.cgi?id=17030
-        Small buffer overflow within initialization
-
-        * kjs/date_object.cpp:
-        (KJS::DateObjectFuncImp::callAsFunction):
-        (KJS::parseDate):
-        Remove unnecessary and incorrect memset() calls - GregorianDateTime can initialize itself.
-
-2008-02-25  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Dan Bernstein.
-
-        - Add a variant of remove that takes a position and a length.
-
-        * wtf/Vector.h:
-        (WTF::Vector::remove):
-
-2008-02-25  Mark Mentovai  <mark@moxienet.com>
-
-        Reviewed by Mark Rowe.
-
-        Enable CollectorHeapIntrospector to build by itself, as well as in an AllInOneFile build.
-        http://bugs.webkit.org/show_bug.cgi?id=17538
-
-        * kjs/CollectorHeapIntrospector.cpp: Provide "using" declaration for
-          WTF::RemoteMemoryReader.
-        * kjs/collector.h: Move CollectorHeap declaration here...
-        * kjs/collector.cpp: ... from here.
-
-2008-02-25  Darin Adler  <darin@apple.com>
-
-        Reviewed by Adam.
-
-        * JavaScriptCore.exp: Sort the contents of this file.
-
-2008-02-25  Adam Roben  <aroben@apple.com>
-
-        MSVC build fix
-
-        * kjs/testkjs.cpp:
-        (functionQuit): Don't add a return statement after exit(0) for MSVC.
-
-2008-02-24  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Mark Rowe.
-
-        http://bugs.webkit.org/show_bug.cgi?id=17529
-        Add support for reading from stdin from testkjs
-
-        * kjs/testkjs.cpp:
-        (GlobalObject::GlobalObject): Add readline function to global object.
-        (functionReadline): Added. Reads characters from stdin until a '\n' or
-        EOF is encountered. The input is returned as a String to the caller.
-
-2008-02-24  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Mark Rowe.
-
-        http://bugs.webkit.org/show_bug.cgi?id=17528
-        Give testkjs a bath
-
-        * JavaScriptCore.exp:
-        * JavaScriptCore.xcodeproj/project.pbxproj: Make the testkjs.cpp use 4 space indentation.
-        * kjs/testkjs.cpp:
-        (StopWatch::getElapsedMS):
-        (GlobalObject::className):
-        (GlobalObject::GlobalObject):
-        Rename GlobalImp to GlobalObject and setup the global functions
-        in the GlobalObject's constructor. Also, use static functions for
-        the implementation so we can use the standard PrototypeFunction
-        class and remove TestFunctionImp.
-        (functionPrint): Move print() functionality here.
-        (functionDebug): Move debug() functionality here.
-        (functionGC): Move gc() functionality here.
-        (functionVersion): Move version() functionality here.
-        (functionRun): Move run() functionality here.
-        (functionLoad): Move load() functionality here.
-        (functionQuit): Move quit() functionality here.
-        (prettyPrintScript): Fix indentation.
-        (runWithScripts): Since all the functionality of createGlobalObject is
-        now in the GlobalObject constructor, just call new here.
-        (parseArguments): Fix indentation.
-        (kjsmain): Ditto
-        (fillBufferWithContentsOfFile): Ditto.
-
-2008-02-24  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt and Mark Rowe.
-
-        http://bugs.webkit.org/show_bug.cgi?id=17505
-        Add support for getting command line arguments in testkjs
-
-        - This slightly changes the behavior of parsing arguments by requiring
-          a '-f' before all files. 
-
-        * kjs/testkjs.cpp:
-        (createGlobalObject): Add a global property called 'arguments' which
-        contains an array with the parsed arguments as strings.
-        (runWithScripts): Pass in the arguments vector so that it can be passed
-        to the global object.
-        (parseArguments): Change parsing rules to require a '-f' before any script
-        file. After all '-f' and '-p' arguments have been parsed, the remaining
-        are added to the arguments vector and exposed to the script. If there is a
-        chance of ambiguity (the user wants to pass the string '-f' to the script),
-        the string '--' can be used separate the options from the pass through 
-        arguments.
-        (kjsmain):
-
-2008-02-24  Dan Bernstein  <mitz@apple.com>
-
-        Reviewed by Darin Adler.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=17511
-          REGRESSION: Reproducible crash in SegmentedSubstring::SegmentedSubstring(SegmentedSubstring const&)
-
-        * wtf/Deque.h:
-        (WTF::::expandCapacityIfNeeded): Fixed the case where m_start and m_end
-        are both zero but the buffer capacity is non-zero.
-        (WTF::::prepend): Added validity checks.
-
-2008-02-23  Jan Michael Alonzo  <jmalonzo@unpluggable.com>
-
-        Rubber stamped by Darin.
-
-        Add separator '\' after libJavaScriptCore_la_LIBADD and cleanup
-        whitespaces introduced in the previous commit.
-
-        * GNUmakefile.am: 
-
-2008-02-23  Jan Michael Alonzo  <jmalonzo@unpluggable.com>
-
-        * GNUmakefile.am: Add GLOBALDEPS for testkjs and minidom.
-
-2008-02-23  Darin Adler  <darin@apple.com>
-
-        Reviewed by Anders.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=17496
-          make Deque use a circular array; add iterators
-
-        * wtf/Deque.h: Wrote an all-new version of this class that uses a circular
-        buffer. Growth policy is identical to vector. Added iterators.
-
-        * wtf/Vector.h: Made two small refinements while using this to implement
-        Deque: Made VectorBufferBase derive from Noncopyable, which would have
-        saved me some debugging time if it had been there. Renamed Impl and
-        m_impl to Buffer and m_buffer.
-
-2008-02-23  Darin Adler  <darin@apple.com>
-
-        Reviewed by Anders.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=17067
-          eliminate attributes parameter from JSObject::put for speed/clarity
-
-        * API/JSCallbackObject.h: Removed attribute arguments.
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::JSCallbackObject<Base>::put): Ditto.
-        * API/JSObjectRef.cpp:
-        (JSObjectSetProperty): Use initializeVariable or putDirect when necessary
-        to set attribute values.
-        * JavaScriptCore.exp: Updated.
-        * bindings/objc/objc_runtime.h: Removed attribute arguments.
-        * bindings/objc/objc_runtime.mm:
-        (ObjcFallbackObjectImp::put): Ditto.
-        * bindings/runtime_array.cpp:
-        (RuntimeArray::put): Ditto.
-        * bindings/runtime_array.h: Ditto.
-        * bindings/runtime_object.cpp:
-        (RuntimeObjectImp::put): Ditto.
-        * bindings/runtime_object.h: Ditto. Also removed canPut which was only
-        called from one place in WebCore that can use hasProperty instead.
-
-        * kjs/Activation.h: Removed attribute argument from put and added the new
-        initializeVariable function that's used to put variables in variable objects.
-        Also made isActivationObject a const member.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::put): Removed attribute argument.
-        (KJS::JSGlobalObject::initializeVariable): Added. Used to give variables
-        their initial values, which can include the read-only property.
-        (KJS::JSGlobalObject::reset): Removed obsolete comments about flags.
-        Removed Internal flag, which is no longer needed.
-        * kjs/JSGlobalObject.h: More of the same.
-
-        * kjs/JSVariableObject.h: Added pure virtual initializeVariable function.
-        (KJS::JSVariableObject::symbolTablePut): Removed checkReadOnly flag; we always
-        check read-only.
-        (KJS::JSVariableObject::symbolTableInitializeVariable): Added.
-
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::put): Removed attribute argument.
-        * kjs/array_instance.h: Ditto.
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::put): Ditto.
-        (KJS::Arguments::put): Ditto.
-        (KJS::ActivationImp::put): Ditto.
-        (KJS::ActivationImp::initializeVariable): Added.
-        * kjs/function.h: Removed attribute arguments.
-
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct): Removed Internal flag.
-
-        * kjs/lookup.h:
-        (KJS::lookupPut): Removed attributes argument. Also changed to use putDirect
-        instead of calling JSObject::put.
-        (KJS::cacheGlobalObject): Ditto.
-
-        * kjs/nodes.cpp:
-        (KJS::ConstDeclNode::handleSlowCase): Call initializeVariable to initialize
-        the constant.
-        (KJS::ConstDeclNode::evaluateSingle): Ditto.
-        (KJS::TryNode::execute): Use putDirect to set up the new object.
-        (KJS::FunctionBodyNode::processDeclarations): Removed Internal.
-        (KJS::ProgramNode::processDeclarations): Ditto.
-        (KJS::EvalNode::processDeclarations): Call initializeVariable to initialize
-        the variables and functions.
-        (KJS::FuncDeclNode::makeFunction): Removed Internal.
-        (KJS::FuncExprNode::evaluate): Ditto.
-
-        * kjs/object.cpp: Removed canPut, which was only being used in one code path,
-        not the normal high speed one.
-        (KJS::JSObject::put): Removed attribute argument. Moved the logic from
-        canPut here, in the one code ath that was still using it.
-        * kjs/object.h: Removed Internal attribute, ad canPut function. Removed the
-        attributes argument to the put function. Made isActivationObject const.
-
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpImp::put): Removed attributes argument.
-        (KJS::RegExpImp::putValueProperty): Ditto.
-        (KJS::RegExpObjectImp::put): Ditto.
-        (KJS::RegExpObjectImp::putValueProperty): Ditto.
-        * kjs/regexp_object.h: Ditto.
-
-        * kjs/string_object.cpp:
-        (KJS::StringInstance::put): Removed attributes argument.
-        * kjs/string_object.h: Ditto.
-
-2008-02-23  Jan Michael Alonzo  <jmalonzo@unpluggable.com>
-
-        Not reviewed, Gtk build fix.
-
-        * kjs/testkjs.pro:
-
-2008-02-23  Alexey Proskuryakov  <ap@webkit.org>
-
-        Windows build fix - move ThreadCondition implementation from WebCore to WTF.
-
-        * wtf/ThreadingWin.cpp:
-        (WTF::ThreadCondition::ThreadCondition):
-        (WTF::ThreadCondition::~ThreadCondition):
-        (WTF::ThreadCondition::wait):
-        (WTF::ThreadCondition::signal):
-        (WTF::ThreadCondition::broadcast):
-
-2008-02-23  Alexey Proskuryakov  <ap@webkit.org>
-
-        Touch some files, hoping that Windows build bot will create JSC headers.
-
-        * kjs/AllInOneFile.cpp:
-        * kjs/array_instance.cpp:
-        * wtf/HashTable.cpp:
-
-2008-02-23  Alexey Proskuryakov  <ap@webkit.org>
-
-        Qt/Wx build fix - this file was still in a wrong namespace, too.
-
-        * wtf/ThreadingNone.cpp:
-
-2008-02-23  Alexey Proskuryakov  <ap@webkit.org>
-
-        More build fixing - fix mismatched braces.
-
-        * JavaScriptCore.pri:
-
-2008-02-23  Alexey Proskuryakov  <ap@webkit.org>
-
-        Wx and Gtk build fixes.
-
-        * JavaScriptCore.pri: Don't try to compile ThreadingPthreads.
-        * wtf/ThreadingGtk.cpp: Use a correct namespace.
-
-2008-02-23  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        Move basic threading support from WebCore to WTF.
-
-        Added mutex protection to MessageQueue::killed() for paranoia sake.
-
-        * GNUmakefile.am:
-        * JavaScriptCore.exp:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * wtf/Locker.h: Copied from WebCore/platform/Locker.h.
-        * wtf/MessageQueue.h: Copied from WebCore/platform/MessageQueue.h.
-        (WTF::::killed):
-        * wtf/Threading.h: Copied from WebCore/platform/Threading.h.
-        * wtf/ThreadingGtk.cpp: Copied from WebCore/platform/gtk/ThreadingGtk.cpp.
-        (WebCore::createThread):
-        * wtf/ThreadingNone.cpp: Copied from WebCore/platform/ThreadingNone.cpp.
-        * wtf/ThreadingPthreads.cpp: Copied from WebCore/platform/pthreads/ThreadingPthreads.cpp.
-        (WTF::createThread):
-        * wtf/ThreadingWin.cpp: Copied from WebCore/platform/win/ThreadingWin.cpp.
-        (WTF::createThread):
-        (WTF::Mutex::Mutex):
-        (WTF::Mutex::~Mutex):
-        (WTF::Mutex::lock):
-        (WTF::Mutex::tryLock):
-        (WTF::Mutex::unlock):
-
-2008-02-22  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Partial fix for <rdar://problem/5744037> Gmail out of memory (17455)
-        
-        I'm removing KJS_MEM_LIMIT for the following reasons:
-        
-        - We have a few reports of KJS_MEM_LIMIT breaking important web
-        applications, like GMail and Google Reader. (For example, if you
-        simply open 12 GMail tabs, tab #12 will hit the limit.)
-
-        - Firefox has no discernable JS object count limit, so any limit, even
-        a large one, is a potential compatibility problem.
-        
-        - KJS_MEM_LIMIT does not protect against malicious memory allocation,
-        since there are many ways to maliciously allocate memory without
-        increasing the JS object count.
-        
-        - KJS_MEM_LIMIT is already mostly broken, since it only aborts the
-        script that breaches the limit, not any subsequent scripts.
-        
-        - We've never gotten bug reports about websites that would have
-        benefited from an unbroken KJS_MEM_LIMIT. The initial check-in of
-        KJS_MEM_LIMIT (KJS revision 80061) doesn't mention a website that
-        needed it.
-        
-        - Any website that brings you anywhere close to crashing due to the
-        number of live JS objects will almost certainly put up the "slow
-        script" dialog at least 20 times beforehand.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::collect):
-        * kjs/collector.h:
-        * kjs/nodes.cpp:
-        (KJS::TryNode::execute):
-
-2008-02-22  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Alexey P.
-
-        <rdar://problem/5759327> REGRESSION: while(NaN) acts like while(true)
-
-        Fix yet another case where we incorrectly relied on implicit double
-        to bool coercion.
-
-        * kjs/nodes.cpp:
-        (KJS::PostDecLocalVarNode::evaluateToBoolean):
-
-2008-02-20  Michael Knaup  <michael.knaup@mac.com>
-
-        Reviewed by Darin.
-
-        Fix for Bug 16753: date set methods with no args should result in NaN (Acid3 bug)
-        The set values result in NaN now when called with no args, NaN or +/- inf values.
-        The setYear, setFullYear and setUTCFullYear methods used on NaN dates work as 
-        descripted in the standard.
-
-        * kjs/date_object.cpp:
-        (KJS::fillStructuresUsingTimeArgs):
-        (KJS::fillStructuresUsingDateArgs):
-        (KJS::setNewValueFromTimeArgs):
-        (KJS::setNewValueFromDateArgs):
-        (KJS::dateProtoFuncSetYear):
-
-2008-02-19  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Darin.
-
-        Change OpaqueJSClass and RootObject to start with a ref count of 1.
-        
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::OpaqueJSClass):
-        (OpaqueJSClass::createNoAutomaticPrototype):
-        (OpaqueJSClass::create):
-        * API/JSClassRef.h:
-        * API/JSObjectRef.cpp:
-        (JSClassCreate):
-        * bindings/runtime_root.cpp:
-        (KJS::Bindings::RootObject::create):
-        (KJS::Bindings::RootObject::RootObject):
-
-2008-02-19  Darin Adler  <darin@apple.com>
-
-        Rubber stamped by Anders.
-
-        - removed explicit initialization to 1 for RefCounted; that's now the default
-
-        * kjs/regexp.cpp:
-        (KJS::RegExp::RegExp): Removed RefCounted initializer.
-
-2008-02-19  Darin Adler  <darin@apple.com>
-
-        Reviewed by Anders.
-
-        - next step for http://bugs.webkit.org/show_bug.cgi?id=17257
-          start ref counts at 1 instead of 0 for speed
-
-        * wtf/RefCounted.h:
-        (WTF::RefCounted::RefCounted): Have refcounts default to 1. This allows us to start
-        removing the explicit initialization of RefCounted from classes and eventually we
-        can remove the ability to have the initial count of 0 entirely.
-
-2008-02-18  Samuel Weinig  <sam@webkit.org>
-
-        Reviewed by Geoff Garen.
-
-        Fix for http://bugs.webkit.org/show_bug.cgi?id=17419
-        Remove CompatMode from JavaScriptCore as it is never set to anything other than NativeMode
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::init):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::setDebugger):
-        * kjs/date_object.cpp:
-        (KJS::dateProtoFuncGetYear):
-
-2008-02-18  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        * wtf/ASCIICType.h:
-        (WTF::toASCIIHexValue): Added.
-
-2008-02-17  Darin Adler  <darin@apple.com>
-
-        * wtf/ListHashSet.h: (WTF::swap): Removed stray return statement.
-
-2008-02-15  Adam Roben  <aroben@apple.com>
-
-        Make JavaScriptCore's FEATURE_DEFINES match WebCore's
-
-        Reviewed by Mark.
-
-        * Configurations/JavaScriptCore.xcconfig:
-
-2008-02-14  Stephanie Lewis <slewis@apple.com>
-
-        Reviewed by Geoff.
-
-        Update order files.
-
-        * JavaScriptCore.order:
-
-2008-02-14  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Fixed <rdar://problem/5737835> nee http://bugs.webkit.org/show_bug.cgi?id=17329
-        Crash in JSGlobalObject::popActivation when inserting hyperlink in Wordpress (17329)
-        
-        Don't reset the "activations" stack in JSGlobalObject::reset, since we
-        might be executing a script during the call to reset, and the script
-        needs to safely run to completion.
-        
-        Instead, initialize the "activations" stack when the global object is
-        created, and subsequently rely on pushing and popping during normal
-        execution to maintain the stack's state.
-        
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::init):
-        (KJS::JSGlobalObject::reset):
-
-2008-02-13  Bernhard Rosenkraenzer  <bero@arklinux.org>
-
-        Reviewed by Darin.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=17339
-          JavaScriptCore does not build with gcc 4.3
-
-        * kjs/interpreter.cpp: Add include of <unistd.h>, since that's where
-        getpid() comes from.
-
-2008-02-13  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Alexey P.
-
-        <rdar://problem/5737003> REGRESSION (r27747): can't browse pictures on fastcupid.com
-
-        When converting numeric values to booleans we need to account for NaN
-
-        * kjs/nodes.cpp:
-        (KJS::MultNode::evaluateToBoolean):
-        (KJS::ModNode::evaluateToBoolean):
-
-2008-02-08  Samuel Weinig  <sam@webkit.org>
-
-        Reviewed by Brady Eidson.
-
-        <rdar://problem/5659216> REGRESSION: PLT 0.3% slower due to r28868 (caching ClassNodeList and NamedNodeList)
-
-        - Tweak the statements in isASCIISpace to account for the statistical distribution of
-          usage in the PLT.
-
-        .4% speedup on my machine.  Stephanie's machine shows this as .3% speedup.
-
-        * wtf/ASCIICType.h:
-        (WTF::isASCIISpace): 
-
-2008-02-11  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Anders Carlsson.
-
-        Fixes for:
-        <rdar://problem/5735497> Match Firefox's cross-domain model more accurately by return the built-in version of functions even if they have been overridden
-        <rdar://problem/5735443> Crash when setting the Window objects prototype to a custom Object and then calling a method on it
-
-        - Expose the native Object.prototype.toString implementation so that it can be used for cross-domain
-          toString calling.
-
-        * JavaScriptCore.exp:
-        * kjs/object_object.cpp:
-        * kjs/object_object.h:
-
-2008-02-10  Darin Adler  <darin@apple.com>
-
-        Rubber stamped by Eric.
-
-        * kjs/ExecState.h:
-        (KJS::ExecState::takeException): Added.
-
-2008-02-10  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=17256
-          eliminate default ref. count of 0 in RefCounted class
-
-        * wtf/RefCounted.h:
-        (WTF::RefCounted::RefCounted): Remove default of 0.
-
-2008-02-10  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=17256
-          Make clients of RefCounted explicitly set the count to 0.
-
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::OpaqueJSClass):
-        * bindings/runtime_root.cpp:
-        (KJS::Bindings::RootObject::RootObject):
-
-2008-02-09  Darin Adler  <darin@apple.com>
-
-        Reviewed by Mitz.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=17256
-          Change RegExp to start its ref count at 1, not 0
-
-        We'll want to do this to every RefCounted class, one at a time.
-
-        * kjs/nodes.h:
-        (KJS::RegExpNode::RegExpNode): Use RegExp::create instead of new RegExp.
-        * kjs/regexp.cpp:
-        (KJS::RegExp::RegExp): Marked inline, set initial ref count to 1.
-        (KJS::RegExp::create): Added. Calls new RegExp then adopts the initial ref.
-        * kjs/regexp.h: Reformatted. Made the constructors private. Added static
-        create functions that return objects already wrapped in PassRefPtr.
-        * kjs/regexp_object.cpp:
-        (KJS::regExpProtoFuncCompile): Use RegExp::create instead of new RegExp.
-        (KJS::RegExpObjectImp::construct): Ditto.
-        * kjs/string_object.cpp:
-        (KJS::stringProtoFuncMatch): Ditto.
-        (KJS::stringProtoFuncSearch): Ditto.
-
-2008-02-08  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        <rdar://problem/5731773> REGRESSION (r28973): Extraneous parentheses in function.toString()
-        https://bugs.webkit.org/show_bug.cgi?id=17214
-
-        Make a subclass of CommaNode to provide the correct precedence for each expression in
-        a variable declaration list.
-
-        * kjs/grammar.y:
-        * kjs/nodes.h:
-        (KJS::VarDeclCommaNode::):
-
-2008-02-08  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=17247
-          Labelled continue/break can fail in some cases
-
-        Test: fast/js/continue-break-multiple-labels.html
-
-        * kjs/nodes.h:
-        (KJS::StatementNode::pushLabel): Made this virtual.
-        (KJS::LabelNode::pushLabel): Forward pushLabel calls to the statement inside.
-
-2008-02-08  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15003
-          Function.prototype.constructor should not be DontDelete/ReadOnly (Acid3 bug)
-
-        Test: fast/js/constructor-attributes.html
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset): Remove unwanted attributes from "constructor".
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct): Ditto.
-        * kjs/nodes.cpp:
-        (KJS::FuncDeclNode::makeFunction): Ditto.
-        (KJS::FuncExprNode::evaluate): Ditto.
-
-2008-02-06  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Added an ASSERT to catch refCount underflow, since it caused a leak in
-        my last check-in.
-
-        * wtf/RefCounted.h:
-        (WTF::RefCounted::deref):
-
-2008-02-06  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-
-        PLT speedup related to <rdar://problem/5659272> REGRESSION: PLT .4%
-        slower due to r28884 (global variable symbol table optimization)
-        
-        Tweaked RefCounted::deref() to be a little more efficient.
-
-        1% - 1.5% speedup on my machine. .7% speedup on Stephanie's machine.
-        
-        * wtf/RefCounted.h:
-        (WTF::RefCounted::deref): Don't modify m_refCount if we're just going
-        to delete the object anyway. Also, use a simple == test, which might be
-        faster than <= on some hardware.
-
-2008-02-06  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=17094
-          Array.prototype functions create length properties with DontEnum/DontDelete
-
-        Test results match Gecko with very few obscure exceptions that seem to be
-        bugs in Gecko.
-
-        Test: fast/js/array-functions-non-arrays.html
-
-        * kjs/array_object.cpp:
-        (KJS::arrayProtoFuncConcat):  Removed DontEnum and DontDelete from the call
-        to set length.
-        (KJS::arrayProtoFuncPop): Ditto. Also added missing call to deleteProperty,
-        which is not needed for real arrays, but is needed for non-arrays.
-        (KJS::arrayProtoFuncPush): Ditto.
-        (KJS::arrayProtoFuncShift): Ditto.
-        (KJS::arrayProtoFuncSlice): Ditto.
-        (KJS::arrayProtoFuncSort): Removed incorrect call to set length when
-        the array has no elements.
-        (KJS::arrayProtoFuncSplice): Removed DontEnum and DontDelete from the call
-        to set length.
-        (KJS::arrayProtoFuncUnShift): Ditto. Also added a check for 0 arguments to
-        make behavior match the specification in that case.
-        * kjs/nodes.cpp:
-        (KJS::ArrayNode::evaluate): Removed DontEnum and DontDelete from the call
-        to set length.
-
-2008-02-06  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        - replace calls to put to set up properties with calls to putDirect, to
-          prepare for a future change where put won't take attributes any more,
-          and for a slight performance boost
-
-        * API/JSObjectRef.cpp:
-        (JSObjectMakeConstructor): Use putDirect instead of put.
-        * kjs/CommonIdentifiers.h: Removed lastIndex.
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset): Use putDirect instead of put.
-        * kjs/array_object.cpp:
-        (KJS::arrayProtoFuncConcat): Took out extra call to get length (unused).
-        (KJS::ArrayObjectImp::ArrayObjectImp): Use putDirect instead of put.
-        * kjs/error_object.cpp:
-        (KJS::ErrorPrototype::ErrorPrototype): Use putDirect instead of put.
-        * kjs/function.cpp:
-        (KJS::Arguments::Arguments): Use putDirect instead of put.
-        (KJS::PrototypeFunction::PrototypeFunction): Use putDirect instead of put.
-        * kjs/function_object.cpp:
-        (KJS::FunctionObjectImp::construct): Use putDirect instead of put.
-        * kjs/nodes.cpp:
-        (KJS::FuncDeclNode::makeFunction): Use putDirect instead of put.
-        (KJS::FuncExprNode::evaluate): Use putDirect instead of put.
-        * kjs/regexp_object.cpp:
-        (KJS::regExpProtoFuncCompile): Use setLastIndex instead of put(lastIndex).
-        (KJS::RegExpImp::match): Get and set lastIndex by using m_lastIndex instead of
-        calling get and put.
-        * kjs/regexp_object.h:
-        (KJS::RegExpImp::setLastIndex): Added.
-        * kjs/string_object.cpp:
-        (KJS::stringProtoFuncMatch): Use setLastIndex instead of put(lastIndex).
-
-2008-02-05  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Anders Carlsson.
-
-        Fix for http://bugs.webkit.org/show_bug.cgi?id=8080
-        NodeList (and other DOM lists) items are not enumeratable using for..in
-
-        * JavaScriptCore.exp:
-
-2008-02-05  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Update versioning to support the mysterious future.
-
-        * Configurations/Version.xcconfig: Add SYSTEM_VERSION_PREFIX_1060.
-
-2008-02-04  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Oliver Hunt.
-
-        Fixes Bug 16889: REGRESSION (r29425): Canvas-based graphing calculator fails to run
-              Bug 17015: REGRESSION (r29414-29428): www.fox.com "shows" menu fails to render
-              Bug 17164: REGRESSION: JavaScript pop-up menu appears at wrong location when hovering image at http://news.chinatimes.com/
-
-        <http://bugs.webkit.org/show_bug.cgi?id=16889>
-        <rdar://problem/5696255>
-
-        <http://bugs.webkit.org/show_bug.cgi?id=17015>
-
-        <http://bugs.webkit.org/show_bug.cgi?id=17164>
-        <rdar://problem/5720947>
-
-        The ActivationImp tear-off (r29425) introduced a problem with ReadModify
-        nodes that first resolve a slot, call valueForReadModifyNode(), and then
-        store a value in the previously resolved slot. Since valueForReadModifyNode()
-        may cause a tear-off, the slot needs to be resolved again, but this was
-        not happening with the existing code.
-
-        * kjs/nodes.cpp:
-        (KJS::ReadModifyLocalVarNode::evaluate):
-        (KJS::ReadModifyResolveNode::evaluate):
-
-2008-02-04  Cameron McCormack <cam@mcc.id.au>
-
-        Reviewed by Geoff Garen.
-
-        Remove some unneccesary UNUSED_PARAMs.  Clarify ownership rule of return value of JSObjectCopyPropertyNames.
-
-        * API/JSNode.c:
-        (JSNode_appendChild):
-        (JSNode_removeChild):
-        (JSNode_replaceChild):
-        (JSNode_getNodeType):
-        (JSNode_getFirstChild):
-        * API/JSNodeList.c:
-        (JSNodeList_length):
-        * API/JSObjectRef.h:
-
-2008-02-04  Rodney Dawes  <dobey@wayofthemonkey.com>
-
-        Reviewed by Alp Toker and Mark Rowe.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=17175.
-        Bug 17175: Use of C++ compiler flags in CFLAGS
-
-        * GNUmakefile.am: Use global_cxxflags as well as global_cflags in CXXFLAGS.
-
-2008-02-04  Alp Toker  <alp@atoker.com>
-
-        Rubber-stamped by Mark Rowe.
-
-        Remove all trailing whitespace in the GTK+ port and related
-        components.
-
-        * GNUmakefile.am:
-
-2008-02-02  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff Garen.
-
-        PLT speedup related to <rdar://problem/5659272> REGRESSION: PLT .4%
-        slower due to r28884 (global variable symbol table optimization)
-
-        Geoff's theory is that the slowdown was due to copying hash tables when
-        putting things into the back/forward cache. If that's true, then this
-        should fix the problem.
-
-        (According to Geoff's measurements, in a PLT that exaggerates the
-        importance of symbol table saving during cached page creation, this
-        patch is a ~3X speedup in cached page creation, and a 9% speedup overall.)
-
-        * JavaScriptCore.exp: Updated.
-
-        * kjs/JSVariableObject.cpp:
-        (KJS::JSVariableObject::saveLocalStorage): Updated for changes to SavedProperty,
-        which has been revised to avoid initializing each SavedProperty twice when building
-        the array. Store the property names too, so we don't have to store the symbol table
-        separately. Do this by iterating the symbol table instead of the local storage vector.
-        (KJS::JSVariableObject::restoreLocalStorage): Ditto. Restore the symbol table as
-        well as the local storage vector.
-
-        * kjs/JSVariableObject.h: Removed save/restoreSymbolTable and do that work inside
-        save/restoreLocalStorage instead. Made restoreLocalStorage a non-const member function
-        that takes a const reference to a SavedProperties object.
-
-        * kjs/LocalStorage.h: Changed attributes to be unsigned instead of int to match
-        other declarations of attributes elsewhere.
-
-        * kjs/property_map.cpp:
-        (KJS::SavedProperties::SavedProperties): Updated for data member name change.
-        (KJS::PropertyMap::save): Updated for data member name change and to use the new
-        inline init function instead of setting the fields directly. This allows us to
-        skip initializing the SavedProperty objects when first allocating the array, and
-        just do it when we're actually setting up the individual elements.
-        (KJS::PropertyMap::restore): Updated for SavedProperty changes.
-
-        * kjs/property_map.h: Changed SavedProperty from a struct to a class. Set it up so
-        it does not get initialized at construction time to avoid initializing twice when
-        creating an array of SavedProperty. Removed the m_ prefixes from the members of
-        the SavedProperties struct. Generally we use m_ for class members and not struct.
-
-2008-02-02  Tony Chang  <idealisms@gmail.com>
-
-        Reviewed by darin.  Landed by eseidel.
-
-        Add #define guards for WIN32_LEAN_AND_MEAN and _CRT_RAND_S.
-
-        * kjs/config.h:
-        * wtf/FastMalloc.cpp:
-        * wtf/TCSpinLock.h:
-
-2008-01-28  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Darin Adler.
-
-        - Fix whitespace in nodes.h/cpp and nodes2string.cpp.
-
-        (NOTE: Specific changed functions elided for space and clarity)
-        * kjs/nodes.cpp:
-        * kjs/nodes.h:
-        * kjs/nodes2string.cpp:
-
-2008-01-27  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver Hunt.
-
-        Patch for http://bugs.webkit.org/show_bug.cgi?id=17025
-        nodes.h/cpp has been rolling around in the mud - lets hose it down
-
-        - Rename member variables to use the m_ prefix.
-
-        (NOTE: Specific changed functions elided for space and clarity)
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        * kjs/nodes.h:
-        * kjs/nodes2string.cpp:
-
-2008-01-27  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - fix <rdar://problem/5657450> REGRESSION: const is broken
-
-        Test: fast/js/const.html
-
-        SunSpider said this was 0.3% slower. And I saw some Shark samples in
-        JSGlobalObject::put -- not a lot but a few. We may be able to regain the
-        speed, but for now we will take that small hit for correctness sake.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::put): Pass the checkReadOnly flag in to symbolTablePut
-        instead of passing attributes.
-
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTablePut): Removed the code to set attributes
-        here, since we only set attributes when creating a property. Added the code
-        to check read-only here, since we need that to implement const!
-
-        * kjs/function.cpp:
-        (KJS::ActivationImp::put): Pass the checkReadOnly flag in to symbolTablePut
-        instead of passing attributes.
-
-        * kjs/nodes.cpp:
-        (KJS::isConstant): Added.
-        (KJS::PostIncResolveNode::optimizeVariableAccess): Create a PostIncConstNode
-        if optimizing for a local variable and the variable is constant.
-        (KJS::PostDecResolveNode::optimizeVariableAccess): Ditto. But PostDecConstNode.
-        (KJS::PreIncResolveNode::optimizeVariableAccess): Ditto. But PreIncConstNode.
-        (KJS::PreDecResolveNode::optimizeVariableAccess): Ditto. But PreDecConstNode.
-        (KJS::PreIncConstNode::evaluate): Return the value + 1.
-        (KJS::PreDecConstNode::evaluate): Return the value - 1.
-        (KJS::PostIncConstNode::evaluate): Return the value converted to a number.
-        (KJS::PostDecConstNode::evaluate): Ditto.
-        (KJS::ReadModifyResolveNode::optimizeVariableAccess): Create a ReadModifyConstNode
-        if optimizing for a local variable and the variable is constant.
-        (KJS::AssignResolveNode::optimizeVariableAccess): Ditto. But AssignConstNode.
-        (KJS::ScopeNode::optimizeVariableAccess): Pass the local storage to the
-        node optimizeVariableAccess functions, since that's where we need to look to
-        figure out if a variable is constant.
-        (KJS::FunctionBodyNode::processDeclarations): Moved the call to
-        optimizeVariableAccess until after localStorage is set up.
-        (KJS::ProgramNode::processDeclarations): Ditto.
-
-        * kjs/nodes.h: Fixed the IsConstant and HasInitializer values. They are used
-        as flag masks, so a value of 0 will not work for IsConstant. Changed the
-        first parameter to optimizeVariableAccess to be a const reference to a symbol
-        table and added a const reference to local storage. Added classes for const
-        versions of local variable access: PostIncConstNode, PostDecConstNode,
-        PreIncConstNode, PreDecConstNode, ReadModifyConstNode, and AssignConstNode.
-
-        * kjs/object.cpp:
-        (KJS::JSObject::put): Tweaked comments a bit, and changed the checkReadOnly
-        expression to match the form used at the two other call sites.
-
-2008-01-27  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16498
-          ''.constructor.toString() gives [function]
-
-        Test: fast/js/function-names.html
-
-        * kjs/array_object.cpp:
-        (KJS::ArrayObjectImp::ArrayObjectImp): Use the class name as the constructor's function name.
-        * kjs/bool_object.cpp:
-        (KJS::BooleanObjectImp::BooleanObjectImp): Ditto.
-        * kjs/date_object.cpp:
-        (KJS::DateObjectImp::DateObjectImp): Ditto.
-        * kjs/error_object.cpp:
-        (KJS::ErrorPrototype::ErrorPrototype): Make the error object be an Error.
-        (KJS::ErrorObjectImp::ErrorObjectImp): Use the class name as the constructor's function name.
-        (KJS::NativeErrorPrototype::NativeErrorPrototype): Take const UString&.
-        (KJS::NativeErrorImp::NativeErrorImp): Use the prototype's name as the constructor's function
-        name.
-        * kjs/error_object.h: Change ErrorPrototype to inherit from ErrorInstance. Change the
-        NativeErrorImp constructor to take a NativeErrorPrototype pointer for its prototype.
-        * kjs/function.h: Removed unneeded constructor for internal functions without names.
-        We want to avoid those!
-        * kjs/function_object.cpp:
-        (KJS::functionProtoFuncToString): Removed code that writes out just [function] for functions
-        that have no names. There's no reason to do that.
-        (KJS::FunctionObjectImp::FunctionObjectImp): Use the class name as the constructor's
-        function name.
-        * kjs/internal.cpp: Removed the unused constructor.
-        * kjs/number_object.cpp:
-        (KJS::fractionalPartToString): Marked static for internal linkage.
-        (KJS::exponentialPartToString): Ditto.
-        (KJS::numberProtoFuncToPrecision): Removed an unneeded else.
-        (KJS::NumberObjectImp::NumberObjectImp): Use the class name as the constructor's
-        function name.
-        (KJS::NumberObjectImp::getValueProperty): Tweaked formatting.
-        * kjs/object_object.cpp:
-        (KJS::ObjectObjectImp::ObjectObjectImp): Use "Object" for the function name.
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpObjectImp::RegExpObjectImp): Use "RegExp" for the function name.
-        * kjs/string_object.cpp:
-        (KJS::StringObjectImp::StringObjectImp): Use the class name as the constructor's
-        function name.
-
-2008-01-26  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=17027
-          Incorrect Function.toString behaviour with read/modify/write operators performed on negative numbers
-
-        Test: fast/js/function-toString-parentheses.html
-
-        The problem here was that a NumberNode with a negative number in it had the wrong
-        precedence. It's not a primary expression, it's a unary operator with a primary
-        expression after it.
-
-        Once the precedence of NumberNode was fixed, the cases from bug 17020 were also
-        fixed without trying to treat bracket nodes like dot nodes. That wasn't needed.
-        The reason we handle numbers before dot nodes specially is that the dot is a
-        legal character in a number. The same is not true of a bracket. Eventually we
-        could get smarter, and only add the parentheses when there is actual ambiguity.
-        There is none if the string form of the number already has a dot in it, or if
-        it's a number with a alphabetic name like infinity or NAN.
-
-        * kjs/nodes.h: Renamed back from ObjectAccess to DotExpr.
-        (KJS::NumberNode::precedence): Return PrecUnary for negative numbers, since
-        they serialize as a unary operator, not a primary expression.
-        * kjs/nodes2string.cpp:
-        (KJS::SourceStream::operator<<): Clear m_numberNeedsParens if this adds
-        parens; one set is enough.
-        (KJS::bracketNodeStreamTo): Remove unneeded special flag here. Normal
-        operator precedence suffices.
-        (KJS::NewExprNode::streamTo): Ditto.
-
-2008-01-26  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej and Darin.
-
-        Fix for http://bugs.webkit.org/show_bug.cgi?id=17020
-        Function.toString does not parenthesise numbers for the bracket accessor
-
-        It turns out that logic was there for all of the dot accessor nodes to make numbers be
-        parenthesised properly, so it was a trivial extension to extend that to the bracket nodes.
-        I renamed the enum type to reflect the fact that it is now used for both dot and bracket
-        accessors.
-
-        * kjs/nodes2string.cpp:
-        (KJS::bracketNodeStreamTo):
-        (KJS::BracketAccessorNode::streamTo):
-
-2008-01-26  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Darin.
-
-        Fix Bug 17018: Incorrect code generated from Function.toString for get/setters in object literals
-
-        Don't quote getter and setter names during output, as that is simply wrong.
-
-        * kjs/nodes2string.cpp:
-        (KJS::PropertyNode::streamTo):
-
-2008-01-26  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric Seidel.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=16860
-          a bit of cleanup after the Activation optimization
-
-        * JavaScriptCore.exp: Export the GlobalExecState constructor instead of
-        the global flavor of the ExecState constructor. It'd probably be cleaner
-        to not export either one, but JSGlobalObject inlines the code that
-        constructs the ExecState. If we changed that, we could remove this export.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Re-sorted a few things and
-        put the new source files into the kjs group rather than at the top level.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState): Marked inline and updated for data member
-        name changes. This is now only for use for the derived classes. Also removed
-        code that sets the unused m_savedExec data member for the global case. That
-        data member is only used for the other two types.
-        (KJS::ExecState::~ExecState): Marked inline and removed all the code.
-        The derived class destructors now inclde the appropriate code.
-        (KJS::ExecState::lexicalGlobalObject): Removed unneeded special case for
-        an empty scope chain. The bottom function already returns 0 for that case,
-        so the general case code handles it fine. Also changed to use data members
-        directly rather than calling functions.
-        (KJS::GlobalExecState::GlobalExecState): Added. Calls through to the base
-        class constructor.
-        (KJS::GlobalExecState::~GlobalExecState): Added.
-        (KJS::InterpreterExecState::InterpreterExecState): Added. Moved code to
-        manipulate activeExecStates here since we don't want to have to check for the
-        special case of globalExec.
-        (KJS::InterpreterExecState::~InterpreterExecState): Added.
-        (KJS::EvalExecState::EvalExecState): Added.
-        (KJS::EvalExecState::~EvalExecState): Added.
-        (KJS::FunctionExecState::FunctionExecState): Added.
-        (KJS::FunctionExecState::~FunctionExecState): Added.
-
-        * kjs/ExecState.h: Tweaked the header, includes, and declarations a bit.
-        Made ExecState inherit from Noncopyable. Reformatted some comments and
-        made them a bit more brief. Rearranged declarations a little bit and removed
-        unused savedExec function. Changed seenLabels function to return a reference
-        rather than a pointer. Made constructors and destructor protected, and also
-        did the same with all data members. Renamed m_thisVal to m_thisValue and
-        ls to m_labelStack. Added three new derived classes for each of the
-        types of ExecState. The primary goal here was to remove a branch from the
-        code in the destructor, but it's also clearer than overloading the arguments
-        to the ExecState constructor.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::getCurrentTime): Fixed formatting.
-        (KJS::JSGlobalObject::pushActivation): Removed parentheses that don't make
-        the expression clearer -- other similar sites didn't have these parentheses,
-        even the one a couple lines earlier that sets stackEntry.
-        (KJS::JSGlobalObject::tearOffActivation): Got rid of unneeded static_cast
-        (I think I mentioned this during patch review) and used an early exit so that
-        the entire contents of the function aren't nested inside an if statement.
-        Also removed the check of codeType, instead checking Activation for 0.
-        For now, I kept the codeType check, but inside an assertion.
-
-        * kjs/JSGlobalObject.h: Changed type of globalExec to GlobalExecState.
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction): Changed type to FunctionExecState.
-        (KJS::GlobalFuncImp::callAsFunction): Changed type to EvalExecState.
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate): Changed type to GlobalExecState.
-
-        * kjs/nodes.cpp:
-        (KJS::ContinueNode::execute): Changed code since seenLabels() returns a
-        reference now instead of a pointer.
-        (KJS::BreakNode::execute): Ditto.
-        (KJS::LabelNode::execute): Ditto.
-
-2008-01-26  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Mark Rowe.
-
-        Cleanup node2string a little.
-        - Remove some unnecessary branching.
-        - Factor out bracket and dot streaming into static inline functions.
-
-        * kjs/nodes.h:
-        * kjs/nodes2string.cpp:
-        (KJS::bracketNodeStreamTo):
-        (KJS::dotNodeStreamTo):
-        (KJS::FunctionCallBracketNode::streamTo):
-        (KJS::FunctionCallDotNode::streamTo):
-        (KJS::PostIncBracketNode::streamTo):
-        (KJS::PostDecBracketNode::streamTo):
-        (KJS::PostIncDotNode::streamTo):
-        (KJS::PostDecDotNode::streamTo):
-        (KJS::DeleteBracketNode::streamTo):
-        (KJS::DeleteDotNode::streamTo):
-        (KJS::PreIncBracketNode::streamTo):
-        (KJS::PreDecBracketNode::streamTo):
-        (KJS::PreIncDotNode::streamTo):
-        (KJS::PreDecDotNode::streamTo):
-        (KJS::ReadModifyBracketNode::streamTo):
-        (KJS::AssignBracketNode::streamTo):
-        (KJS::ReadModifyDotNode::streamTo):
-        (KJS::AssignDotNode::streamTo):
-        (KJS::WhileNode::streamTo):
-
-2008-01-26  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Darin Adler.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=17001
-        Bug 17001: Build error with Gtk port on Mac OS X
-
-        If both XP_MACOSX and XP_UNIX are defined then X11.h and Carbon.h will both be included.
-        These provide conflicting definitions for a type named 'Cursor'.  As XP_UNIX is set by
-        the build system when targeting X11, it doesn't make sense for XP_MACOSX to also be set
-        in this instance.
-
-        * bindings/npapi.h: Don't define XP_MACOSX if XP_UNIX is defined.
-
-2008-01-26  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=17013
-          JSC can't round trip certain for-loops
-
-        Test: fast/js/toString-for-var-decl.html
-
-        * kjs/nodes.h: Added PlaceholderTrueNode so we can put nodes into
-        for loops without injecting the word "true" into them (nice, but not
-        the bug fix). Fixed ForNode constructor so expr1WasVarDecl is set
-        only when there is an expression, since it's common for the actual
-        variable declaration to be moved by the parser.
-
-        * kjs/nodes2string.cpp:
-        (KJS::PlaceholderTrueNode::streamTo): Added. Empty.
-
-2008-01-25  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Fix for bug 17012: REGRESSION: JSC can't round trip an object literal
-
-        Add logic to ensure that object literals and function expressions get
-        parentheses when necessary.
-
-        * kjs/nodes.h:
-        * kjs/nodes2string.cpp:
-        (KJS::SourceStream::operator<<):
-
-2008-01-24  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-
-        * JavaScriptCore.vcproj/JavaScriptCore.sln:
-
-2008-01-24  Steve Falkenburg  <sfalken@apple.com>
-
-        Build fix.
-
-        * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln:
-
-2008-01-24  Michael Goddard  <michael.goddard@trolltech.com>
-
-        Reviewed by Simon.
-
-        Fix QDateTime to JS Date conversion.
-        Several conversion errors (some UTC related, some month
-        offset related) and the conversion distance for Date
-        to DateTime conversion weights were fixed (it should never
-        be better to convert a JS Number into a Date rather than
-        an int).
-        
-        * bindings/qt/qt_runtime.cpp:
-        (KJS::Bindings::convertValueToQVariant):
-        (KJS::Bindings::convertQVariantToValue):
-
-2008-01-24  Michael Goddard  <michael.goddard@trolltech.com>
-
-        Reviewed by Simon.
-
-        Add support for calling QObjects.
-        Add support for invokeDefaultMethod (via a call to
-        a specific slot), and also allow using it as a
-        constructor, like QtScript.
-        
-
-        * bindings/qt/qt_class.cpp:
-        (KJS::Bindings::QtClass::fallbackObject):
-        * bindings/qt/qt_instance.cpp:
-        (KJS::Bindings::QtRuntimeObjectImp::construct):
-        (KJS::Bindings::QtInstance::QtInstance):
-        (KJS::Bindings::QtInstance::~QtInstance):
-        (KJS::Bindings::QtInstance::implementsCall):
-        (KJS::Bindings::QtInstance::invokeDefaultMethod):
-        * bindings/qt/qt_instance.h:
-        * bindings/qt/qt_runtime.cpp:
-        (KJS::Bindings::findMethodIndex):
-        (KJS::Bindings::QtRuntimeMetaMethod::QtRuntimeMetaMethod):
-        (KJS::Bindings::QtRuntimeMetaMethod::callAsFunction):
-        * bindings/qt/qt_runtime.h:
-
-2008-01-24  Michael Goddard  <michael.goddard@trolltech.com>
-
-        Reviewed by Simon.
-
-        Code style cleanups.
-        Add spaces before/after braces in inline function.
-
-        * bindings/qt/qt_instance.h:
-
-2008-01-24  Michael Goddard  <michael.goddard@trolltech.com>
-
-        Reviewed by Simon.
-
-        Code style cleanups.
-        Remove spaces and unneeded declared parameter names.
-
-        * bindings/qt/qt_instance.cpp:
-        (KJS::Bindings::QtRuntimeObjectImp::removeFromCache):
-
-2008-01-24  Michael Goddard  <michael.goddard@trolltech.com>
-
-        Reviewed by Simon.
-
-        Clear stale RuntimeObjectImps.
-        Since other objects can have refs to the QtInstance,
-        we can't rely on the QtInstance being deleted when the
-        RuntimeObjectImp is invalidate or deleted.  This
-        could result in a stale JSObject being returned for
-        a valid Instance.
-
-        * bindings/qt/qt_instance.cpp:
-        (KJS::Bindings::QtRuntimeObjectImp::QtRuntimeObjectImp):
-        (KJS::Bindings::QtRuntimeObjectImp::~QtRuntimeObjectImp):
-        (KJS::Bindings::QtRuntimeObjectImp::invalidate):
-        (KJS::Bindings::QtRuntimeObjectImp::removeFromCache):
-        (KJS::Bindings::QtInstance::getRuntimeObject):
-        * bindings/runtime.cpp:
-        (KJS::Bindings::Instance::createRuntimeObject):
-        * bindings/runtime.h:
-
-2008-01-23  Alp Toker  <alp@atoker.com>
-
-        Rubber-stamped by Mark Rowe.
-
-        Remove whitespace after -I in automake include lists.
-
-        * GNUmakefile.am:
-
-2008-01-23  Michael Goddard <michael.goddard@trolltech.com>
-
-        Reviewed by Lars Knoll <lars@trolltech.com>.
-
-        Reworked the JavaScriptCore Qt bindings:
-        
-        * Add initial support for string and variant arrays, as well
-        as sub QObjects in the JS bindings.
-        
-        * Don't expose fields marked as not scriptable by moc.
-        
-        * Add support for dynamic properties and accessing named
-        QObject children of an object (like QtScript and older
-        IE DOM style JS).
-        * Add support for custom toString methods.
-        
-        * Fine tune some bindings to be closer to QtScript.
-        Make void functions return undefined, and empty/
-        null QStrings return a zero length string.
-        
-        * Create framework for allowing more direct method calls.
-        Since RuntimeMethod doesn't allow us to add additional
-        methods/properties to a function, add these classes.
-        Start prototyping object.signal.connect(...).
-        
-        * Add signal support to the Qt bindings.
-        Allow connecting to signals (object.signal.connect(slot)),
-        disconnecting, and emitting signals.  Currently chooses
-        the first signal that matches the name, so this will need
-        improvement.
-        
-        * Add property names, and resolve signals closer to use.
-        Enumerating properties now returns some of the Qt properties
-        and signals.  Slots and methods aren't quite present.  Also,
-        resolve signal connections etc. closer to the time of use, so
-        we can do more dynamic resolution based on argument type etc.
-        Still picks the first one with the same name, at the moment.
-        
-        * Make signature comparison code consistent.
-        Use the same code for checking meta signatures in
-        the method and fallback getters, and avoid a
-        QByteArray construction when we can.
-        
-        * Fix minor memory leak, and handle pointers better.
-        Delete the private object in the dtors, and use RefPtrs
-        for holding Instances etc.
-        
-        * Handle method lookup better.
-        Allow invocation time method lookup based on the arguments,
-        which is closer to QtScript behaviour.  Also, cache the
-        method lists and delete them in the QtClass dtor (stops
-        a memory leak).
-        
-        * Improve JS to Qt data type conversions.
-        Add some support for Date & RegExp JS objects,
-        and provide some metrics on the quality of the
-        conversion.
-        
-        * A couple of fixes for autotest failures.
-        Better support for converting lists, read/write only
-        QMetaProperty support, modified slot search order...)
-
-        * bindings/qt/qt_class.cpp:
-        (KJS::Bindings::QtClass::QtClass):
-        (KJS::Bindings::QtClass::~QtClass):
-        (KJS::Bindings::QtClass::name):
-        (KJS::Bindings::QtClass::fallbackObject):
-        (KJS::Bindings::QtClass::methodsNamed):
-        (KJS::Bindings::QtClass::fieldNamed):
-        * bindings/qt/qt_class.h:
-        * bindings/qt/qt_instance.cpp:
-        (KJS::Bindings::QtInstance::QtInstance):
-        (KJS::Bindings::QtInstance::~QtInstance):
-        (KJS::Bindings::QtInstance::getRuntimeObject):
-        (KJS::Bindings::QtInstance::getClass):
-        (KJS::Bindings::QtInstance::implementsCall):
-        (KJS::Bindings::QtInstance::getPropertyNames):
-        (KJS::Bindings::QtInstance::invokeMethod):
-        (KJS::Bindings::QtInstance::invokeDefaultMethod):
-        (KJS::Bindings::QtInstance::stringValue):
-        (KJS::Bindings::QtInstance::booleanValue):
-        (KJS::Bindings::QtInstance::valueOf):
-        (KJS::Bindings::QtField::name):
-        (KJS::Bindings::QtField::valueFromInstance):
-        (KJS::Bindings::QtField::setValueToInstance):
-        * bindings/qt/qt_instance.h:
-        (KJS::Bindings::QtInstance::getBindingLanguage):
-        (KJS::Bindings::QtInstance::getObject):
-        * bindings/qt/qt_runtime.cpp:
-        (KJS::Bindings::QWKNoDebug::QWKNoDebug):
-        (KJS::Bindings::QWKNoDebug::~QWKNoDebug):
-        (KJS::Bindings::QWKNoDebug::operator<<):
-        (KJS::Bindings::):
-        (KJS::Bindings::valueRealType):
-        (KJS::Bindings::convertValueToQVariant):
-        (KJS::Bindings::convertQVariantToValue):
-        (KJS::Bindings::QtRuntimeMethod::QtRuntimeMethod):
-        (KJS::Bindings::QtRuntimeMethod::~QtRuntimeMethod):
-        (KJS::Bindings::QtRuntimeMethod::codeType):
-        (KJS::Bindings::QtRuntimeMethod::execute):
-        (KJS::Bindings::QtRuntimeMethodData::~QtRuntimeMethodData):
-        (KJS::Bindings::QtRuntimeMetaMethodData::~QtRuntimeMetaMethodData):
-        (KJS::Bindings::QtRuntimeConnectionMethodData::~QtRuntimeConnectionMethodData):
-        (KJS::Bindings::QtMethodMatchType::):
-        (KJS::Bindings::QtMethodMatchType::QtMethodMatchType):
-        (KJS::Bindings::QtMethodMatchType::kind):
-        (KJS::Bindings::QtMethodMatchType::isValid):
-        (KJS::Bindings::QtMethodMatchType::isVariant):
-        (KJS::Bindings::QtMethodMatchType::isMetaType):
-        (KJS::Bindings::QtMethodMatchType::isUnresolved):
-        (KJS::Bindings::QtMethodMatchType::isMetaEnum):
-        (KJS::Bindings::QtMethodMatchType::enumeratorIndex):
-        (KJS::Bindings::QtMethodMatchType::variant):
-        (KJS::Bindings::QtMethodMatchType::metaType):
-        (KJS::Bindings::QtMethodMatchType::metaEnum):
-        (KJS::Bindings::QtMethodMatchType::unresolved):
-        (KJS::Bindings::QtMethodMatchType::typeId):
-        (KJS::Bindings::QtMethodMatchType::name):
-        (KJS::Bindings::QtMethodMatchData::QtMethodMatchData):
-        (KJS::Bindings::QtMethodMatchData::isValid):
-        (KJS::Bindings::QtMethodMatchData::firstUnresolvedIndex):
-        (KJS::Bindings::indexOfMetaEnum):
-        (KJS::Bindings::findMethodIndex):
-        (KJS::Bindings::findSignalIndex):
-        (KJS::Bindings::QtRuntimeMetaMethod::QtRuntimeMetaMethod):
-        (KJS::Bindings::QtRuntimeMetaMethod::mark):
-        (KJS::Bindings::QtRuntimeMetaMethod::callAsFunction):
-        (KJS::Bindings::QtRuntimeMetaMethod::getOwnPropertySlot):
-        (KJS::Bindings::QtRuntimeMetaMethod::lengthGetter):
-        (KJS::Bindings::QtRuntimeMetaMethod::connectGetter):
-        (KJS::Bindings::QtRuntimeMetaMethod::disconnectGetter):
-        (KJS::Bindings::QtRuntimeConnectionMethod::QtRuntimeConnectionMethod):
-        (KJS::Bindings::QtRuntimeConnectionMethod::callAsFunction):
-        (KJS::Bindings::QtRuntimeConnectionMethod::getOwnPropertySlot):
-        (KJS::Bindings::QtRuntimeConnectionMethod::lengthGetter):
-        (KJS::Bindings::QtConnectionObject::QtConnectionObject):
-        (KJS::Bindings::QtConnectionObject::~QtConnectionObject):
-        (KJS::Bindings::QtConnectionObject::metaObject):
-        (KJS::Bindings::QtConnectionObject::qt_metacast):
-        (KJS::Bindings::QtConnectionObject::qt_metacall):
-        (KJS::Bindings::QtConnectionObject::execute):
-        (KJS::Bindings::QtConnectionObject::match):
-        (KJS::Bindings::::QtArray):
-        (KJS::Bindings::::~QtArray):
-        (KJS::Bindings::::rootObject):
-        (KJS::Bindings::::setValueAt):
-        (KJS::Bindings::::valueAt):
-        * bindings/qt/qt_runtime.h:
-        (KJS::Bindings::QtField::):
-        (KJS::Bindings::QtField::QtField):
-        (KJS::Bindings::QtField::fieldType):
-        (KJS::Bindings::QtMethod::QtMethod):
-        (KJS::Bindings::QtMethod::name):
-        (KJS::Bindings::QtMethod::numParameters):
-        (KJS::Bindings::QtArray::getLength):
-        (KJS::Bindings::QtRuntimeMethod::d_func):
-        (KJS::Bindings::QtRuntimeMetaMethod::d_func):
-        (KJS::Bindings::QtRuntimeConnectionMethod::d_func):
-        (KJS::Bindings::):
-        * bindings/runtime.cpp:
-        (KJS::Bindings::Instance::createBindingForLanguageInstance):
-        (KJS::Bindings::Instance::createRuntimeObject):
-        (KJS::Bindings::Instance::reallyCreateRuntimeObject):
-        * bindings/runtime.h:
-
-2008-01-22  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Darin and Adam.
-
-        <rdar://problem/5688975>
-        div element on microsoft site has wrong left offset.
-        
-        Return true even if NPN_GetProperty returns null or undefined. This matches Firefox 
-        (and is what the Silverlight plug-in expects).
-        
-        * bindings/NP_jsobject.cpp:
-        (_NPN_GetProperty):
-
-2008-01-21  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed http://bugs.webkit.org/show_bug.cgi?id=16909
-        REGRESSION: Amazon.com crash (ActivationImp)
-        
-        (and a bunch of other crashes)
-        
-        Plus, a .7% SunSpider speedup to boot.
-        
-        Replaced the buggy currentExec and savedExec mechanisms with an
-        explicit ExecState stack.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::collect): Explicitly mark the ExecState stack.
-
-        (KJS::Collector::reportOutOfMemoryToAllExecStates): Slight change in
-        behavior: We no longer throw an exception in any global ExecStates,
-        since global ExecStates are more like pseudo-ExecStates, and aren't
-        used for script execution. (It's unclear what would happen if you left
-        an exception waiting around in a global ExecState, but it probably
-        wouldn't be good.)
-
-2008-01-21  Jan Michael Alonzo  <jmalonzo@unpluggable.com>
-
-        Reviewed by Alp Toker.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16955
-        Get errors when cross-compile webkit-gtk
-
-        * GNUmakefile.am: removed ICU_CFLAGS
-
-2008-01-18  Kevin McCullough  <kmccullough@apple.com>
-
-        - Build fix.
-
-        * kjs/ustring.h:
-
-2008-01-18  Kevin McCullough  <kmccullough@apple.com>
-
-        - Build fix.
-
-        * kjs/ustring.cpp:
-        * kjs/ustring.h:
-        (KJS::UString::cost):
-
-2008-01-18  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Geoff.
-
-        - Correctly report cost of appended strings to trigger GC.
-
-        * kjs/ustring.cpp:
-        (KJS::UString::Rep::create):
-        (KJS::UString::UString): Don't create unnecssary objects.
-        (KJS::UString::cost): Report cost if necessary but also keep track of 
-        reported cost.
-        * kjs/ustring.h:
-
-2008-01-18  Simon Hausmann  <hausmann@webkit.org>
-
-        Reviewed by Holger.
-
-        Fix return type conversions from Qt slots to JS values.
-        
-        This also fixes fast/dom/open-and-close-by-DOM.html, which called
-        layoutTestController.windowCount().
-        
-        When constructing the QVariant that holds the return type we cannot
-        use the QVarian(Type) constuctor as that will create a null variant.
-        We have to use the QVariant(Type, void *) constructor instead, just
-        like in QMetaObject::read() for example.
-        
-
-        * bindings/qt/qt_instance.cpp:
-        (KJS::Bindings::QtInstance::getRuntimeObject):
-
-2008-01-18  Prasanth Ullattil  <prasanth.ullattil@trolltech.com>
-
-        Reviewed by Simon Hausmann <hausmann@webkit.org>.
-
-        Fix compilation on Win64(2): Implemented currentThreadStackBase on X86-64 on Windows
-        
-
-        * kjs/collector.cpp:
-        (KJS::Collector::heapAllocate):
-
-2008-01-18  Prasanth Ullattil  <prasanth.ullattil@trolltech.com>
-
-        Reviewed by Simon Hausmann <hausmann@webkit.org>.
-
-        Fix compilation on Win64(1): Define WTF_PLATFORM_X86_64 correctly on Win64.
-        
-
-        * wtf/Platform.h:
-
-2008-01-17  Antti Koivisto  <antti@apple.com>
-
-        Fix Windows build.
-
-        * kjs/regexp_object.cpp:
-        (KJS::regExpProtoFuncToString):
-
-2008-01-16  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Darin.
-
-        Fix for http://bugs.webkit.org/show_bug.cgi?id=16901
-        Convert remaining JS function objects to use the new PrototypeFunction class
-
-        - Moves Boolean, Function, RegExp, Number, Object and Global functions to their
-          own static function implementations so that they can be used with the
-          PrototypeFunction class.  SunSpider says this is 1.003x as fast.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset):
-        * kjs/array_object.h:
-        * kjs/bool_object.cpp:
-        (KJS::BooleanInstance::BooleanInstance):
-        (KJS::BooleanPrototype::BooleanPrototype):
-        (KJS::booleanProtoFuncToString):
-        (KJS::booleanProtoFuncValueOf):
-        (KJS::BooleanObjectImp::BooleanObjectImp):
-        (KJS::BooleanObjectImp::implementsConstruct):
-        (KJS::BooleanObjectImp::construct):
-        (KJS::BooleanObjectImp::callAsFunction):
-        * kjs/bool_object.h:
-        (KJS::BooleanInstance::classInfo):
-        * kjs/error_object.cpp:
-        (KJS::ErrorPrototype::ErrorPrototype):
-        (KJS::errorProtoFuncToString):
-        * kjs/error_object.h:
-        * kjs/function.cpp:
-        (KJS::globalFuncEval):
-        (KJS::globalFuncParseInt):
-        (KJS::globalFuncParseFloat):
-        (KJS::globalFuncIsNaN):
-        (KJS::globalFuncIsFinite):
-        (KJS::globalFuncDecodeURI):
-        (KJS::globalFuncDecodeURIComponent):
-        (KJS::globalFuncEncodeURI):
-        (KJS::globalFuncEncodeURIComponent):
-        (KJS::globalFuncEscape):
-        (KJS::globalFuncUnEscape):
-        (KJS::globalFuncKJSPrint):
-        (KJS::PrototypeFunction::PrototypeFunction):
-        * kjs/function.h:
-        * kjs/function_object.cpp:
-        (KJS::FunctionPrototype::FunctionPrototype):
-        (KJS::functionProtoFuncToString):
-        (KJS::functionProtoFuncApply):
-        (KJS::functionProtoFuncCall):
-        * kjs/function_object.h:
-        * kjs/number_object.cpp:
-        (KJS::NumberPrototype::NumberPrototype):
-        (KJS::numberProtoFuncToString):
-        (KJS::numberProtoFuncToLocaleString):
-        (KJS::numberProtoFuncValueOf):
-        (KJS::numberProtoFuncToFixed):
-        (KJS::numberProtoFuncToExponential):
-        (KJS::numberProtoFuncToPrecision):
-        * kjs/number_object.h:
-        (KJS::NumberInstance::classInfo):
-        (KJS::NumberObjectImp::classInfo):
-        (KJS::NumberObjectImp::):
-        * kjs/object_object.cpp:
-        (KJS::ObjectPrototype::ObjectPrototype):
-        (KJS::objectProtoFuncValueOf):
-        (KJS::objectProtoFuncHasOwnProperty):
-        (KJS::objectProtoFuncIsPrototypeOf):
-        (KJS::objectProtoFuncDefineGetter):
-        (KJS::objectProtoFuncDefineSetter):
-        (KJS::objectProtoFuncLookupGetter):
-        (KJS::objectProtoFuncLookupSetter):
-        (KJS::objectProtoFuncPropertyIsEnumerable):
-        (KJS::objectProtoFuncToLocaleString):
-        (KJS::objectProtoFuncToString):
-        * kjs/object_object.h:
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpPrototype::RegExpPrototype):
-        (KJS::regExpProtoFuncTest):
-        (KJS::regExpProtoFuncExec):
-        (KJS::regExpProtoFuncCompile):
-        (KJS::regExpProtoFuncToString):
-        * kjs/regexp_object.h:
-
-2008-01-16  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej & Darin.
-
-        Fixes Bug 16868: Gmail crash
-          and Bug 16871: Crash when loading apple.com/startpage
-
-        <http://bugs.webkit.org/show_bug.cgi?id=16868>
-        <rdar://problem/5686108>
-
-        <http://bugs.webkit.org/show_bug.cgi?id=16871>
-        <rdar://problem/5686670>
-
-        Adds ActivationImp tear-off for cross-window eval() and fixes an
-        existing garbage collection issue exposed by the ActivationImp tear-off
-        patch (r29425) that can occur when an ExecState's m_callingExec is
-        different than its m_savedExec.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::mark):
-        * kjs/function.cpp:
-        (KJS::GlobalFuncImp::callAsFunction):
-
-2008-01-16  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver.
-
-        Clean up MathObjectImp, it needed a little scrubbing.
-
-        * kjs/math_object.cpp:
-        (KJS::MathObjectImp::MathObjectImp):
-        (KJS::MathObjectImp::getOwnPropertySlot):
-        (KJS::MathObjectImp::getValueProperty):
-        (KJS::mathProtoFuncACos):
-        (KJS::mathProtoFuncASin):
-        (KJS::mathProtoFuncATan):
-        (KJS::mathProtoFuncATan2):
-        (KJS::mathProtoFuncCos):
-        (KJS::mathProtoFuncExp):
-        (KJS::mathProtoFuncLog):
-        (KJS::mathProtoFuncSin):
-        (KJS::mathProtoFuncSqrt):
-        (KJS::mathProtoFuncTan):
-        * kjs/math_object.h:
-        (KJS::MathObjectImp::classInfo):
-        (KJS::MathObjectImp::):
-
-2008-01-16  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Rename Lexer variable bol to atLineStart.
-
-        * kjs/lexer.cpp:
-        (KJS::Lexer::Lexer):
-        (KJS::Lexer::setCode):
-        (KJS::Lexer::nextLine):
-        (KJS::Lexer::lex):
-        * kjs/lexer.h:
-
-2008-01-16  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen and Anders Carlsson.
-
-        Remove uses of KJS_PURE_ECMA as we don't ever build with it defined,
-        and we have many features that are not included in the ECMA spec.
-
-        * kjs/lexer.cpp:
-        (KJS::Lexer::Lexer):
-        (KJS::Lexer::setCode):
-        (KJS::Lexer::nextLine):
-        (KJS::Lexer::lex):
-        * kjs/lexer.h:
-        * kjs/string_object.cpp:
-        * kjs/string_object.h:
-
-2008-01-15  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Geoffrey Garen.
-
-        Fix <rdar://problem/5595552> r27608 introduced a 20% increase in JS binary size, 4% increase in WebCore binary size
-
-        - This changes the way JS functions that use Lookup tables are handled.  Instead of using
-          one class per function, which allowed specialization of the virtual callAsFunction
-          method, we now use one class, PrototypeFunction, which takes a pointer to a static
-          function to use as the implementation.  This significantly decreases the binary size
-          of JavaScriptCore (about 145k on an Intel only build) while still keeping some of the
-          speedup r27608 garnered (SunSpider says this is 1.005x as slow, which should leave some
-          wiggle room from the original 1% speedup) and keeps the functions implementations in separate
-          functions to help with optimizations.
-
-        * JavaScriptCore.exp:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/array_object.cpp:
-        (KJS::arrayProtoFuncToString):
-        (KJS::arrayProtoFuncToLocaleString):
-        (KJS::arrayProtoFuncJoin):
-        (KJS::arrayProtoFuncConcat):
-        (KJS::arrayProtoFuncPop):
-        (KJS::arrayProtoFuncPush):
-        (KJS::arrayProtoFuncReverse):
-        (KJS::arrayProtoFuncShift):
-        (KJS::arrayProtoFuncSlice):
-        (KJS::arrayProtoFuncSort):
-        (KJS::arrayProtoFuncSplice):
-        (KJS::arrayProtoFuncUnShift):
-        (KJS::arrayProtoFuncFilter):
-        (KJS::arrayProtoFuncMap):
-        (KJS::arrayProtoFuncEvery):
-        (KJS::arrayProtoFuncForEach):
-        (KJS::arrayProtoFuncSome):
-        (KJS::arrayProtoFuncIndexOf):
-        (KJS::arrayProtoFuncLastIndexOf):
-        * kjs/array_object.h:
-        * kjs/date_object.cpp:
-        (KJS::DatePrototype::getOwnPropertySlot):
-        (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::dateProtoFuncSetMilliSeconds):
-        (KJS::dateProtoFuncSetUTCMilliseconds):
-        (KJS::dateProtoFuncSetSeconds):
-        (KJS::dateProtoFuncSetUTCSeconds):
-        (KJS::dateProtoFuncSetMinutes):
-        (KJS::dateProtoFuncSetUTCMinutes):
-        (KJS::dateProtoFuncSetHours):
-        (KJS::dateProtoFuncSetUTCHours):
-        (KJS::dateProtoFuncSetDate):
-        (KJS::dateProtoFuncSetUTCDate):
-        (KJS::dateProtoFuncSetMonth):
-        (KJS::dateProtoFuncSetUTCMonth):
-        (KJS::dateProtoFuncSetFullYear):
-        (KJS::dateProtoFuncSetUTCFullYear):
-        (KJS::dateProtoFuncSetYear):
-        (KJS::dateProtoFuncGetYear):
-        * kjs/date_object.h:
-        * kjs/function.cpp:
-        (KJS::PrototypeFunction::PrototypeFunction):
-        (KJS::PrototypeFunction::callAsFunction):
-        * kjs/function.h:
-        * kjs/lookup.h:
-        (KJS::HashEntry::):
-        (KJS::staticFunctionGetter):
-        * kjs/math_object.cpp:
-        (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/math_object.h:
-        * kjs/string_object.cpp:
-        (KJS::stringProtoFuncToString):
-        (KJS::stringProtoFuncValueOf):
-        (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/string_object.h:
-
-2008-01-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Adam Roben.
-        
-        Some tweaks to our headerdoc, suggested by David Gatwood on the docs
-        team.
-
-        * API/JSBase.h:
-        * API/JSObjectRef.h:
-        * API/JSStringRef.h:
-        * API/JSValueRef.h:
-
-2008-01-15  Alp Toker  <alp@atoker.com>
-
-        Rubber-stamped by Anders.
-
-        Make the HTTP backend configurable in the GTK+ port. curl is currently
-        the only option.
-
-        * wtf/Platform.h: Don't hard-code WTF_USE_CURL for GTK
-
-2008-01-15  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Beth Dakin.
-
-        Remove unneeded variable.
-
-        * kjs/string_object.cpp:
-        (KJS::StringProtoFuncSubstr::callAsFunction):
-
-2008-01-14  Steve Falkenburg  <sfalken@apple.com>
-
-        Use shared vsprops for most vcproj properties.
-        
-        Reviewed by Darin.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add missing Debug_Internal config.
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj: Add missing Debug_Internal config.
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj:
-
-2008-01-14  Adam Roben  <aroben@apple.com>
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Added
-        some headers that were missing from the vcproj so their contents will
-        be included in Find in Files.
-
-2008-01-14  Adam Roben  <aroben@apple.com>
-
-        Fix Bug 16871: Crash when loading apple.com/startpage
-
-        <http://bugs.webkit.org/show_bug.cgi?id=16871>
-        <rdar://problem/5686670>
-
-        Patch written by Darin, reviewed by me.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::mark): Call ActivationImp::markChildren if our
-        m_activation is on the stack. This is what ScopeChain::mark also does,
-        but apparently in some cases it's possible for an ExecState's
-        ActivationImp to not be in any ScopeChain.
-
-2008-01-14  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Oliver.
-
-        -<rdar://problem/5622667> REGRESSION (Leopard-ToT): Endless loading loop
-        trying to view techreport.com comments
-        - We need to set values in the map, because if they are already in the
-        map they will not be reset when we use add().
-
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::put):
-
-2008-01-14  Darin Adler  <darin@apple.com>
-
-        Reviewed by Adam.
-
-        - re-speed-up the page load test (my StringImpl change slowed it down)
-
-        * wtf/RefCounted.h:
-        (WTF::RefCounted::RefCounted): Allow derived classes to start with a reference
-        count other than 0. Eventually everyone will want to start with a 1. This is a
-        staged change. For now, there's a default of 0, and you can specify 1. Later,
-        there will be no default and everyone will have to specify. And then later, there
-        will be a default of 1. Eventually, we can take away even the option of starting
-        with 0!
-
-        * wtf/Vector.h:
-        (WTF::Vector::Vector): Sped up creation of non-empty vectors by removing the
-        overhead of first constructing something empty and then calling resize.
-        (WTF::Vector::clear): Sped up the common case of calling clear on an empty
-        vector by adding a check for that case.
-        (WTF::Vector::releaseBuffer): Marked this function inline and removed a branch
-        in the case of vectors with no inline capacity (normal vectors) by leaving out
-        the code to copy the inline buffer in that case.
-
-2008-01-14  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by David Kilzer.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16787
-        array.splice() with 1 element not working
-
-        Test: fast/js/array-splice.html
-
-        * kjs/array_object.cpp:
-        (KJS::ArrayProtoFuncSplice::callAsFunction): Implement this Mozilla extension, and fix
-        some other edge cases.
-
-2008-01-13  Steve Falkenburg  <sfalken@apple.com>
-
-        Share common files across projects.
-        
-        Unify vsprops files
-        Debug:          common.vsprops, debug.vsprops
-        Debug_Internal: common.vsprops, debug.vsprops, debug_internal.vsprops
-        Release:        common.vsprops, release.vsprops
-        
-        Shared properties can go into common.vsprops, shared debug settings can go into debug.vsprops.
-        debug_internal.vsprops will be mostly empty except for file path prefix modifiers.
-
-        Reviewed by Adam Roben.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * JavaScriptCore.vcproj/debug.vsprops: Removed.
-        * JavaScriptCore.vcproj/debug_internal.vsprops: Removed.
-        * JavaScriptCore.vcproj/release.vsprops: Removed.
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj:
-
-2008-01-13  Marius Bugge Monsen  <mbm@trolltech.com>
-
-        Contributions and review by Adriaan de Groot,
-        Simon Hausmann, Eric Seidel, and Darin Adler.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=16590
-          Compilation fixes for Solaris.
-
-        * kjs/DateMath.h:
-        (KJS::GregorianDateTime::GregorianDateTime): Use the WIN_OS code path
-        for SOLARIS too, presumably because Solaris also lacks the tm_gtoff and tm_zone
-        fields.
-        (KJS::GregorianDateTime::operator tm): Ditto.
-
-        * kjs/collector.cpp:
-        (KJS::currentThreadStackBase): Use thr_stksegment on Solaris.
-
-        * wtf/MathExtras.h:
-        (isfinite): Implement for Solaris.
-        (isinf): Ditto.
-        (signbit): Ditto. But this one is wrong, so I added a FIXME.
-
-        * wtf/Platform.h: Define PLATFORM(SOLARIS) when "sun" or "__sun" is defined.
-
-2008-01-13  Michael Goddard  <michael.goddard@trolltech.com>
-
-        Reviewed by Anders Carlsson.
-
-        Add binding language type to Instance.
-        Allows runtime determination of the type of an
-        Instance, to allow safe casting.  Doesn't actually
-        add any safe casting yet, though.
-
-        Add a helper function to get an Instance from a JSObject*.
-        Given an object and the expected binding language, see if
-        the JSObject actually wraps an Instance of the given type
-        and return it.  Otherwise return 0.
-
-        Move RuntimeObjectImp creations into Instance.
-        Make the ctor protected, and Instance a friend class, so
-        that all creation of RuntimeObjectImps goes through
-        one place.
-
-        Remove copy ctor/assignment operator for QtInstance.
-        Instance itself is Noncopyable, so QtInstance doesn't
-        need to have these.
-
-        Add caching for QtInstance and associated RuntimeObjectImps.
-        Push any dealings with QtLanguage bindings into QtInstance,
-        and cache them there, rather than in the Instance layer.  Add
-        a QtRuntimeObjectImp to help with caching.
-
-        * JavaScriptCore.exp:
-        * bindings/c/c_instance.h:
-        * bindings/jni/jni_instance.h:
-        * bindings/objc/objc_instance.h:
-        * bindings/qt/qt_instance.cpp:
-        (KJS::Bindings::QtRuntimeObjectImp::QtRuntimeObjectImp):
-        (KJS::Bindings::QtRuntimeObjectImp::~QtRuntimeObjectImp):
-        (KJS::Bindings::QtRuntimeObjectImp::invalidate):
-        (KJS::Bindings::QtRuntimeObjectImp::removeFromCache):
-        (KJS::Bindings::QtInstance::QtInstance):
-        (KJS::Bindings::QtInstance::~QtInstance):
-        (KJS::Bindings::QtInstance::getQtInstance):
-        (KJS::Bindings::QtInstance::getRuntimeObject):
-        * bindings/qt/qt_instance.h:
-        (KJS::Bindings::QtInstance::getBindingLanguage):
-        * bindings/runtime.cpp:
-        (KJS::Bindings::Instance::createBindingForLanguageInstance):
-        (KJS::Bindings::Instance::createRuntimeObject):
-        (KJS::Bindings::Instance::getInstance):
-        * bindings/runtime.h:
-        * bindings/runtime_object.h:
-        (KJS::RuntimeObjectImp::getInternalInstance):
-
-2008-01-12  Alp Toker  <alp@atoker.com>
-
-        Reviewed by Mark Rowe.
-
-        Hide non-public symbols in GTK+/autotools release builds.
-
-        * GNUmakefile.am:
-
-2008-01-12  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Mark Rowe.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=16852
-        Fixes leaking of ActivationStackNode objects.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::deleteActivationStack):
-        (KJS::JSGlobalObject::~JSGlobalObject):
-        (KJS::JSGlobalObject::init):
-        (KJS::JSGlobalObject::reset):
-        * kjs/JSGlobalObject.h:
-
-2008-01-12  Darin Adler  <darin@apple.com>
-
-        - try to fix Qt Windows build
-
-        * pcre/dftables: Remove reliance on the list form of Perl pipes.
-
-2008-01-12  Darin Adler  <darin@apple.com>
-
-        - try to fix Qt build
-
-        * kjs/function.cpp: Added include of scope_chain_mark.h.
-        * kjs/scope_chain_mark.h: Added multiple-include guards.
-
-2008-01-12  Mark Rowe  <mrowe@apple.com>
-
-        Another Windows build fix.
-
-        * kjs/Activation.h:
-
-2008-01-12  Mark Rowe  <mrowe@apple.com>
-
-        Attempted Windows build fix.  Use struct consistently when forward-declaring
-        ActivationStackNode and StackActivation.
-
-        * kjs/Activation.h:
-        * kjs/JSGlobalObject.h:
-
-2008-01-12  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Fixes a problem with the ActivationImp tear-off patch (r29425) where
-        some of the calls to JSGlobalObject::tearOffActivation() were using
-        the wrong test to determine whether it should leave a relic behind.
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::argumentsGetter):
-        (KJS::ActivationImp::getOwnPropertySlot):
-
-2008-01-11  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed <rdar://problem/5665251> REGRESSION (r28880-r28886): Global
-        variable access (16644)
-        
-        This bug was caused by var declarations shadowing built-in properties of
-        the global object.
-        
-        To match Firefox, we've decided that var declarations will never shadow
-        built-in properties of the global object or its prototypes. We used to
-        behave more like IE, which allows shadowing, but walking that line got
-        us into trouble with websites that sent us down the Firefox codepath.
-
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTableGet): New code to support calling
-        hasProperty before the variable object is fully initialized (so you
-        can call it during initialization).
-
-        * kjs/nodes.cpp:.
-        (KJS::ProgramNode::initializeSymbolTable): Always do a full hasProperty
-        check when looking for duplicates, not getDirect, since it only checks
-        the property map, and not hasOwnProperty, since it doesn't check
-        prototypes.
-        (KJS::EvalNode::processDeclarations): ditto
-
-        * kjs/property_slot.h:
-        (KJS::PropertySlot::ungettableGetter): Best function name evar.
-
-2008-01-11  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Maciej.
-
-        Optimized ActivationImp allocation, so that activation records are now
-        first allocated on an explicitly managed stack and only heap allocated
-        when necessary. Roughly a 5% improvement on SunSpider, and a larger
-        improvement on benchmarks that use more function calls.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/Activation.h: Added.
-        (KJS::ActivationImp::ActivationData::ActivationData):
-        (KJS::ActivationImp::ActivationImp):
-        (KJS::ActivationImp::classInfo):
-        (KJS::ActivationImp::isActivationObject):
-        (KJS::ActivationImp::isOnStack):
-        (KJS::ActivationImp::d):
-        (KJS::StackActivation::StackActivation):
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        (KJS::ExecState::~ExecState):
-        * kjs/ExecState.h:
-        (KJS::ExecState::replaceScopeChainTop):
-        (KJS::ExecState::setActivationObject):
-        (KJS::ExecState::setLocalStorage):
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset):
-        (KJS::JSGlobalObject::pushActivation):
-        (KJS::JSGlobalObject::checkActivationCount):
-        (KJS::JSGlobalObject::popActivationHelper):
-        (KJS::JSGlobalObject::popActivation):
-        (KJS::JSGlobalObject::tearOffActivation):
-        * kjs/JSGlobalObject.h:
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::JSVariableObjectData::JSVariableObjectData):
-        (KJS::JSVariableObject::JSVariableObject):
-        * kjs/function.cpp:
-        (KJS::FunctionImp::argumentsGetter):
-        (KJS::ActivationImp::ActivationImp):
-        (KJS::ActivationImp::~ActivationImp):
-        (KJS::ActivationImp::init):
-        (KJS::ActivationImp::getOwnPropertySlot):
-        (KJS::ActivationImp::markHelper):
-        (KJS::ActivationImp::mark):
-        (KJS::ActivationImp::ActivationData::ActivationData):
-        (KJS::GlobalFuncImp::callAsFunction):
-        * kjs/function.h:
-        * kjs/nodes.cpp:
-        (KJS::PostIncResolveNode::evaluate):
-        (KJS::PostDecResolveNode::evaluate):
-        (KJS::PreIncResolveNode::evaluate):
-        (KJS::PreDecResolveNode::evaluate):
-        (KJS::ReadModifyResolveNode::evaluate):
-        (KJS::AssignResolveNode::evaluate):
-        (KJS::WithNode::execute):
-        (KJS::TryNode::execute):
-        (KJS::FunctionBodyNode::processDeclarations):
-        (KJS::FuncExprNode::evaluate):
-        * kjs/object.h:
-        * kjs/scope_chain.h:
-        (KJS::ScopeChain::replace):
-        * kjs/scope_chain_mark.h: Added.
-        (KJS::ScopeChain::mark):
-
-2008-01-11  Simon Hausmann  <hausmann@webkit.org>
-
-        Reviewed by Mark Rowe.
-
-        Fix the (clean) qmake build. For generating chartables.c we don't
-        depend on a separate input source file anymore, the dftables perl
-        script is enough. So use that instead as value for the .input
-        variable, to ensure that qmake also generates a rule to call dftables.
-
-        * pcre/pcre.pri:
-
-2008-01-10  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by John Sullivan.
-
-        Fixed some world leak reports:
-        * <rdar://problem/5669436> PLT complains about world leak of 1 JavaScript
-        Interpreter after running cvs-base suite
-
-        * <rdar://problem/5669423> PLT complains about world leak if browser
-        window is open when PLT starts
-        
-        * kjs/collector.h: Added the ability to distinguish between global
-        objects and GC-protected global objects, since we only consider the
-        latter to be world leaks.
-        * kjs/collector.cpp:
-
-2008-01-11  Mark Rowe  <mrowe@apple.com>
-
-        Silence qmake warning about ctgen lacking input.
-
-        Rubber-stamped by Alp Toker.
-
-        * pcre/pcre.pri:
-
-2008-01-10  David Kilzer  <ddkilzer@apple.com>
-
-        dftables should be rewritten as a script
-
-        <http://bugs.webkit.org/show_bug.cgi?id=16818>
-        <rdar://problem/5681463>
-
-        Reviewed by Darin.
-
-        Rewrote the dftables utility in Perl.  Attempted to switch all
-        build systems to call the script directly instead of building
-        a binary first.  Only the Xcode build was able to be tested.
-
-        * DerivedSources.make: Added pcre directory to VPATH and changed
-        to invoke dftables directly.
-        * GNUmakefile.am: Removed build information and changed to invoke
-        dftables directly.
-        * JavaScriptCore.vcproj/JavaScriptCore.sln: Removed reference to
-        dftables project.
-        * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Ditto.
-        * JavaScriptCore.vcproj/dftables: Removed.
-        * JavaScriptCore.vcproj/dftables/dftables.vcproj: Removed.
-        * JavaScriptCore.xcodeproj/project.pbxproj: Removed dftables target.
-        * jscore.bkl: Removed dftables executable definition.
-        * pcre/dftables: Copied from JavaScriptCore/pcre/dftables.cpp.
-        * pcre/dftables.cpp: Removed.
-        * pcre/dftables.pro: Removed.
-        * pcre/pcre.pri: Removed references to dftables.cpp and changed to
-        invoke dftables directly.
-
-2008-01-10  Dan Bernstein  <mitz@apple.com>
-
-        Reviewed by Darin Adler.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16782
-          <rdar://problem/5675331> REGRESSION(r29266): Reproducible crash in fast/replaced/image-map.html
-
-        The crash resulted from a native object (DumpRenderTree's
-        EventSender) causing its wrapper to be invalidated (by clicking a
-        link that replaced the document in the window) and consequently
-        deallocated. The fix is to use RefPtrs to protect the native object
-        from deletion by self-invalidation.
-
-        * bindings/runtime_method.cpp:
-        (RuntimeMethod::callAsFunction):
-        * bindings/runtime_object.cpp:
-        (RuntimeObjectImp::fallbackObjectGetter):
-        (RuntimeObjectImp::fieldGetter):
-        (RuntimeObjectImp::methodGetter):
-        (RuntimeObjectImp::put):
-        (RuntimeObjectImp::defaultValue):
-        (RuntimeObjectImp::callAsFunction):
-
-2008-01-07  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Turn testIsInteger assertions into compile-time asserts and move them into HashTraits.h
-        where possible.
-
-        * kjs/testkjs.cpp:
-        * wtf/HashTraits.h:
-
-2008-01-07  Nikolas Zimmermann  <zimmermann@kde.org>
-
-        Reviewed by Mark.
-
-        Enable SVG_FONTS by default.
-
-        * Configurations/JavaScriptCore.xcconfig:
-
-2008-01-07  Darin Adler  <darin@apple.com>
-
-        Rubber stamped by David Kilzer.
-
-        - get rid of empty fpconst.cpp
-
-        * GNUmakefile.am: Remove fpconst.cpp.
-        * JavaScriptCore.pri: Ditto.
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Ditto.
-        * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
-        * JavaScriptCoreSources.bkl: Ditto.
-
-        * kjs/fpconst.cpp: Removed.
-
-2008-01-07  Darin Adler  <darin@apple.com>
-
-        Reviewed by David Kilzer.
-
-        - fix alignment problem with NaN and Inf globals
-
-        * kjs/fpconst.cpp: Move the contents of this file from here back to
-        value.cpp. The reason this was in a separate file is that the DARWIN
-        version of this used a declaration of the globals with a different
-        type to avoid creating "init routines". That's no longer necessary for
-        DARWIN and was never necessary for the non-DARWIN code path.
-        To make this patch easy to merge, I didn't actually delete this file
-        yet. We'll do that in a separate changeset.
-
-        * kjs/value.cpp: If C99's NAN and INFINITY are present, then use them,
-        othrewise use the union trick from fpconst.cpp. I think it would be
-        better to eliminate KJS::NaN and KJS::Inf and just use NAN and INFINITY
-        directly or std::numeric_limits<double>::quiet_nan() and
-        std::numeric_limits<double>::infinity(). But when I tried that, it
-        slowed down SunSpider. Someone else could do that cleanup if they
-        could do it without slowing down the engine.
-
-2008-01-07  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Added
-        JavaScript.h to the project.
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
-        Copy JavaScript.h to WEBKITOUTPUTDIR.
-
-2008-01-07  Timothy Hatcher  <timothy@apple.com>
-
-        Reviewed by Darin.
-
-        Fix Mac build.
-
-        * API/JSNode.c:
-        * API/JSNode.h:
-        * API/JSNodeList.c:
-        * API/JSNodeList.h:
-        * API/JavaScript.h:
-        * API/JavaScriptCore.h:
-        * API/minidom.c:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-01-07  Alp Toker  <alp@atoker.com>
-
-        Reviewed by Darin.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16029
-        JavaScriptCore.h is not suitable for platforms other than Mac OS X
-
-        Introduce a new JavaScriptCore/JavaScript.h public API header. This
-        should be used by all new portable code using the JavaScriptCore API.
-
-        JavaScriptCore/JavaScriptCore.h will remain for compatibility with
-        existing applications that depend on it including JSStringRefCF.h
-        which isn't portable.
-
-        Also add minidom to the GTK+/autotools build since we can now support
-        it on all platforms.
-
-        * API/JSNode.h:
-        * API/JSNodeList.h:
-        * API/JavaScript.h: Added.
-        * API/JavaScriptCore.h:
-        * ForwardingHeaders/JavaScriptCore/JavaScript.h: Added.
-        * GNUmakefile.am:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2008-01-06  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Abstract all DateObject.set* functions in preparation for fixing:
-        http://bugs.webkit.org/show_bug.cgi?id=16753
-        
-        SunSpider had random changes here and there but was overall a wash.
-
-        * kjs/date_object.cpp:
-        (KJS::fillStructuresUsingTimeArgs):
-        (KJS::setNewValueFromTimeArgs):
-        (KJS::setNewValueFromDateArgs):
-        (KJS::DateProtoFuncSetMilliSeconds::callAsFunction):
-        (KJS::DateProtoFuncSetUTCMilliseconds::callAsFunction):
-        (KJS::DateProtoFuncSetSeconds::callAsFunction):
-        (KJS::DateProtoFuncSetUTCSeconds::callAsFunction):
-        (KJS::DateProtoFuncSetMinutes::callAsFunction):
-        (KJS::DateProtoFuncSetUTCMinutes::callAsFunction):
-        (KJS::DateProtoFuncSetHours::callAsFunction):
-        (KJS::DateProtoFuncSetUTCHours::callAsFunction):
-        (KJS::DateProtoFuncSetDate::callAsFunction):
-        (KJS::DateProtoFuncSetUTCDate::callAsFunction):
-        (KJS::DateProtoFuncSetMonth::callAsFunction):
-        (KJS::DateProtoFuncSetUTCMonth::callAsFunction):
-        (KJS::DateProtoFuncSetFullYear::callAsFunction):
-        (KJS::DateProtoFuncSetUTCFullYear::callAsFunction):
-
-2008-01-06  Nikolas Zimmermann  <zimmermann@kde.org>
-
-        Reviewed by Dan.
-
-        Add new helper function isArabicChar - SVG Fonts support needs it.
-
-        * wtf/unicode/icu/UnicodeIcu.h:
-        (WTF::Unicode::isArabicChar):
-        * wtf/unicode/qt4/UnicodeQt4.h:
-        (WTF::Unicode::isArabicChar):
-
-2008-01-06  Alp Toker  <alp@atoker.com>
-
-        Reviewed by Mark Rowe.
-
-        Use $(EXEEXT) to account for the .exe extension in the GTK+ Windows
-        build. (This is already done correctly in DerivedSources.make.) Issue
-        noticed by Mikkel when building in Cygwin.
-
-        Add a missing slash. This was a hack from the qmake build system that
-        isn't necessary with autotools.
-
-        * GNUmakefile.am:
-
-2008-01-05  Darin Adler  <darin@apple.com>
-
-        * API/JSRetainPtr.h: One more file that needed the change below.
-
-2008-01-05  Darin Adler  <darin@apple.com>
-
-        * wtf/OwnPtr.h: OwnPtr needs the same fix as RefPtr below.
-
-2008-01-05  Adam Roben  <aroben@apple.com>
-
-        Build fix.
-
-        Reviewed by Maciej.
-
-        * wtf/RetainPtr.h: Use PtrType instead of T* because of the
-        RemovePointer magic.
-
-2008-01-05  Darin Adler  <darin@apple.com>
-
-        Rubber stamped by Maciej Stachowiak.
-
-        - cut down own PIC branches by using a pointer-to-member-data instead of a
-          pointer-to-member-function in WTF smart pointers
-
-        * wtf/OwnArrayPtr.h:
-        * wtf/OwnPtr.h:
-        * wtf/PassRefPtr.h:
-        * wtf/RefPtr.h:
-        * wtf/RetainPtr.h:
-        Use a pointer to the m_ptr member instead of the get member.
-        The GCC compiler generates better code for this idiom.
-
-2008-01-05  Henry Mason  <hmason@mac.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16738
-        Bug 16738: Collector block offset could be stored as an cell offset instead of a byte offset
-
-        Gives a 0.4% SunSpider boost and prettier code.
-
-        * kjs/collector.cpp: Switched to cell offsets from byte offsets
-        (KJS::Collector::heapAllocate):
-        (KJS::Collector::sweep):
-
-2008-01-04  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Have the two malloc zones print useful diagnostics if their free method are unexpectedly invoked.
-        Due to <rdar://problem/5671357> this can happen if an application attempts to free a pointer that
-        was not allocated by any registered malloc zone on the system.
-
-        * kjs/CollectorHeapIntrospector.h:
-        * wtf/FastMalloc.cpp:
-
-2008-01-04  Alp Toker  <alp@atoker.com>
-
-        GTK+ autotools build fix. Terminate empty rules.
-
-        * GNUmakefile.am:
-
-2008-01-03  Simon Hausmann  <hausmann@webkit.org>
-
-        Reviewed by Mark Rowe.
-
-        Fix compilation with gcc 4.3: limits.h is needed for INT_MAX.
-
-        * pcre/pcre_exec.cpp:
-
-2008-01-03  Darin Adler  <darin@apple.com>
-
-        * tests/mozilla/expected.html: The fix for bug 16696 also fixed a test
-        case, ecma_3/RegExp/perlstress-002.js, so updated results to expect
-        that test to succeed.
-
-2008-01-02  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16696
-          JSCRE fails fails to match Acid3 regexp
-
-        Test: fast/regex/early-acid3-86.html
-
-        The problem was with the cutoff point between backreferences and octal
-        escape sequences. We need to determine the cutoff point by counting the
-        total number of capturing brackets, which requires an extra pass through
-        the expression when compiling it.
-
-        * pcre/pcre_compile.cpp:
-        (CompileData::CompileData): Added numCapturingBrackets. Removed some
-        unused fields.
-        (compileBranch): Use numCapturingBrackets when calling checkEscape.
-        (calculateCompiledPatternLength): Use numCapturingBrackets when calling
-        checkEscape, and also store the bracket count at the end of the compile.
-        (jsRegExpCompile): Call calculateCompiledPatternLength twice -- once to
-        count the number of brackets and then a second time to calculate the length.
-
-2008-01-02  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16696
-          JSCRE fails fails to match Acid3 regexp
-
-        Test: fast/regex/early-acid3-86.html
-
-        The problem was with the cutoff point between backreferences and octal
-        escape sequences. We need to determine the cutoff point by counting the
-        total number of capturing brackets, which requires an extra pass through
-        the expression when compiling it.
-
-        * pcre/pcre_compile.cpp:
-        (CompileData::CompileData): Added numCapturingBrackets. Removed some
-        unused fields.
-        (compileBranch): Use numCapturingBrackets when calling checkEscape.
-        (calculateCompiledPatternLength): Use numCapturingBrackets when calling
-        checkEscape, and also store the bracket count at the end of the compile.
-        (jsRegExpCompile): Call calculateCompiledPatternLength twice -- once to
-        count the number of brackets and then a second time to calculate the length.
-
-2008-01-02  David Kilzer <ddkilzer@webkit.org>
-
-        Reviewed and landed by Darin.
-
-        * kjs/nodes.cpp:
-        (KJS::DoWhileNode::execute): Added a missing return.
-
-2008-01-02  Darin Adler  <darin@apple.com>
-
-        - try to fix Qt build
-
-        * wtf/unicode/qt4/UnicodeQt4.h:
-        (WTF::Unicode::foldCase): Add some missing const.
-
-2008-01-02  Alice Liu  <alice.liu@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        need to export ASCIICType.h for use in DRT
-
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * wtf/ASCIICType.h:
-        (WTF::isASCIIUpper):
-
-2008-01-02  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Beth Dakin.
-
-        Cleanup error_object.h/cpp.
-
-        * kjs/JSGlobalObject.cpp:
-        (KJS::JSGlobalObject::reset):
-        * kjs/error_object.cpp:
-        (KJS::ErrorInstance::ErrorInstance):
-        (KJS::ErrorPrototype::ErrorPrototype):
-        (KJS::ErrorProtoFuncToString::ErrorProtoFuncToString):
-        (KJS::ErrorProtoFuncToString::callAsFunction):
-        (KJS::ErrorObjectImp::ErrorObjectImp):
-        (KJS::ErrorObjectImp::implementsConstruct):
-        (KJS::ErrorObjectImp::construct):
-        (KJS::ErrorObjectImp::callAsFunction):
-        (KJS::NativeErrorPrototype::NativeErrorPrototype):
-        (KJS::NativeErrorImp::NativeErrorImp):
-        (KJS::NativeErrorImp::implementsConstruct):
-        (KJS::NativeErrorImp::construct):
-        (KJS::NativeErrorImp::callAsFunction):
-        (KJS::NativeErrorImp::mark):
-        * kjs/error_object.h:
-        (KJS::ErrorInstance::classInfo):
-        (KJS::NativeErrorImp::classInfo):
-
-2008-01-02  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Alp Toker.
-
-        * GNUmakefile.am: Add missing dependency on grammar.y.
-
-2008-01-01  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        - fix for http://bugs.webkit.org/show_bug.cgi?id=16695
-          JSC allows non-identifier codepoints in identifiers (affects Acid3)
-
-        Test: fast/js/kde/parse.html
-
-        * kjs/lexer.cpp:
-        (KJS::Lexer::lex): Added additional states to distinguish Unicode escapes at the
-        start of identifiers from ones inside identifiers. Rejected characters that don't pass
-        the isIdentStart and isIdentPart tests.
-        (KJS::Lexer::convertUnicode): Removed incorrect FIXME comment.
-
-        * kjs/lexer.h: Added new states to distinguish \u escapes at the start of identifiers
-        from \u escapes inside identifiers.
-
-2008-01-01  Darin Adler  <darin@apple.com>
-
-        - rolled scope chain optimization out; it was breaking the world
-
-2008-01-01  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=16685
-          eliminate List::empty() to cut down on PIC branches
-
-        Also included one other speed-up -- remove the call to reserveCapacity from
-        FunctionBodyNode::processDeclarations in all but the most unusual cases.
-
-        Together these make SunSpider 1.016x as fast.
-
-        * JavaScriptCore.exp: Updated.
-        * kjs/ExecState.cpp:
-        (KJS::globalEmptyList): Added. Called only when creating global ExecState
-        instances.
-        (KJS::ExecState::ExecState): Broke constructor up into three separate functions,
-        for the three separate node types. Also went through each of the three and
-        streamlined as much as possible, removing dead code. This prevents us from having
-        to access the global in the function body version of the constructor.
-
-        * kjs/ExecState.h: Added emptyList(). Replaced the constructor with a set of
-        three that are specific to the different node types that can create new execution
-        state objects.
-
-        * kjs/array_object.cpp:
-        (KJS::ArrayProtoFuncToLocaleString::callAsFunction): Use exec->emptyList() instead
-        of List::empty().
-        (KJS::ArrayProtoFuncConcat::callAsFunction): Ditto.
-        (KJS::ArrayProtoFuncSlice::callAsFunction): Ditto.
-        (KJS::ArrayProtoFuncSplice::callAsFunction): Ditto.
-        (KJS::ArrayProtoFuncFilter::callAsFunction): Ditto.
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction): Updated to call new ExecState constructor.
-        (KJS::GlobalFuncImp::callAsFunction): Ditto (for eval).
-        * kjs/function_object.cpp:
-        (FunctionObjectImp::construct): Use exec->emptyList() instead of List::empty().
-
-        * kjs/list.cpp: Removed List::empty.
-        * kjs/list.h: Ditto.
-
-        * kjs/nodes.cpp:
-        (KJS::ElementNode::evaluate): Use exec->emptyList() instead of List::empty().
-        (KJS::ArrayNode::evaluate): Ditto.
-        (KJS::ObjectLiteralNode::evaluate): Ditto.
-        (KJS::PropertyListNode::evaluate): Ditto.
-        (KJS::FunctionBodyNode::processDeclarations): Another speed-up. Check the capacity
-        before calling reserveCapacity, because it doesn't get inlined the local storage
-        vector is almost always big enough -- saving the function call overhead is a big
-        deal.
-        (KJS::FuncDeclNode::makeFunction): Use exec->emptyList() instead of List::empty().
-        (KJS::FuncExprNode::evaluate): Ditto.
-        * kjs/object.cpp:
-        (KJS::tryGetAndCallProperty): Ditto.
-        * kjs/property_slot.cpp:
-        (KJS::PropertySlot::functionGetter): Ditto.
-        * kjs/string_object.cpp:
-        (KJS::StringProtoFuncSplit::callAsFunction): Ditto.
-
-2008-01-01  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16648
-          REGRESSION (r28165): Yuku.com navigation prints "jsRegExpExecute failed with result -2"
-          <rdar://problem/5646486> REGRESSION (r28165): Layout test fast/regex/test1 fails intermittently
-
-        Fixes 34 failing test cases in the fast/regex/test1.html test.
-
-        Restored the stack which prevents infinite loops for brackets that match the empty
-        string; it had been removed as an optimization.
-
-        Unfortunately, restoring this stack causes the regular expression test in SunSpider
-        to be 1.095x as slow and the overall test to be 1.004x as slow. Maybe we can find
-        a correct optimization to restore the speed!
-
-        It's possible the original change was on the right track but just off by one.
-
-        * pcre/pcre_exec.cpp: Add back eptrblock, but name it BracketChainNode.
-        (MatchStack::pushNewFrame): Add back the logic needed here.
-        (startNewGroup): Ditto.
-        (match): Ditto.
-
-2008-01-01  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=16683
-          speed up function calls by making ScopeChain::push cheaper
-
-        This gives a 1.019x speedup on SunSpider.
-
-        After doing this, I realized this probably will be obsolete when the optimization
-        to avoid creating an activation object is done. When we do that one we should check
-        if rolling this out will speed things up, since this does add overhead at the time
-        you copy the scope chain.
-
-        * kjs/object.h: Removed the ScopeChain::release function. It was
-        marked inline, and called in exactly one place, so moved it there.
-        No idea why it was in this header file!
-
-        * kjs/scope_chain.cpp: Removed the overload of the ScopeChain::push
-        function that takes another ScopeChain. It was unused. I think we used
-        it over in WebCore at one point, but not any more.
-
-        * kjs/scope_chain.h: Changed ScopeChainNode into a struct rather than
-        a class, got rid of its constructor so we can have one that's uninitialized,
-        and moved the refCount into a derived struct, ScopeChainHeapNode. Made _node
-        mutable so it can be changed in the moveToHeap function. Changed the copy
-        constructor and assignment operator to call moveToHeap, since the top node
-        can't be shared when it's embedded in another ScopeChain object. Updated
-        functions as needed to handle the case where the first object isn't on the
-        heap or to add casts for cases where it's guaranteed to be. Changed the push
-        function to always put the new node into the ScopeChain object; it will get
-        put onto the heap when needed later.
-
-2008-01-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Fixed slight logic error in reserveCapacity, where we would reallocate
-        the storage buffer unnecessarily.
-
-        * wtf/Vector.h:
-        (WTF::::reserveCapacity): No need to grow the buffer if newCapacity is
-        equal to capacity().
-
-2008-01-01  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=16684
-          eliminate debugger overhead from function body execution
-
-        Speeds SunSpider up 1.003x. That's a small amount, but measurable.
-
-        * JavaScriptCore.exp: Updated.
-        * kjs/Parser.h:
-        (KJS::Parser::parse): Create the node with a static member function named create() instead
-        of using new explicitly.
-
-        * kjs/grammar.y: Changed calls to new FunctionBodyNode to use FunctionBodyNode::create().
-
-        * kjs/nodes.cpp:
-        (KJS::ProgramNode::create): Added. Calls new.
-        (KJS::EvalNode::create): Ditto.
-        (KJS::FunctionBodyNode::create): Ditto, but creates FunctionBodyNodeWithDebuggerHooks
-        when a debugger is present.
-        (KJS::FunctionBodyNode::execute): Removed debugger hooks.
-        (KJS::FunctionBodyNodeWithDebuggerHooks::FunctionBodyNodeWithDebuggerHooks): Added.
-        (KJS::FunctionBodyNodeWithDebuggerHooks::execute): Calls the debugger, then the code,
-        then the debugger again.
-
-        * kjs/nodes.h: Added create functions, made the constructors private and protected.
-
-2007-12-30  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        More small cleanup to array_object.cpp
-
-        * kjs/array_object.cpp:
-        (KJS::ArrayProtoFuncToString::callAsFunction):
-        (KJS::ArrayProtoFuncToLocaleString::callAsFunction):
-        (KJS::ArrayProtoFuncJoin::callAsFunction):
-        (KJS::ArrayProtoFuncConcat::callAsFunction):
-        (KJS::ArrayProtoFuncReverse::callAsFunction):
-        (KJS::ArrayProtoFuncShift::callAsFunction):
-        (KJS::ArrayProtoFuncSlice::callAsFunction):
-        (KJS::ArrayProtoFuncSort::callAsFunction):
-        (KJS::ArrayProtoFuncSplice::callAsFunction):
-        (KJS::ArrayProtoFuncUnShift::callAsFunction):
-        (KJS::ArrayProtoFuncFilter::callAsFunction):
-        (KJS::ArrayProtoFuncMap::callAsFunction):
-        (KJS::ArrayProtoFuncEvery::callAsFunction):
-
-2007-12-30  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Apply wkstyle to array_object.cpp
-
-        * kjs/array_object.cpp:
-        (KJS::ArrayPrototype::ArrayPrototype):
-        (KJS::ArrayPrototype::getOwnPropertySlot):
-        (KJS::ArrayProtoFuncConcat::callAsFunction):
-        (KJS::ArrayProtoFuncPop::callAsFunction):
-        (KJS::ArrayProtoFuncReverse::callAsFunction):
-        (KJS::ArrayProtoFuncShift::callAsFunction):
-        (KJS::ArrayProtoFuncSlice::callAsFunction):
-        (KJS::ArrayProtoFuncSort::callAsFunction):
-        (KJS::ArrayProtoFuncSplice::callAsFunction):
-        (KJS::ArrayProtoFuncUnShift::callAsFunction):
-        (KJS::ArrayProtoFuncFilter::callAsFunction):
-        (KJS::ArrayProtoFuncMap::callAsFunction):
-        (KJS::ArrayProtoFuncEvery::callAsFunction):
-        (KJS::ArrayProtoFuncLastIndexOf::callAsFunction):
-        (KJS::ArrayObjectImp::ArrayObjectImp):
-        (KJS::ArrayObjectImp::implementsConstruct):
-        (KJS::ArrayObjectImp::construct):
-        (KJS::ArrayObjectImp::callAsFunction):
-
-2007-12-30  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Remove maxInt/minInt, replacing with std:max/min<int>()
-
-        * kjs/array_object.cpp:
-        (KJS::ArrayProtoFuncSplice::callAsFunction):
-        * kjs/operations.cpp:
-        * kjs/operations.h:
-
-2007-12-30  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-        
-        Update Number.toString to properly throw exceptions.
-        Cleanup code in Number.toString implementation.
-
-        * kjs/number_object.cpp:
-        (KJS::numberToString):
-        * kjs/object.cpp:
-        (KJS::Error::create): Remove bogus debug lines.
-
-2007-12-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Oliver.
-
-        ASSERT when debugging via Drosera due to missed var lookup optimization.
-        http://bugs.webkit.org/show_bug.cgi?id=16634
-        
-        No test case possible.
-
-        * kjs/nodes.cpp:
-        (KJS::BreakpointCheckStatement::optimizeVariableAccess):
-        * kjs/nodes.h:
-
-2007-12-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Oliver.
-
-        Fix (-0).toFixed() and re-factor a little
-        Fix (-0).toExponential() and printing of trailing 0s in toExponential
-        Fix toPrecision(nan) handling
-        http://bugs.webkit.org/show_bug.cgi?id=16640
-
-        * kjs/number_object.cpp:
-        (KJS::numberToFixed):
-        (KJS::fractionalPartToString):
-        (KJS::numberToExponential):
-        (KJS::numberToPrecision):
-
-2007-12-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        More changes to make number code readable
-
-        * kjs/number_object.cpp:
-        (KJS::integer_part_noexp):
-        (KJS::numberToFixed):
-        (KJS::numberToExponential):
-
-2007-12-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        More small cleanups to toPrecision
-
-        * kjs/number_object.cpp:
-        (KJS::numberToPrecision):
-
-2007-12-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        More small attempts to make number code readable
-
-        * kjs/number_object.cpp:
-        (KJS::exponentialPartToString):
-        (KJS::numberToExponential):
-        (KJS::numberToPrecision):
-
-2007-12-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Break out callAsFunction implementations into static functions
-
-        * kjs/number_object.cpp:
-        (KJS::numberToString):
-        (KJS::numberToFixed):
-        (KJS::numberToExponential):
-        (KJS::numberToPrecision):
-        (KJS::NumberProtoFunc::callAsFunction):
-
-2007-12-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Apply wkstyle/astyle and fix placement of *
-
-        * kjs/number_object.cpp:
-        (KJS::NumberInstance::NumberInstance):
-        (KJS::NumberPrototype::NumberPrototype):
-        (KJS::NumberProtoFunc::NumberProtoFunc):
-        (KJS::integer_part_noexp):
-        (KJS::intPow10):
-        (KJS::NumberProtoFunc::callAsFunction):
-        (KJS::NumberObjectImp::NumberObjectImp):
-        (KJS::NumberObjectImp::getOwnPropertySlot):
-        (KJS::NumberObjectImp::getValueProperty):
-        (KJS::NumberObjectImp::implementsConstruct):
-        (KJS::NumberObjectImp::construct):
-        (KJS::NumberObjectImp::callAsFunction):
-        * kjs/object.cpp:
-        (KJS::JSObject::put):
-
-2007-12-27  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        ASSERT in JavaScriptCore while viewing WICD test case
-        http://bugs.webkit.org/show_bug.cgi?id=16626
-        
-        * kjs/nodes.cpp:
-        (KJS::ForInNode::execute): move KJS_CHECK_EXCEPTION to proper place
-
-2007-12-26  Jan Michael Alonzo  <jmalonzo@unpluggable.com>
-
-        Reviewed by Alp Toker.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16390
-        Use autotools or GNU make as the build system for the GTK port
-
-        * GNUmakefile.am: Added.
-
-2007-12-25  Maciej Stachowiak  <mjs@apple.com>
-        
-        Reviewed by Oliver.
-                
-        - Remove unnecessary redundant check from property setting
-        http://bugs.webkit.org/show_bug.cgi?id=16602
-                
-        1.3% speedup on SunSpider.
-        
-        * kjs/object.cpp:
-        (KJS::JSObject::put): Don't do canPut check when not needed; let
-        the PropertyMap handle it.        
-        (KJS::JSObject::canPut): Don't check the static property
-        table. lookupPut does that already.
-        
-2007-12-24  Alp Toker  <alp@atoker.com>
-
-        Fix builds that don't use AllInOneFile.cpp following breakage
-        introduced in r28973.
-
-        * kjs/grammar.y:
-
-2007-12-24  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Eric.
-
-        - Optimize variable declarations
-        http://bugs.webkit.org/show_bug.cgi?id=16585
-        
-        3.5% speedup on SunSpider.
-
-        var statements now result in either assignments or empty statements.
-        
-        This allows a couple of optimization opportunities:
-        - No need to branch at runtime to check if there is an initializer
-        - EmptyStatementNodes can be removed entirely (also done in this patch)
-        - Assignment expressions get properly optimized for local variables
-        
-        This patch also includes some code cleanup:
-        - Most of the old VarStatement/VarDecl logic is now only used for const declarations, 
-          thus it is renamed appropriately
-        - AssignExprNode is gone
-        
-        * JavaScriptCore.exp:
-        * kjs/NodeInfo.h:
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::SourceElements::append):
-        (KJS::ConstDeclNode::ConstDeclNode):
-        (KJS::ConstDeclNode::optimizeVariableAccess):
-        (KJS::ConstDeclNode::handleSlowCase):
-        (KJS::ConstDeclNode::evaluateSingle):
-        (KJS::ConstDeclNode::evaluate):
-        (KJS::ConstStatementNode::optimizeVariableAccess):
-        (KJS::ConstStatementNode::execute):
-        (KJS::VarStatementNode::optimizeVariableAccess):
-        (KJS::VarStatementNode::execute):
-        (KJS::ForInNode::ForInNode):
-        (KJS::ForInNode::optimizeVariableAccess):
-        (KJS::ForInNode::execute):
-        (KJS::FunctionBodyNode::initializeSymbolTable):
-        (KJS::ProgramNode::initializeSymbolTable):
-        (KJS::FunctionBodyNode::processDeclarations):
-        (KJS::ProgramNode::processDeclarations):
-        (KJS::EvalNode::processDeclarations):
-        * kjs/nodes.h:
-        (KJS::DeclarationStacks::):
-        (KJS::StatementNode::):
-        (KJS::ConstDeclNode::):
-        (KJS::ConstStatementNode::):
-        (KJS::EmptyStatementNode::):
-        (KJS::VarStatementNode::):
-        (KJS::ForNode::):
-        * kjs/nodes2string.cpp:
-        (KJS::ConstDeclNode::streamTo):
-        (KJS::ConstStatementNode::streamTo):
-        (KJS::ScopeNode::streamTo):
-        (KJS::VarStatementNode::streamTo):
-        (KJS::ForNode::streamTo):
-        (KJS::ForInNode::streamTo):
-
-2007-12-21  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        * JavaScriptCore.exp: Remove unused symbol to prevent a weak external symbol
-        being generated in JavaScriptCore.framework.
-
-2007-12-21  Darin Adler  <darin@apple.com>
-
-        Requested by Maciej.
-
-        * kjs/nodes.h: Use the new NEVER_INLINE here and eliminate the old
-        KJS_NO_INLINE. We don't want to have two, and we figured it was better
-        to keep the one that's in WTF.
-
-2007-12-21  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=16561
-          remove debugger overhead from non-debugged JavaScript execution
-
-        1.022x as fast on SunSpider.
-
-        * JavaScriptCore.exp: Updated.
-
-        * kjs/NodeInfo.h: Renamed SourceElementsStub to SourceElements,
-        since that more accurately describes the role of this object, which
-        is a reference-counted wrapper for a Vector.
-
-        * kjs/Parser.cpp:
-        (KJS::Parser::didFinishParsing): Changed parameter type to SourceElements,
-        and use plain assignment instead of set.
-        * kjs/Parser.h: Changed parameter type of didFinishParsing to a
-        SourceElements. Also changed m_sourceElements; we now use a RefPtr instead
-        of an OwnPtr as well.
-
-        * kjs/grammar.y: Got rid of all the calls to release() on SourceElements.
-        That's now handed inside the constructors for various node types, since we now
-        use vector swapping instead.
-
-        * kjs/nodes.cpp:
-        (KJS::Node::rethrowException): Added NEVER_INLINE, because this was getting inlined
-        and we want exception handling out of the normal code flow.
-        (KJS::SourceElements::append): Moved here from the header. This now handles
-        creating a BreakpointCheckStatement for each statement in the debugger case.
-        That way we can get breakpoint handling without having it in every execute function.
-        (KJS::BreakpointCheckStatement::BreakpointCheckStatement): Added.
-        (KJS::BreakpointCheckStatement::execute): Added. Contains the code that was formerly
-        in the StatementNode::hitStatement function and the KJS_BREAKPOINT macro.
-        (KJS::BreakpointCheckStatement::streamTo): Added.
-        (KJS::ArgumentListNode::evaluateList): Use KJS_CHECKEXCEPTIONVOID since the return
-        type is void.
-        (KJS::VarStatementNode::execute): Removed KJS_BREAKPOINT.
-        (KJS::BlockNode::BlockNode): Changed parameter type to SourceElements.
-        Changed code to use release since the class now contains a vector rather than
-        a vector point.
-        (KJS::BlockNode::optimizeVariableAccess): Updated since member is now a vector
-        rather than a vector pointer.
-        (KJS::BlockNode::execute): Ditto.
-        (KJS::ExprStatementNode::execute): Removed KJS_BREAKPOINT.
-        (KJS::IfNode::execute): Ditto.
-        (KJS::IfElseNode::execute): Ditto.
-        (KJS::DoWhileNode::execute): Ditto.
-        (KJS::WhileNode::execute): Ditto.
-        (KJS::ContinueNode::execute): Ditto.
-        (KJS::BreakNode::execute): Ditto.
-        (KJS::ReturnNode::execute): Ditto.
-        (KJS::WithNode::execute): Ditto.
-        (KJS::CaseClauseNode::optimizeVariableAccess): Updated since member is now a vector
-        rather than a vector pointer.
-        (KJS::CaseClauseNode::executeStatements): Ditto.
-        (KJS::SwitchNode::execute): Removed KJS_BREAKPOINT.
-        (KJS::ThrowNode::execute): Ditto.
-        (KJS::TryNode::execute): Ditto.
-        (KJS::ScopeNode::ScopeNode): Changed parameter type to SourceElements.
-        (KJS::ProgramNode::ProgramNode): Ditto.
-        (KJS::EvalNode::EvalNode): Ditto.
-        (KJS::FunctionBodyNode::FunctionBodyNode): Ditto.
-        (KJS::ScopeNode::optimizeVariableAccess): Updated since member is now a vector
-        rather than a vector pointer.
-
-        * kjs/nodes.h: Removed hitStatement. Renamed SourceElements to StatementVector.
-        Renamed SourceElementsStub to SourceElements and made it derive from
-        ParserRefCounted rather than from Node, hold a vector rather than a pointer to
-        a vector, and changed the release function to swap with another vector rather
-        than the pointer idiom. Updated BlockNode and CaseClauseNode to hold actual
-        vectors instead of pointers to vectors. Added BreakpointCheckStatement.
-
-        * kjs/nodes2string.cpp:
-        (KJS::statementListStreamTo): Changed to work on a vector instead of a pointer
-        to a vector.
-        (KJS::BlockNode::streamTo): Ditto.
-        (KJS::CaseClauseNode::streamTo):  Ditto.
-
-        * wtf/AlwaysInline.h: Added NEVER_INLINE.
-        * wtf/PassRefPtr.h: Tweaked formatting. Added clear() function that matches the
-        ones in OwnPtr and auto_ptr.
-        * wtf/RefPtr.h: Ditto.
-
-2007-12-21  Darin Adler  <darin@apple.com>
-
-        - fix broken regression tests
-
-        The broken tests were fast/js/do-while-expression-value.html and
-        fast/js/while-expression-value.html.
-
-        * kjs/nodes.cpp: Check in the correct version of this file. I had accidentally landed
-        an old version of my patch for bug 16471.
-        (KJS::statementListExecute): The logic here was backwards. Have to set the value
-        even for non-normal execution results.
-
-2007-12-20  Alexey Proskuryakov  <ap@webkit.org>
-
-        Windows build fix
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Copy npruntime_internal.h
-        to WebKitBuild.
-
-2007-12-20  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by mjs.
-        
-        Split IfNode into IfNode and IfElseNode for speedup.
-        http://bugs.webkit.org/show_bug.cgi?id=16470
-        
-        SunSpider claims this is 1.003x as fast as before.
-        (This required running with --runs 15 to get consistent enough results to tell!)
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::IfNode::optimizeVariableAccess):
-        (KJS::IfNode::execute):
-        (KJS::IfNode::getDeclarations):
-        (KJS::IfElseNode::optimizeVariableAccess):
-        (KJS::IfElseNode::execute):
-        (KJS::IfElseNode::getDeclarations):
-        * kjs/nodes.h:
-        (KJS::IfNode::):
-        (KJS::IfElseNode::):
-        * kjs/nodes2string.cpp:
-        (KJS::IfNode::streamTo):
-        (KJS::IfElseNode::streamTo):
-
-2007-12-20  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        * wtf/OwnPtr.h:
-        (WTF::operator==): Added.
-        (WTF::operator!=): Added.
-
-2007-12-20  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        AST optimization: Avoid NULL-checking ForNode's child nodes.
-        
-        0.6% speedup on SunSpider.
-        
-        This is a proof of concept patch that demonstrates how to optimize
-        grammar productions with optional components, like
-        
-            for (optional; optional; optional) {
-                ...
-            }
-            
-        The parser emits NULL for an optional component that is not present.
-
-        Instead of checking for a NULL child at execution time, a node that
-        expects an optional component to be present more often than not checks
-        for a NULL child at construction time, and substitutes a viable
-        alternative node in its place.
-
-        (We'd like the parser to start emitting NULL a lot more once we teach
-        it to emit NULL for certain no-op productions like EmptyStatement and
-        VariableStatement, so, as a foundation, it's important for nodes with
-        NULL optional components to be fast.)
-
-        * kjs/Parser.cpp:
-        (KJS::Parser::didFinishParsing): Check for NULL SourceElements. Also,
-        moved didFinishParsing into the .cpp file because adding a branch while
-        it was in the header file caused a substantial and inexplicable
-        performance regression. (Did I mention that GCC is crazy?)
-
-        * kjs/grammar.y:
-
-        * kjs/nodes.cpp:
-        (KJS::BlockNode::BlockNode): Check for NULL SourceElements.
-        (KJS::ForNode::optimizeVariableAccess): No need to check for NULL here.
-        (KJS::ForNode::execute): No need to check for NULL here.
-        * kjs/nodes.h:
-        (KJS::ForNode::): Check for NULL SourceElements. Substitute a TrueNode
-        because it's semantically harmless, and it evaluates to boolean in an
-        efficient manner.
-
-2007-12-20  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Slight logic reordering in JSImmediate::from(double)
-
-        This gives a 0.6% improvement in SunSpider.
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::from):
-
-2007-12-20  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by mjs.
-
-        Fix major Array regression introduced by 28899.
-
-        SunSpider claims this is at least 1.37x as fast as pre-regression. :)
-
-        * kjs/array_instance.cpp: make Arrays fast again!
-
-2007-12-20  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Geoff, then re-rubber-stamped by Geoff after final search/replace and testing.
-
-        Small reworking of Date code for 4% speedup on Date tests (0.2% overall)
-        http://bugs.webkit.org/show_bug.cgi?id=16537
-
-        Make msToYear human-readable
-        Make msToDayInMonth slightly more readable and avoid recalculating msToYear
-        Remove use of isInLeapYear to avoid calling msToYear
-        Remove dayInYear call by changing msToDayInMonth to dayInMonthFromDayInYear
-        Remove more duplicate calls to dayInYear and getUTCOffset for further speedup
-
-        * kjs/DateMath.cpp:
-        (KJS::daysFrom1970ToYear):
-        (KJS::msToYear):
-        (KJS::monthFromDayInYear):
-        (KJS::checkMonth):
-        (KJS::dayInMonthFromDayInYear):
-        (KJS::dateToDayInYear):
-        (KJS::getDSTOffsetSimple):
-        (KJS::getDSTOffset):
-        (KJS::gregorianDateTimeToMS):
-        (KJS::msToGregorianDateTime):
-
-2007-12-20  Rodney Dawes  <dobey@wayofthemonkey.com>
-
-        Reviewed by Darin Adler.
-
-        Proxy includes of npruntime.h or npapi.h through npruntime_internal.h
-        Include stdio.h in npapi.h for the use of FILE with XP_UNIX defined
-        This is for building with X11, as some type and enum names conflict
-        with #define names in X11 headers.
-        http://bugs.webkit.org/show_bug.cgi?id=15669
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bindings/NP_jsobject.h:
-        * bindings/npapi.h:
-        * bindings/npruntime.cpp:
-        * bindings/npruntime_impl.h:
-        * bindings/npruntime_priv.h:
-        * bindings/npruntime_internal.h:
-        * bindings/testbindings.cpp:
-        * bindings/c/c_class.h:
-        * bindings/c/c_runtime.h:
-        * bindings/c/c_utility.h:
-
-2007-12-20  Darin Adler  <darin@apple.com>
-
-        - re-fix http://bugs.webkit.org/show_bug.cgi?id=16471
-          Completions need to be smaller (or not exist at all)
-
-        Same patch as last time with the test failures problem fixed.
-
-        * kjs/function.cpp:
-        (KJS::GlobalFuncImp::callAsFunction): Make sure to check the completion
-        type from newExec to see if the execute raised an exception.
-
-2007-12-20  Darin Adler  <darin@apple.com>
-
-        - roll out that last change -- it was causing test failures;
-          I'll check it back in after fixing them
-
-2007-12-20  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=16471
-          Completions need to be smaller (or not exist at all)
-
-        SuSpider shows 2.4% speedup.
-
-        Stop using completions in the execution engine.
-        Instead, the completion type and label target are both
-        stored in the ExecState.
-
-        * API/JSContextRef.cpp: Removed unneeded include of "completion.h".
-        * bindings/runtime_method.cpp: Removed unused execute function.
-        * bindings/runtime_method.h: Ditto.
-
-        * kjs/ExecState.h: Added completionType, breakOrContinueTarget,
-        setCompletionType, setNormalCompletion, setBreakCompletion,
-        setContinueCompletion, setReturnValueCompletion, setThrowCompletion,
-        setInterruptedCompletion, m_completionType, and m_breakOrContinueTarget.
-
-        * kjs/completion.h: Removed constructor and getter for target
-        for break and continue from Completion. This class is now only
-        used for the public API to Interpreter and such.
-
-        * kjs/date_object.h: Removed unused execute function.
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction): Removed some unneeded
-        exception processing. Updated to call the new execute function
-        and to get the completion type from the ExecState. Merged in
-        the execute function, which repeated some of the same logic and
-        was called only from here.
-        (KJS::GlobalFuncImp::callAsFunction): More of the same for eval.
-        * kjs/function.h: Removed execute.
-
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate): Added code to convert the result of
-        execut into a Completion.
-
-        * kjs/nodes.cpp:
-        (KJS::Node::setErrorCompletion): Renamed from createErrorCompletion.
-        Now sets the completion type in the ExecState.
-        (KJS::Node::rethrowException): Now sets the completion type in the
-        ExecState.
-        (KJS::StatementNode::hitStatement): Now sets the completion type in
-        the ExecState.
-        (KJS::VarStatementNode::execute): Updated to put completion type in
-        the ExecState instead of a Completion object.
-        (KJS::statementListExecute): Ditto. Also changed the for loop to use
-        indices instead of iterators.
-        (KJS::BlockNode::execute): Updated return type.
-        (KJS::EmptyStatementNode::execute): Updated to put completion type in
-        the ExecState instead of a Completion object.
-        (KJS::ExprStatementNode::execute): Ditto.
-        (KJS::IfNode::execute): Ditto.
-        (KJS::DoWhileNode::execute): Ditto. Also streamlined the logic a little
-        to make the normal case a little faster and moved the end outside the
-        loop so that "break" can do a break.
-        (KJS::WhileNode::execute): Ditto.
-        (KJS::ForNode::execute): Ditto.
-        (KJS::ForInNode::execute): Ditto.
-        (KJS::ContinueNode::execute): Updated to put completion type in
-        the ExecState instead of a Completion object.
-        (KJS::BreakNode::execute): Ditto.
-        (KJS::ReturnNode::execute): Ditto.
-        (KJS::WithNode::execute): Ditto.
-        (KJS::CaseClauseNode::executeStatements): Ditto. Also renamed to have
-        execute in its name to reflect the fact that it's a member of the same
-        family of functions.
-        (KJS::CaseBlockNode::executeBlock): Ditto.
-        (KJS::SwitchNode::execute): Ditto.
-        (KJS::LabelNode::execute): Ditto.
-        (KJS::ThrowNode::execute): Ditto.
-        (KJS::TryNode::execute): Ditto.
-        (KJS::ProgramNode::execute): Ditto.
-        (KJS::EvalNode::execute): Ditto.
-        (KJS::FunctionBodyNode::execute): Ditto.
-        (KJS::FuncDeclNode::execute): Ditto.
-
-        * kjs/nodes.h: Renamed setErrorCompletion to createErrorCompletion, made
-        hitStatement protected, changed return value of execute to a JSValue,
-        renamed evalStatements to executeStatements, and evalBlock to executeBlock.
-
-        * kjs/number_object.h: Removed unused execute function.
-
-2007-12-20  Geoffrey Garen  <ggaren@apple.com>
-
-        Added Radar number.
-
-        * kjs/nodes.cpp:
-        (KJS::ProgramNode::processDeclarations):
-
-2007-12-20  Geoffrey Garen  <ggaren@apple.com>
-
-        Linux build fix: config.h has to come first.
-
-        * kjs/error_object.cpp:
-
-2007-12-19  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Optimized global access to global variables, using a symbol table.
-        
-        SunSpider reports a 1.5% overall speedup, a 6.2% speedup on 3d-morph,
-        and a whopping 33.1% speedup on bitops-bitwise-and.
-
-        * API/JSCallbackObjectFunctions.h: Replaced calls to JSObject:: with
-        calls to Base::, since JSObject is not always our base class. This
-        was always a bug, but the bug is even more apparent after some of my
-        changes.
-
-        (KJS::::staticFunctionGetter): Replaced use of getDirect with call to
-        getOwnPropertySlot. Global declarations are no longer stored in the
-        property map, so a call to getDirect is insufficient for finding
-        override properties.
-
-        * API/testapi.c: 
-        * API/testapi.js: Added test for the getDirect change mentioned above.
-
-        * kjs/ExecState.cpp: 
-        * kjs/ExecState.h: Dialed back the optimization to store a direct
-        pointer to the localStorage buffer. One ExecState can grow the global
-        object's localStorage without another ExecState's knowledge, so
-        ExecState can't store a direct pointer to the localStorage buffer
-        unless/until we invent a way to update all the relevant ExecStates.
-
-        * kjs/JSGlobalObject.cpp: Inserted the symbol table into get and put
-        operations.
-        (KJS::JSGlobalObject::reset): Reset the symbol table and local storage,
-        too. Also, clear the property map here, removing the need for a
-        separate call.
-
-        * kjs/JSVariableObject.cpp:
-        * kjs/JSVariableObject.h: Added support for saving localStorage and the
-        symbol table to the back/forward cache, and restoring them.
-
-        * kjs/function.cpp:
-        (KJS::GlobalFuncImp::callAsFunction): Renamed progNode to evalNode
-        because it's an EvalNode, not a ProgramNode.
-
-        * kjs/lookup.h:
-        (KJS::cacheGlobalObject): Replaced put with faster putDirect, since
-        that's how the rest of lookup.h works. putDirect is safe here because
-        cacheGlobalObject is only used for objects whose names are not valid
-        identifiers.
-
-        * kjs/nodes.cpp: The good stuff!
-
-        (KJS::EvalNode::processDeclarations): Replaced hasProperty with
-        the new hasOwnProperty, which is slightly faster.
-
-        * kjs/object.h: Nixed clearProperties because clear() does this job now.
-
-        * kjs/property_map.cpp:
-        * kjs/property_map.h: More back/forward cache support.
-        
-        * wtf/Vector.h:
-        (WTF::::grow): Added fast non-branching grow function. I used it in
-        an earlier version of this patch, even though it's not used anymore.
-
-2007-12-09  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver Hunt.
-
-        Build fix for non-Mac platforms.  Move NodeInfo into its own header so that the YYTYPE
-        declaration in grammar.h is able to declare members of that type.
-
-        * kjs/NodeInfo.h: Added.
-        (KJS::createNodeInfo):
-        (KJS::mergeDeclarationLists):
-        (KJS::appendToVarDeclarationList):
-        * kjs/grammar.y:
-        * kjs/lexer.cpp:
-
-2007-12-19  Oliver Hunt  <oliver@apple.com>
-
-        Make appendToVarDeclarationList static
-
-        RS=Weinig.
-
-        * kjs/grammar.y:
-
-2007-12-18  Oliver Hunt  <oliver@apple.com>
-
-        Remove dead code due to removal of post-parse declaration discovery.
-
-        RS=Geoff.
-
-        Due to the removal of the declaration discovery pass after parsing we
-        no longer need any of the logic used for that discovery.
-
-        * kjs/nodes.cpp:
-        (KJS::Node::Node):
-        (KJS::VarDeclNode::VarDeclNode):
-        (KJS::BlockNode::BlockNode):
-        (KJS::ForInNode::ForInNode):
-        (KJS::CaseBlockNode::CaseBlockNode):
-        * kjs/nodes.h:
-        (KJS::VarStatementNode::):
-        (KJS::IfNode::):
-        (KJS::DoWhileNode::):
-        (KJS::WhileNode::):
-        (KJS::WithNode::):
-        (KJS::LabelNode::):
-        (KJS::TryNode::):
-        (KJS::FuncDeclNode::):
-        (KJS::CaseClauseNode::):
-        (KJS::ClauseListNode::):
-        (KJS::SwitchNode::):
-
-2007-12-18  Oliver Hunt  <oliver@apple.com>
-
-        Replace post-parse pass to find declarations with logic in the parser itself
-
-        Reviewed by Geoff.
-
-        Instead of finding declarations in a pass following the initial parsing of
-        a program, we incorporate the logic directly into the parser.  This lays
-        the groundwork for further optimisations (such as improving performance in
-        declaration expressions -- var x = y; -- to match that of standard assignment)
-        in addition to providing a 0.4% performance improvement in SunSpider.
-
-        * JavaScriptCore.exp:
-        * kjs/Parser.cpp:
-        (KJS::Parser::parse):
-        * kjs/Parser.h:
-        (KJS::Parser::didFinishParsing):
-        (KJS::Parser::parse):
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::ParserTracked::ParserTracked):
-        (KJS::ParserTracked::~ParserTracked):
-        (KJS::ParserTracked::ref):
-        (KJS::ParserTracked::deref):
-        (KJS::ParserTracked::refcount):
-        (KJS::ParserTracked::clearNewTrackedObjects):
-        (KJS::Node::Node):
-        (KJS::ScopeNode::ScopeNode):
-        (KJS::ProgramNode::ProgramNode):
-        (KJS::EvalNode::EvalNode):
-        (KJS::FunctionBodyNode::FunctionBodyNode):
-        (KJS::FunctionBodyNode::initializeSymbolTable):
-        (KJS::FunctionBodyNode::processDeclarations):
-        * kjs/nodes.h:
-        (KJS::ParserTracked::):
-        (KJS::Node::):
-        (KJS::ScopeNode::):
-
-2007-12-18  Xan Lopez  <xan@gnome.org>
-
-        Reviewed by Geoff.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=14521
-        Bug 14521: JavaScriptCore fails to build on Linux/PPC gcc 4.1.2
-        
-        * wtf/TCSpinLock.h:
-        (TCMalloc_SpinLock::Unlock):
-
-        Use less strict memory operand constraint on inline asm generation.
-        PLATFORM(DARWIN) left unpatched due to Apple's GCC bug.
-
-        Patch by David Kilzer <ddkilzer@webkit.org>
-
-2007-12-18  Mark Rowe  <mrowe@apple.com>
-
-        Rubber-stamped by Maciej Stachowiak.
-
-        Remove outdated and non-functioning project files for the Apollo port.
-
-        * JavaScriptCore.apolloproj: Removed.
-
-2007-12-18  Darin Adler  <darin@apple.com>
-
-        - fix Windows build
-
-        * pcre/pcre_exec.cpp:
-        (jsRegExpExecute): Change back from false/true to 0/1 -- I probably should not have
-        deleted MATCH_MATCH and MATCH_NOMATCH, but I'm going to leave them out.
-
-2007-12-18  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16458
-          REGRESSION (r28164): regular expressions can now hang due to lack of a match limit
-          <rdar://problem/5636067>
-
-        Test: fast/regex/slow.html
-
-        Slows down SunSpider a bit (about 1.01x); filed a bug to follow up on that:
-        http://bugs.webkit.org/show_bug.cgi?id=16503
-
-        * pcre/pcre.h: Changed name of error code to not specifically mention "recursion".
-        * pcre/pcre_exec.cpp:
-        (match): Replaced the depth limit, MATCH_RECURSION_LIMIT, with a total match looping
-        limit, matchLimit. Also eliminated the constants for MATCH_MATCH and MATCH_NOMATCH,
-        since they are just true and false (1 and 0).
-        (jsRegExpExecute): More of the MATCH_MATCH change.
-
-2007-12-17  Darin Adler  <darin@apple.com>
-
-        - speculative build fix for non-gcc platforms
-
-        * pcre/pcre_exec.cpp: (match): Remove unused cases from return switch.
-
-2007-12-16  Mark Rowe  <mrowe@apple.com>
-
-        Speculative build fix for non-Mac platforms.
-
-        * pcre/pcre_compile.cpp: Include string.h for memset, memmove, etc.
-
-2007-12-16  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=16438
-        - removed some more unused code
-        - changed quite a few more names to WebKit-style
-        - moved more things out of pcre_internal.h
-        - changed some indentation to WebKit-style
-        - improved design of the functions for reading and writing
-          2-byte values from the opcode stream (in pcre_internal.h)
-
-        * pcre/dftables.cpp:
-        (main): Added the kjs prefix a normal way in lieu of using macros.
-
-        * pcre/pcre_compile.cpp: Moved some definitions here from pcre_internal.h.
-        (errorText): Name changes, fewer typedefs.
-        (checkEscape): Ditto. Changed uppercase conversion to use toASCIIUpper.
-        (isCountedRepeat): Name change.
-        (readRepeatCounts): Name change.
-        (firstSignificantOpcode): Got rid of the use of OP_lengths, which is
-        very lightly used here. Hard-coded the length of OP_BRANUMBER.
-        (firstSignificantOpcodeSkippingAssertions): Ditto. Also changed to
-        use the advanceToEndOfBracket function.
-        (getOthercaseRange): Name changes.
-        (encodeUTF8): Ditto.
-        (compileBranch): Name changes. Removed unused after_manual_callout and
-        the code to handle it. Removed code to handle OP_ONCE since we never
-        emit this opcode. Changed to use advanceToEndOfBracket in more places.
-        (compileBracket): Name changes.
-        (branchIsAnchored): Removed code to handle OP_ONCE since we never emit
-        this opcode.
-        (bracketIsAnchored): Name changes.
-        (branchNeedsLineStart): More fo the same.
-        (bracketNeedsLineStart): Ditto.
-        (branchFindFirstAssertedCharacter): Removed OP_ONCE code.
-        (bracketFindFirstAssertedCharacter): More of the same.
-        (calculateCompiledPatternLengthAndFlags): Ditto.
-        (returnError): Name changes.
-        (jsRegExpCompile): Ditto.
-
-        * pcre/pcre_exec.cpp: Moved some definitions here from pcre_internal.h.
-        (matchRef): Updated names.
-        Improved macros to use the do { } while(0) idiom so they expand to single
-        statements rather than to blocks or multiple statements. And refeactored
-        the recursive match macros.
-        (MatchStack::pushNewFrame): Name changes.
-        (getUTF8CharAndIncrementLength): Name changes.
-        (match): Name changes. Removed the ONCE opcode.
-        (jsRegExpExecute): Name changes.
-
-        * pcre/pcre_internal.h: Removed quite a few unneeded includes. Rewrote
-        quite a few comments. Removed the macros that add kjs prefixes to the
-        functions with external linkage; instead renamed the functions. Removed
-        the unneeded typedefs pcre_uint16, pcre_uint32, and uschar. Removed the
-        dead and not-all-working code for LINK_SIZE values other than 2, although
-        we aim to keep the abstraction working. Removed the OP_LENGTHS macro.
-        (put2ByteValue): Replaces put2ByteOpcodeValueAtOffset.
-        (get2ByteValue): Replaces get2ByteOpcodeValueAtOffset.
-        (put2ByteValueAndAdvance): Replaces put2ByteOpcodeValueAtOffsetAndAdvance.
-        (putLinkValueAllowZero): Replaces putOpcodeValueAtOffset; doesn't do the
-        addition, since a comma is really no better than a plus sign. Added an
-        assertion to catch out of range values and changed the parameter type to
-        int rather than unsigned.
-        (getLinkValueAllowZero): Replaces getOpcodeValueAtOffset.
-        (putLinkValue): New function that most former callers of the
-        putOpcodeValueAtOffset function can use; asserts the value that is
-        being stored is non-zero and then calls putLinkValueAllowZero.
-        (getLinkValue): Ditto.
-        (putLinkValueAndAdvance): Replaces putOpcodeValueAtOffsetAndAdvance. No
-        caller was using an offset, which makes sense given the advancing behavior.
-        (putLinkValueAllowZeroAndAdvance): Ditto.
-        (isBracketOpcode): Added. For use in an assertion.
-        (advanceToEndOfBracket): Renamed from moveOpcodePtrPastAnyAlternateBranches,
-        and removed comments about how it's not well designed. This function takes
-        a pointer to the beginning of a bracket and advances to the end of the
-        bracket.
-
-        * pcre/pcre_tables.cpp: Updated names.
-        * pcre/pcre_ucp_searchfuncs.cpp:
-        (kjs_pcre_ucp_othercase): Ditto.
-        * pcre/pcre_xclass.cpp:
-        (getUTF8CharAndAdvancePointer): Ditto.
-        (kjs_pcre_xclass): Ditto.
-        * pcre/ucpinternal.h: Ditto.
-
-        * wtf/ASCIICType.h:
-        (WTF::isASCIIAlpha): Added an int overload, like the one we already have for
-        isASCIIDigit.
-        (WTF::isASCIIAlphanumeric): Ditto.
-        (WTF::isASCIIHexDigit): Ditto.
-        (WTF::isASCIILower): Ditto.
-        (WTF::isASCIISpace): Ditto.
-        (WTF::toASCIILower): Ditto.
-        (WTF::toASCIIUpper): Ditto.
-
-2007-12-16  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16459
-          REGRESSION: assertion failure with regexp with \B in a case-ignoring character range
-          <rdar://problem/5646361>
-
-        The problem was that \B was not handled properly in character classes.
-
-        Test: fast/js/regexp-overflow.html
-
-        * pcre/pcre_compile.cpp:
-        (check_escape): Added handling of ESC_b and ESC_B in character classes here.
-        Allows us to get rid of the handling of \b in character classes from all the
-        call sites that handle it separately and to handle \B properly as well.
-        (compileBranch): Remove the ESC_b handling, since it's not needed any more.
-        (calculateCompiledPatternLengthAndFlags): Ditto.
-
-2007-12-16  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=16448
-        Bug 16448: [GTK] Celtic Kane JavaScript performance on Array test is slow relative to Mac
-
-        * kjs/array_instance.cpp:
-        (KJS::compareByStringPairForQSort):
-        (KJS::ArrayInstance::sort): Convert JSValue's to strings once up front and then sort the
-        results.  This avoids calling toString twice per comparison, but requires a temporary buffer
-        so we only use this approach in cases where the array being sorted is not too large.
-
-2007-12-16  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler and Maciej Stachowiak.
-        
-        More refactoring to support global variable optimization.
-        
-        Changed SymbolTable to use RefPtr<UString::Rep> as its key instead of
-        UString::Rep*. With globals, the symbol table can outlast the
-        declaration node for any given symbol, so the symbol table needs to ref
-        its symbol names.
-        
-        In support, specialized HashMaps with RefPtr keys to allow lookup
-        via raw pointer, avoiding refcount churn.
-        
-        SunSpider reports a .6% speedup (prolly just noise).
-
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj: Added new file: wtf/RefPtrHashMap.h
-        * JavaScriptCore.xcodeproj/project.pbxproj: ditto
-
-        * kjs/JSVariableObject.cpp:
-        (KJS::JSVariableObject::getPropertyNames): Symbol table keys are RefPtrs now.
-
-        * kjs/SymbolTable.h: Modified key traits to match RefPtr. Added a
-        static Rep* for null, which helps compute the deletedValue() trait.
-
-        * wtf/HashMap.h: #include the RefPtr specialization so everyone can use it.
-
-        * wtf/RefPtrHashMap.h: Copied from wtf/HashMap.h. Added overloaded versions
-        of find(), contains(), get(), set(), add(), remove(), and take() that take
-        raw pointers as keys.
-
-2007-12-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16162
-        Problems with float parsing on Linux (locale-dependent parsing was used).
-
-        * kjs/dtoa.cpp: Removed USE_LOCALE to reduce future confusion.
-        * kjs/lexer.cpp: (KJS::Lexer::lex): Parse with kjs_strtod, not the system one.
-
-2007-12-14  Alp Toker  <alp@atoker.com>
-
-        Reviewed by Mark Rowe.
-
-        Enable the AllInOneFile.cpp optimization for the GTK+ port.
-
-        * JavaScriptCore.pri:
-
-2007-12-14  Mark Rowe  <mrowe@apple.com>
-
-        Unreviewed.  Remove commented out fprintf's that were for debugging purposes only.
-
-        * wtf/FastMalloc.cpp:
-        (WTF::TCMalloc_PageHeap::IncrementalScavenge):
-
-2007-12-14  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Don't use the MADV_DONTNEED code path for now as it has no effect on Mac OS X and is
-        currently untested on other platforms.
-
-        * wtf/TCSystemAlloc.cpp:
-        (TCMalloc_SystemRelease): Return after releasing memory rather than potentially falling
-        through into another mechanism if multiple are supported.
-
-2007-12-14  Alp Toker  <alp@atoker.com>
-
-        Build fix for GTK+/Qt and ports that don't use AllInOneFile.cpp.
-
-        Include UnusedParam.h.
-
-        * wtf/TCSystemAlloc.cpp:
-
-2007-12-14  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Stephanie.
-
-        Fix build on windows
-
-        * wtf/FastMalloc.cpp:
-        (WTF::TCMalloc_PageHeap::IncrementalScavenge):
-
-2007-12-14  Dan Bernstein  <mitz@apple.com>
-
-        - try again to fix the Windows build
-
-        * wtf/TCSystemAlloc.cpp:
-        (TCMalloc_SystemRelease):
-
-2007-12-14  Dan Bernstein  <mitz@apple.com>
-
-        - try to fix the Windows build
-
-        * wtf/TCSystemAlloc.cpp:
-        (TCMalloc_SystemRelease):
-
-2007-12-14  Mark Rowe <mrowe@apple.com>
-
-        Reviewed by Maciej and Oliver.
-
-        Add final changes to make TCMalloc release memory to the system.
-        This results in a 0.4% regression against ToT, but this is offset
-        against the gains made by the original TCMalloc r38 merge - in fact
-        we retain around 0.3-0.4% progression overall.
-
-        * wtf/FastMalloc.cpp:
-        (WTF::InitSizeClasses):
-        (WTF::TCMalloc_PageHeap::IncrementalScavenge):
-        * wtf/TCSystemAlloc.cpp:
-        (TCMalloc_SystemRelease):
-
-2007-12-14  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        - removed unnecessary includes of "Vector.h"
-
-        * wtf/HashMap.h:
-        (WTF::copyKeysToVector): Make the type of the vector be a template parameter.
-        This allows copying keys into a vector of a base class or one with an inline capacity.
-        (WTF::copyValuesToVector): Ditto.
-        * wtf/HashSet.h:
-        (WTF::copyToVector): Ditto.
-
-2007-12-14  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Darin and Geoff.
-
-        <rdar://problem/5619295> 
-        REGRESSION: 303-304: Embedded YouTube video fails to render- JS errors (16150) (Flash 9)
-        
-        Get rid of unnecessary and incorrect security checks for plug-ins accessing JavaScript objects. 
-        
-        The way this used to work was that each NPObject that wrapped a JSObject would have a root object
-        corresponding to the frame object (used for managing the lifecycle) and an origin root object (used for
-        doing security checks). 
-        
-        This would prevent a plug-in from accessing a frame's window object if it's security origin was different
-        (some parts of the window, such as the location object, can be accessed from frames with different security 
-        origins, and those checks are being done in WebCore).
-        
-        Also, if a plug-in were to access a window object of a frame that later went away, it could lead to that
-        Window JSObject being garbage collected and the NPObject pointing to freed memory.
-        
-        How this works now is that there is no origin root object anymore, and all NPObject wrappers that are created
-        for a plug-in will have the root object of the containing frame of that plug-in.
-        
-        * bindings/NP_jsobject.cpp:
-        (jsDeallocate):
-        Don't free the origin root object.
-        
-        (_NPN_CreateScriptObject):
-        Remove the origin root object parameter.
-        
-        (_NPN_InvokeDefault):
-        (_NPN_Invoke):
-        (_NPN_Evaluate):
-        (_NPN_GetProperty):
-        (_NPN_SetProperty):
-        (_NPN_RemoveProperty):
-        (_NPN_HasProperty):
-        (_NPN_HasMethod):
-        (_NPN_Enumerate):
-        Get rid of all security checks.
-        
-        * bindings/NP_jsobject.h:
-        Remove originRootObject from the JavaScriptObject struct.
-        
-        * bindings/c/c_utility.cpp:
-        (KJS::Bindings::convertValueToNPVariant):
-        Always use the root object from the ExecState.
-        
-2007-12-13  Steve Falkenburg  <sfalken@apple.com>
-
-        Move source file generation into its own vcproj to fix build dependencies.
-
-        Reviewed by Adam.
-
-        * JavaScriptCore.vcproj/JavaScriptCore.sln:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make: Added.
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.vcproj: Added.
-        * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln:
-
-2007-12-13  Alp Toker  <alp@atoker.com>
-
-        http://bugs.webkit.org/show_bug.cgi?id=16406
-        [Gtk] JavaScriptCore needs -lpthread
-
-        Build fix for Debian and any other platforms that don't implicitly
-        link to pthread.
-
-        Link to pthread on non-Windows platforms until this dependency is
-        removed from JSC.
-
-2007-12-11  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Build fix: Note some variables that are used only for ASSERTs.
-
-        * API/testapi.c:
-        (Base_finalize):
-        (globalObject_initialize):
-        (testInitializeFinalize):
-
-2007-12-11  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Fixed: All JS tests crash on Windows.
-
-        NDEBUG wasn't defined when compiling testkjs in release builds, so the
-        HashTable definition in HashTable.h included an extra data member.
-
-        The solution was to add NDEBUG to the release testkjs configuration on
-        Windows and Mac.
-        
-        For giggles, I also added other missing #defines to testkjs on Windows.
-
-        * Configurations/Base.xcconfig:
-        * Configurations/JavaScriptCore.xcconfig:
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/testkjs.cpp:
-        (main):
-
-2007-12-11  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Removed bogus ASSERT.
-        
-        ASSERT should only be used when we know that a code path will not be
-        taken. This code path is taken often during the jsFunFuzz test.
-
-        * pcre/pcre_exec.cpp:
-        (jsRegExpExecute):
-
-2007-12-11  Darin Adler  <darin@apple.com>
-
-        * wtf/unicode/qt4/UnicodeQt4.h: Try to fix Qt build by adding U16_IS_SINGLE.
-
-2007-12-10  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16379
-          REGRESSION(r28525): Failures in http/tests/xmlhttprequest/response-encoding.html and
-          fast/dom/xmlhttprequest-html-response-encoding.html
-          and <rdar://problem/5640230> REGRESSION (306A4-ToT): Access violation in PCRE function
-          find_firstassertedchar
-
-        Test: fast/js/regexp-find-first-asserted.html
-
-        * pcre/pcre_compile.cpp:
-        (compileBracket): Take out unnecessary initialization of out parameters.
-        (branchFindFirstAssertedCharacter): Added. Broke out the half of the function that handles
-        a branch.
-        (bracketFindFirstAssertedCharacter): Renamed from find_firstassertedchar. Also removed the
-        options parameter -- the caller can handle the options.
-        (jsRegExpCompile): Changed call site to call the appropriate bracket or branch version of
-        the find_firstassertedchar function. Also put the REQ_IGNORE_CASE code here instead of
-        passing in the options.
-
-2007-12-10  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Split this:
-        
-                            FunctionBodyNode
-                                    ^
-                                    |
-                                ProgramNode
-            
-        into this:
-            
-                                ScopeNode
-                ^                   ^                   ^
-                |                   |                   |
-        FunctionBodyNode        ProgramNode         EvalNode
-
-        in preparation for specializing each class more while optimizing global
-        variable access.
-        
-        Also removed some cruft from the FunctionBodyNode interface to simplify
-        things.
-        
-        SunSpider says this patch is a .8% speedup, which seems reasonable,
-        since it eliminates a few branches and adds KJS_FAST_CALL in a few
-        places.
-        
-        Layout tests and JS tests pass. Also, this baby builds on Windows! (Qt
-        mileage may vary...)
-
-2007-12-10  Geoffrey Garen  <ggaren@apple.com>
-
-        RS by Mark Rowe.
-        
-        Mac build fix: added some exported symbols, now that Parser::parse is
-        defined in the header.
-
-        * JavaScriptCore.exp:
-
-2007-12-10  Sam Weinig  <sam@webkit.org>
-
-        Build fix.
-
-        Template methods need to be in the header.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * kjs/Parser.cpp:
-        * kjs/Parser.h:
-        (KJS::Parser::parse):
-
-2007-12-10  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Merged different implementations of Parser::parse into a single,
-        templatized implementation, in preparation for adding yet another
-        implementation for "eval" code.
-        
-        JS and layout tests pass.
-
-2007-12-10  Timothy Hatcher  <timothy@apple.com>
-
-        Reviewed by Mark Rowe
-
-        <rdar://problem/5639463> Bundle versions on Tiger should be 4523.x not 523.x
-
-        * Configurations/Version.xcconfig: Some Tiger versions of Xcode don't set MAC_OS_X_VERSION_MAJOR,
-          so assume Tiger and use a 4 for the SYSTEM_VERSION_PREFIX.
-
-2007-12-10  Mark Rowe  <mrowe@apple.com>
-
-        Tiger build fix.
-
-        * kjs/grammar.y: Use @1 and @0 in place of @$ where Tiger's bison chokes.
-
-2007-12-10  Darin Adler  <darin@apple.com>
-
-        Reviewed by Mark Rowe.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16375
-          REGRESSION: Safari crashes on quit
-
-        Probably a debug-only issue.
-
-        * kjs/Parser.cpp:
-        (KJS::parser): Create the parser and never destroy it by using a pointer instead
-        of a global object.
-
-2007-12-09  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16369
-          REGRESSION (r28525): regular expression tests failing due to bad firstByte optimization
-
-        * pcre/pcre_compile.cpp: Changed some names to use interCaps intead of under_scores.
-        (branchIsAnchored): Broke is_anchored into two separate functions; this one works on a
-        branch and the other on an anchor. The old function would only work on a bracket.
-        Also removed unneeded parameters; the anchored check does not require the bracket
-        map or the options any more because we have a reduced set of features.
-        (bracketIsAnchored): Ditto.
-        (branchNeedsLineStart): Broke canApplyFirstCharOptimization into two functions and gave
-        both a better name. This is the function that was returning the wrong value. The failure
-        was beacuse the old function would only work on a bracket.
-        (bracketNeedsLineStart): Ditto.
-        (jsRegExpCompile): Changed to call the appropriate branch or bracket flavor of the
-        functions based on whether we compiled an outer bracket. Also removed inaccurate comments
-        and unneeded parameters.
-
-        - other small changes
-
-        * pcre/pcre.h: Renumbered error codes, in a logical order. First, normal failure, then
-        the recursion limit, then running out of memory, and finally an unexpected internal error.
-
-        * pcre/pcre_exec.cpp: Fixed indentation.
-        (jsRegExpExecute): Corrected an inaccurate comment.
-
-2007-12-09  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16370
-          REGRESSION (r28540): source URL and line number no longer set for outer function/programs
-
-        Test: fast/js/exception-linenums-in-html-1.html
-        Test: fast/js/exception-linenums-in-html-2.html
-        Test: fast/js/exception-linenums.html
-
-        By the time the ProgramNode was constructed, the source URL was empty.
-
-        * kjs/Parser.cpp:
-        (KJS::Parser::parseProgram): Added code to set and clear m_sourceURL, which is now
-        handled here instead of in the lexer; it needs to still be set when we create the
-        program node. Call setLoc to set the first and last line number.
-        (KJS::Parser::parseFunctionBody): Ditto, but for the body.
-        (KJS::Parser::parse): Removed the sourceURL argument.
-
-        * kjs/Parser.h: Added sourceURL(), m_sourceURL, and m_lastLine. Added a lastLine
-        parameter to didFinishParsing, since the bison grammar knows the last line number
-        and we otherwise do not know it. Removed the sourceURL parameter from parse, since
-        that's now handled at a higher level.
-
-        * kjs/grammar.y: Pass the last line number to didFinishParsing.
-
-        * kjs/lexer.cpp:
-        (KJS::Lexer::setCode): Removed the sourceURL argument and the code to set m_sourceURL.
-        (KJS::Lexer::clear): Ditto.
-        * kjs/lexer.h: More of the same.
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionBodyNode::FunctionBodyNode): Get the source URL from the parser rather
-        than from the lexer. Removed unneeded call to setLoc, since the line numbers already
-        both default to -1.
-
-2007-12-08  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Sam W.
-
-        Split the ENABLE_SVG_EXPERIMENTAL_FEATURES flag into separate flags.
-        
-        Fixes <rdar://problem/5620249> Must disable SVG animation
-        <rdar://problem/5612772> Disable SVG filters on Mac to match Windows behavior
-        
-        Minor config changes.
-
-        * Configurations/JavaScriptCore.xcconfig:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2007-12-07  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Darin.
-
-        - Rename isSafeScript to allowsAccessFrom.
-
-        * bindings/NP_jsobject.cpp:
-        (_isSafeScript):
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::allowsAccessFrom): Reverse caller/argument of allowsAccessFrom to match
-        the new call.
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Refactored variable access optimization: Removed the assumption that
-        the FunctionBodyNode holds the symbol table.
-        
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added #include.
-
-        * kjs/nodes.cpp:
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added #include.
-
-        * kjs/interpreter.cpp:
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added #include.
-
-        * kjs/grammar.y:
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added #include.
-
-        * kjs/function_object.cpp:
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Fixed crash seen running layout tests.
-        
-        Reverted a change I made earlier today. Added a comment to try to
-        discourage myself from making this mistake a third time.
-
-        * kjs/function.cpp:
-        (KJS::ActivationImp::mark):
-        * kjs/function.h:
-        (KJS::ActivationImp::ActivationImpData::ActivationImpData):
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Refactored parsing of global code: Removed the assumption that 
-        ProgramNode inherits from FunctionBodyNode from the parser.
-
-        * kjs/Parser.cpp:
-        (KJS::Parser::parseProgram):
-        (KJS::Parser::parseFunctionBody):
-        (KJS::Parser::parse):
-        * kjs/Parser.h:
-        (KJS::Parser::didFinishParsing):
-        * kjs/function.cpp:
-        * kjs/grammar.y:
-        * kjs/nodes.h:
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added JSVariableObject.cpp to the .pri file.
-
-        * JavaScriptCore.pri:
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added #include.
-
-        * kjs/function.cpp:
-
-2007-12-07  Steve Falkenburg  <sfalken@apple.com>
-
-        Re-named our B&I flag from BUILDBOT to PRODUCTION.
-
-        Reviewed by Sam Weinig.
-
-        * JavaScriptCore.vcproj/JavaScriptCore.make:
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj:
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: removed stray name qualification.
-
-        * kjs/function.h:
-        (KJS::ActivationImp::ActivationImp):
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: moved functions with qualified names outside of class
-        declaration.
-
-        * kjs/JSVariableObject.h:
-        (KJS::JSVariableObject::symbolTableGet):
-        (KJS::JSVariableObject::symbolTablePut):
-
-2007-12-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Next step in refactoring JSGlobalObject: Added JSVariableObject class,
-        and factored symbol-table-related code into it. (JSGlobalObject doesn't
-        use the symbol table code yet, though.)
-        
-        Layout and JS tests, and testapi, pass. SunSpider reports no regression.
-
-2007-12-07  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16185
-          jsRegExpCompile should not add implicit non-capturing bracket
-
-        While this does not make SunSpider faster, it will make many regular
-        expressions a bit faster.
-
-        * pcre/pcre_compile.cpp: Moved CompileData struct in here from the
-        header since it's private to this file.
-        (compile_branch): Updated for function name change.
-        (compile_bracket): Renamed from compile_regex, since, for one thing,
-        this does not compile an entire regular expression.
-        (calculateCompiledPatternLengthAndFlags): Removed unused item_count
-        local variable. Renamed CompileData to cd instead of compile_block
-        to be consistent with other functions. Added code to set the
-        needOuterBracket flag if there's at least one "|" at the outer level.
-        (jsRegExpCompile): Renamed CompileData to cd instead of compile_block
-        to be consistent with other functions. Removed unneeded "size" field
-        from the compiled regular expression. If no outer bracket is needed,
-        then use compile_branch to compile the regular expression.
-
-        * pcre/pcre_internal.h: Removed the CompileData struct, which is now
-        private to pcre_compile.cpp. Removed the size member from JSRegExp.
-
-2007-12-06  Kevin Ollivier  <kevino@theolliviers.com>
-
-        MSVC7 build fix due to a compiler bug with placement new and/or
-        templates and casting.
-
-        Reviewed by Darin Adler.
-
-        * wtf/Vector.h:
-        (WTF::::append):
-
-2007-12-06  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric Seidel.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16321
-          new RegExp("[\u0097]{4,6}", "gmy") crashes in DEBUG builds
-          <rdar://problem/5632992>
-
-        Test: fast/js/regexp-oveflow.html
-
-        * pcre/pcre_compile.cpp:
-        (calculateCompiledPatternLengthAndFlags): In the case where a single character
-        character class is optimized to not use a character class at all, the preflight
-        code was not setting the lastitemlength variable.
-
-2007-12-05  Mark Rowe  <mrowe@apple.com>
-
-        Qt Windows build fix.  Include the time-related headers in the correct place.
-
-        * kjs/JSGlobalObject.cpp:
-        * kjs/interpreter.cpp:
-
-2007-12-05  Darin Adler  <darin@apple.com>
-
-        Not reviewed; just undoing a previous commit.
-
-        - remove earlier incorrect fix for http://bugs.webkit.org/show_bug.cgi?id=16220
-          <rdar://problem/5625221> Crash opening www.news.com (CNet)
-
-        The real bug was the backwards ?: in the compile function, which Geoff just
-        fixed. Rolling out the incorrect earlier fix.
-
-        * pcre/pcre_compile.cpp: (calculateCompiledPatternLengthAndFlags): Take out
-        the unneeded preflight change. The regression test proves this is still working
-        fine, so the bug remains fixed.
-
-2007-12-01  Mark Rowe  <mrowe@apple.com>
-
-        Build fix.  Include headers before trying to use the things that they declare.
-
-        * kjs/JSImmediate.cpp:
-        * kjs/nodes.cpp:
-        * kjs/object.cpp:
-        * kjs/object_object.cpp:
-        * kjs/regexp_object.cpp:
-        * kjs/string_object.cpp:
-
-2007-12-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added some #includes.
-
-        * kjs/JSImmediate.cpp:
-
-2007-12-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added some #includes.
-
-        * kjs/JSGlobalObject.cpp:
-        * kjs/JSImmediate.cpp:
-
-2007-12-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: Fixed #include spelling.
-
-        * kjs/debugger.cpp:
-
-2007-12-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added #include.
-
-        * kjs/debugger.cpp:
-
-2007-12-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added a forward declaration.
-
-        * kjs/debugger.h:
-
-2007-12-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added an #include.
-
-        * kjs/error_object.cpp:
-
-2007-12-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added an #include.
-
-        * kjs/bool_object.cpp:
-
-2007-12-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-
-        Third step in refactoring JSGlobalObject: Moved data members and 
-        functions accessing data members from Interpreter to JSGlobalObject.
-        Changed Interpreter member functions to static functions.
-        
-        This resolves a bug in global object bootstrapping, where the global
-        ExecState could be used when uninitialized.
-        
-        This is a big change, but it's mostly code motion and renaming.
-        
-        Layout and JS tests, and testjsglue and testapi, pass. SunSpider reports
-        a .7% regression, but Shark sees no difference related to this patch,
-        and SunSpider reported a .7% speedup from an earlier step in this 
-        refactoring, so I think it's fair to call that a wash.
-
-2007-12-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler. (Or vice versa.)
-        
-        Fixed ASSERT during run-javascriptcore-tests. (Darin just added the
-        ASSERT, but the bug wasn't new.)
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch): The ?: operator here was backwards, causing us to
-        execute the loop too many times, adding stray KET opcodes to the
-        compiled regular expression.
-
-2007-12-05  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Geoff.
-
-        - Wait until local variable data is fully constructed before notifying the debugger of entering
-        or leaving a call frame.
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-        * kjs/nodes.cpp:
-        (KJS::FunctionBodyNode::execute):
-
-2007-12-05  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Oliver.
-
-        Build fix for GCC 4.2. Cast via a union to avoid strict-aliasing issues.
-
-        * wtf/FastMalloc.cpp:
-        (WTF::):
-        (WTF::getPageHeap):
-
-2007-12-05  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Darin.
-
-        Fix testkjs in 64-bit.
-
-        When built for 64-bit the TCMalloc spin lock uses pthread mutexes rather than a custom spin lock
-        implemented in assembly.  If we fail to initialize the pthread mutex, attempts to lock or unlock
-        it will fail and trigger a call to abort.
-
-        * wtf/FastMalloc.cpp: Initialize the spin lock so that we can later lock and unlock it.
-        * wtf/TCSpinLock.h: Add an Init method to the optimised spin lock.
-
-2007-12-04  Oliver Hunt  <oliver@apple.com>
-
-        Fix gtk build.
-
-        * wtf/TCSystemAlloc.cpp:
-
-2007-12-03  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Mark Rowe and Geoff Garen.
-
-        Merge TCMalloc r38
-
-        It also result in a performance progression between 0.5% and 
-        0.9% depending on the test, however most if not all of this 
-        gain will be consumed by the overhead involved in the later
-        change to release memory to the system.
-
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * wtf/FastMalloc.cpp:
-        (WTF::KernelSupportsTLS):
-        (WTF::CheckIfKernelSupportsTLS):
-        (WTF::):
-        (WTF::ClassIndex):
-        (WTF::SLL_Next):
-        (WTF::SLL_SetNext):
-        (WTF::SLL_Push):
-        (WTF::SLL_Pop):
-        (WTF::SLL_PopRange):
-        (WTF::SLL_PushRange):
-        (WTF::SLL_Size):
-        (WTF::SizeClass):
-        (WTF::ByteSizeForClass):
-        (WTF::NumMoveSize):
-        (WTF::InitSizeClasses):
-        (WTF::AllocationSize):
-        (WTF::TCMalloc_PageHeap::GetSizeClassIfCached):
-        (WTF::TCMalloc_PageHeap::CacheSizeClass):
-        (WTF::TCMalloc_PageHeap::init):
-        (WTF::TCMalloc_PageHeap::New):
-        (WTF::TCMalloc_PageHeap::AllocLarge):
-        (WTF::TCMalloc_PageHeap::Carve):
-        (WTF::TCMalloc_PageHeap::Delete):
-        (WTF::TCMalloc_PageHeap::IncrementalScavenge):
-        (WTF::PagesToMB):
-        (WTF::TCMalloc_PageHeap::Dump):
-        (WTF::TCMalloc_PageHeap::GrowHeap):
-        (WTF::TCMalloc_PageHeap::Check):
-        (WTF::ReleaseFreeList):
-        (WTF::TCMalloc_PageHeap::ReleaseFreePages):
-        (WTF::TCMalloc_ThreadCache_FreeList::Push):
-        (WTF::TCMalloc_ThreadCache_FreeList::PushRange):
-        (WTF::TCMalloc_ThreadCache_FreeList::PopRange):
-        (WTF::TCMalloc_ThreadCache_FreeList::Pop):
-        (WTF::TCMalloc_Central_FreeList::length):
-        (WTF::TCMalloc_Central_FreeList::tc_length):
-        (WTF::TCMalloc_Central_FreeList::Init):
-        (WTF::TCMalloc_Central_FreeList::ReleaseListToSpans):
-        (WTF::TCMalloc_Central_FreeList::EvictRandomSizeClass):
-        (WTF::TCMalloc_Central_FreeList::MakeCacheSpace):
-        (WTF::TCMalloc_Central_FreeList::ShrinkCache):
-        (WTF::TCMalloc_Central_FreeList::InsertRange):
-        (WTF::TCMalloc_Central_FreeList::RemoveRange):
-        (WTF::TCMalloc_Central_FreeList::FetchFromSpansSafe):
-        (WTF::TCMalloc_Central_FreeList::Populate):
-        (WTF::TCMalloc_ThreadCache::Init):
-        (WTF::TCMalloc_ThreadCache::Cleanup):
-        (WTF::TCMalloc_ThreadCache::Allocate):
-        (WTF::TCMalloc_ThreadCache::Deallocate):
-        (WTF::TCMalloc_ThreadCache::FetchFromCentralCache):
-        (WTF::TCMalloc_ThreadCache::ReleaseToCentralCache):
-        (WTF::TCMalloc_ThreadCache::Scavenge):
-        (WTF::TCMalloc_ThreadCache::PickNextSample):
-        (WTF::TCMalloc_ThreadCache::NewHeap):
-        (WTF::TCMalloc_ThreadCache::GetThreadHeap):
-        (WTF::TCMalloc_ThreadCache::GetCache):
-        (WTF::TCMalloc_ThreadCache::GetCacheIfPresent):
-        (WTF::TCMalloc_ThreadCache::InitTSD):
-        (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
-        (WTF::TCMallocStats::ExtractStats):
-        (WTF::TCMallocStats::DumpStats):
-        (WTF::TCMallocStats::DumpStackTraces):
-        (WTF::TCMallocStats::TCMallocImplementation::MarkThreadIdle):
-        (WTF::TCMallocStats::TCMallocImplementation::ReleaseFreeMemory):
-        (WTF::TCMallocStats::TCMallocGuard::TCMallocGuard):
-        (WTF::TCMallocStats::TCMallocGuard::~TCMallocGuard):
-        (WTF::TCMallocStats::DoSampledAllocation):
-        (WTF::TCMallocStats::CheckCachedSizeClass):
-        (WTF::TCMallocStats::CheckedMallocResult):
-        (WTF::TCMallocStats::SpanToMallocResult):
-        (WTF::TCMallocStats::do_malloc):
-        (WTF::TCMallocStats::do_free):
-        (WTF::TCMallocStats::do_memalign):
-        (WTF::TCMallocStats::do_malloc_stats):
-        (WTF::TCMallocStats::do_mallopt):
-        (WTF::TCMallocStats::do_mallinfo):
-        (WTF::TCMallocStats::realloc):
-        (WTF::TCMallocStats::cpp_alloc):
-        (WTF::TCMallocStats::operator new):
-        (WTF::TCMallocStats::):
-        (WTF::TCMallocStats::operator new[]):
-        (WTF::TCMallocStats::malloc_stats):
-        (WTF::TCMallocStats::mallopt):
-        (WTF::TCMallocStats::mallinfo):
-        * wtf/TCPackedCache.h: Added.
-        (PackedCache::PackedCache):
-        (PackedCache::Put):
-        (PackedCache::Has):
-        (PackedCache::GetOrDefault):
-        (PackedCache::Clear):
-        (PackedCache::EntryToValue):
-        (PackedCache::EntryToUpper):
-        (PackedCache::KeyToUpper):
-        (PackedCache::UpperToPartialKey):
-        (PackedCache::Hash):
-        (PackedCache::KeyMatch):
-        * wtf/TCPageMap.h:
-        (TCMalloc_PageMap2::PreallocateMoreMemory):
-        * wtf/TCSystemAlloc.cpp:
-        (TCMalloc_SystemRelease):
-        * wtf/TCSystemAlloc.h:
-
-2007-12-04  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Sam.
-
-        Make isSafeScript const.
-        
-        * kjs/JSGlobalObject.h:
-        (KJS::JSGlobalObject::isSafeScript):
-
-2007-12-04  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix first part of http://bugs.webkit.org/show_bug.cgi?id=16220
-          <rdar://problem/5625221> Crash opening www.news.com (CNet)
-
-        Test: fast/js/regexp-overflow.html
-
-        * pcre/pcre_compile.cpp:
-        (calculateCompiledPatternLengthAndFlags): Add room for the additional BRA/KET that
-        was generated in the compile code but not taken into account here.
-
-2007-12-03  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15618
-          <rdar://problem/5619353> REGRESSION: Stack overflow/crash in KJS::equal (15618)
-
-        Test: fast/js/recursion-limit-equal.html
-
-        * kjs/operations.cpp: (KJS::equal): Check the exception from toPrimitive.
-
-2007-12-03  Dan Bernstein  <mitz@apple.com>
-
-        - fix a copy-and-paste-o
-
-        * bindings/npruntime.cpp:
-        (_NPN_GetIntIdentifier):
-
-2007-12-03  Dan Bernstein  <mitz@apple.com>
-
-        Reviewed by Darin Adler.
-
-        - fix an ASSERT when getIntIdentifier is called with 0 or -1
-
-        * bindings/npruntime.cpp:
-        (_NPN_GetIntIdentifier): We cannot use the hashmap for 0 and -1 since
-        they are the empty value and the deleted value. Instead, keep the
-        identifiers for those two integers in a static array.
-
-2007-12-02  Darin Adler  <darin@apple.com>
-
-        Reviewed by Mitz.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15848
-          <rdar://problem/5619330> REGRESSION: Assertion failure viewing comments page on digg.com
-
-        Test: fast/js/sparse-array.html
-
-        * kjs/array_instance.cpp:
-        (KJS::ArrayInstance::inlineGetOwnPropertySlot): Check sparse array cutoff before looking
-        in hash map. Can't avoid the branch because we can't look for 0 in the hash.
-        (KJS::ArrayInstance::deleteProperty): Ditto.
-
-2007-12-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: added an #include.
-
-        * kjs/collector.cpp:
-
-2007-12-02  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Eric Seidel.
-
-        Second step in refactoring JSGlobalObject: moved virtual functions from
-        Interpreter to JSGlobalObject.
-        
-        Layout and JS tests pass. SunSpider reports a .7% speedup -- don't 
-        believe his lies.
-
-2007-12-01  Alp Toker  <alp@atoker.com>
-
-        Reviewed by Adam Roben.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16228
-        kJSClassDefinitionEmpty is not exported with JS_EXPORT
-
-        Add JS_EXPORT to kJSClassDefinitionEmpty.
-
-        Make the gcc compiler check take precedence over the WIN32||_WIN32
-        check to ensure that symbols are exported on Windows when using gcc.
-
-        Add a TODO referencing the bug about JS_EXPORT in the Win build
-        (http://bugs.webkit.org/show_bug.cgi?id=16227)
-
-        Don't define JS_EXPORT as 'extern' when the compiler is unknown since
-        it would result in the incorrect expansion:
-
-          extern extern const JSClassDefinition kJSClassDefinitionEmpty;
-
-        (This was something we inherited from CFBase.h that doesn't make sense
-        for JSBase.h)
-
-        * API/JSBase.h:
-        * API/JSObjectRef.h:
-
-2007-11-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Beth Dakin.
-        
-        Reversed the ownership relationship between Interpreter and JSGlobalObject.
-        Now, the JSGlobalObject owns the Interpreter, and top-level objects
-        that need the two to persist just protect the JSGlobalObject from GC.
-        
-        Global object bootstrapping looks a little odd right now, but it will
-        make much more sense soon, after further rounds of refactoring.
-
-        * bindings/runtime_root.h: Made this class inherit from RefCounted,
-        to avoid code duplication.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::collect): No need to give special GC treatment to 
-        Interpreters, since we mark their global objects, which mark them.
-
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::mark): No need to mark our global object, since it
-        marks us.
-        * kjs/interpreter.h: Don't inherit from RefCounted -- JSGlobalObject 
-        owns us directly.
-
-        * kjs/testkjs.cpp: Modified to follow the new rules.
-        (createGlobalObject):
-        (runWithScripts):
-
-2007-11-30  Brent Fulgham  <bfulgham@gmail.com>
-
-        Reviewed by Eric.
-
-        * ChangeLog:
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-
-2007-11-30  Eric Seidel  <eric@webkit.org>
-
-        No review, build fix only.
-        
-        Fix uninitialized var warnings in release build.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * pcre/pcre_compile.cpp:
-        (compile_regex):
-
-2007-11-30  Darin Adler  <darin@apple.com>
-
-        Reviewed by Adam Roben.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16207
-          JavaScript regular expressions should match UTF-16 code units rather than characters
-
-        SunSpider says this is 5.5% faster on the regexp test, 0.4% faste overall.
-
-        Test: fast/js/regexp-non-bmp.html
-
-        Renamed ANY_CHAR to NOT_NEWLINE to more-accurately reflect its meaning.
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch): Removed calls to the UTF-16 character accessor functions, replacing
-        them with simple pointer dereferences in some cases, and no code at all in others.
-        (calculateCompiledPatternLengthAndFlags): Ditto.
-
-        * pcre/pcre_exec.cpp:
-        (match): Fixed indentation of some case labels (including all the BEGIN_OPCODE).
-        Removed calls to the UTF-16 character accessor functions, replacing them with simple
-        pointer dereferences in some cases, and no code at all in others. Also removed some
-        explicit UTF-16 support code in a few cases. Removed the unneeded "UTF-8" code path
-        in the ANY_CHAR repeat code, and in another case, eliminated the code to check against
-        end_subject in because it is already done outside the loop.
-        (jsRegExpExecute):
-
-        * pcre/pcre_internal.h: Removed all the UTF-16 helper functions.
-
-2007-11-30  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-        
-        PCRE crashes under GuardMalloc
-        http://bugs.webkit.org/show_bug.cgi?id=16127
-        check against patternEnd to make sure we don't walk off the end of the string
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (calculateCompiledPatternLengthAndFlags):
-
-2007-11-30  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-        
-        Fix layout test regressions caused by r28186
-        http://bugs.webkit.org/show_bug.cgi?id=16195
-        change first_byte and req_byte back to shorts instead of chars
-        (I think PCRE stuffs information in the high bits) 
-
-        * pcre/pcre_internal.h:
-
-2007-11-29  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej and Darin.
-
-        Make the JS collector work with multiple threads 
-
-        Under heavy contention it was possible the GC to suspend other
-        threads inside the pthread spinlock, which could lead to the GC
-        thread blocking on the pthread spinlock itself.
-
-        We now determine and store each thread's stack base when it is
-        registered, thus removing the need for any calls to pthread_get_stackaddr_np
-        that needed the pthread spinlock.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::Thread::Thread):
-        (KJS::Collector::registerThread):
-        (KJS::Collector::markOtherThreadConservatively):
-
-2007-11-29  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        Removed some unreachable code (ironically, the code was some
-        ASSERT_NOT_REACHED()s).
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        * pcre/pcre_exec.cpp:
-        (match):
-
-2007-11-29  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Mark Rowe.
-        
-        Fix for --guard crash of fast/js/regexp-charclass-crash introduced by r28151.
-
-        * pcre/pcre_compile.cpp:
-        (is_anchored):
-
-2007-11-28  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.  Rubber-stamped by Eric.
-
-        * pcre/pcre_exec.cpp:
-        (match): Add braces around the body of the case statement to prevent
-        wanings about jumps across the initialization of a variable.
-
-2007-11-29  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Mark Rowe.
-        
-        Attempt to fix non-mac builds after PCRE cleanup.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCoreSources.bkl:
-        * pcre/pcre.pri:
-
-2007-11-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Centralize code for subjectPtr adjustments using inlines, only ever check for a single
-        trailing surrogate (as UTF16 only allows one), possibly fix PCRE bugs involving char
-        classes and garbled UTF16 strings.
-
-        * pcre/pcre_exec.cpp:
-        (match):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-        (getPreviousChar):
-        (movePtrToPreviousChar):
-        (movePtrToNextChar):
-        (movePtrToStartOfCurrentChar):
-
-2007-11-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        change getChar* functions to return result and push 'c' into local scopes for clarity
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (calculateCompiledPatternLengthAndFlags):
-        * pcre/pcre_exec.cpp:
-        (match):
-        * pcre/pcre_internal.h:
-        (getChar):
-        (getCharAndAdvance):
-        (getCharAndLength):
-        (getCharAndAdvanceIfSurrogate):
-
-2007-11-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Comment cleanup
-
-        * pcre/pcre_exec.cpp:
-        (match):
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Further cleanups to calculateCompiledPatternLengthAndFlags
-
-        * pcre/pcre_compile.cpp:
-        (calculateCompiledPatternLengthAndFlags):
-        * pcre/pcre_internal.h:
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Give consistent naming to the RegExp options/compile flags
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (is_anchored):
-        (find_firstassertedchar):
-        (printCompiledRegExp):
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Pull first_byte and req_byte optimizations out into separate static funtions, SunSpider reported this as a win.
-
-        * pcre/pcre_exec.cpp:
-        (tryFirstByteOptimization):
-        (tryRequiredByteOptimization):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        give PCRE_MULTILINE a better name: OptionMatchAcrossMultipleLines
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (is_anchored):
-        (printCompiledRegExp):
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Oliver.
-
-        Deprecate jsRegExpExecute's offset-vector fallback code
-
-        * pcre/pcre_exec.cpp:
-        (jsRegExpExecute):
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Make cur_is_word and prev_is_word locals, and change OP_ANY to OP_ANY_CHAR for clarity
-
-        * pcre/pcre_compile.cpp:
-        (find_fixedlength):
-        (compile_branch):
-        (canApplyFirstCharOptimization):
-        * pcre/pcre_exec.cpp:
-        (match):
-        * pcre/pcre_internal.h:
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Mitz & Maciej.
-
-        Change _NC operators to use _IGNORING_CASE for clarity
-
-        * pcre/pcre_compile.cpp:
-        (find_fixedlength):
-        (compile_branch):
-        (find_firstassertedchar):
-        * pcre/pcre_exec.cpp:
-        (match):
-        * pcre/pcre_internal.h:
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Mitz.
-
-        Remove branch from return
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        * pcre/pcre_exec.cpp:
-        (match):
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Add repeatInformationFromInstructionOffset inline
-
-        * pcre/pcre_exec.cpp:
-        (repeatInformationFromInstructionOffset):
-        (match):
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Remove no longer used error code JSRegExpErrorMatchLimit
-
-        * kjs/regexp.cpp:
-        (KJS::RegExp::match):
-        * pcre/pcre.h:
-        * pcre/pcre_internal.h:
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Make i locally scoped for better code clarity
-
-        * pcre/pcre_exec.cpp:
-        (match):
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Give subjectPtr and instructionPtr sane names, reduce size of MatchFrame for a 0.2% speedup.
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (calculateCompiledPatternLengthAndFlags):
-        * pcre/pcre_exec.cpp:
-        (match_ref):
-        (MatchStack::pushNewFrame):
-        (getUTF8CharAndIncrementLength):
-        (match):
-        * pcre/pcre_internal.h:
-        (getChar):
-        (getCharAndAdvance):
-        (getCharAndLength):
-        (getCharAndAdvanceIfSurrogate):
-        * pcre/pcre_xclass.cpp:
-        (getUTF8CharAndAdvancePointer):
-
-2007-11-26  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Small speedup (0.7%) by simplifying canUseStackBufferForNextFrame() check
-
-        * pcre/pcre_exec.cpp:
-        (MatchStack::MatchStack):
-        (MatchStack::popCurrentFrame):
-
-2007-11-25  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Lower MATCH_LIMIT_RECURSION to more sane levels to prevent hangs on run-javascriptcore-tests
-
-        * pcre/pcre_internal.h:
-
-2007-11-25  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Remove match_is_group variable for another 5% speedup
-
-        * pcre/pcre_compile.cpp:
-        * pcre/pcre_exec.cpp:
-        (startNewGroup):
-        (match):
-
-2007-11-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Abstract frame variables into locals and args
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        * pcre/pcre_exec.cpp:
-        (match):
-        * pcre/pcre_internal.h:
-
-2007-11-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Section off MatchData arguments into args struct
-
-        * pcre/pcre_exec.cpp:
-        (MatchStack::pushNewFrame):
-        (match):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Remove redundant eptrblock struct
-
-        * pcre/pcre_exec.cpp:
-        (MatchStack::pushNewFrame):
-        (match):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Remove redundant match_call_count and move recursion check out of super-hot code path
-        SunSpider says this is at least an 8% speedup for regexp.
-
-        * pcre/pcre_exec.cpp:
-        (MatchStack::MatchStack):
-        (MatchStack::pushNewFrame):
-        (MatchStack::popCurrentFrame):
-        (MatchStack::popAllFrames):
-        (match):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Get rid of GETCHAR* macros, replacing them with better named inlines
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (calculateCompiledPatternLengthAndFlags):
-        * pcre/pcre_exec.cpp:
-        (match):
-        * pcre/pcre_internal.h:
-        (getCharAndAdvance):
-        (getCharAndLength):
-        (getCharAndAdvanceIfSurrogate):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Further cleanup GET/PUT inlines
-
-        * pcre/pcre_internal.h:
-        (putOpcodeValueAtOffset):
-        (getOpcodeValueAtOffset):
-        (putOpcodeValueAtOffsetAndAdvance):
-        (put2ByteOpcodeValueAtOffset):
-        (get2ByteOpcodeValueAtOffset):
-        (put2ByteOpcodeValueAtOffsetAndAdvance):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Give GET, PUT better names, and add (poor) moveOpcodePtrPastAnyAlternateBranches
-
-        * pcre/pcre_compile.cpp:
-        (firstSignificantOpCodeSkippingAssertions):
-        (find_fixedlength):
-        (complete_callout):
-        (compile_branch):
-        (compile_regex):
-        (is_anchored):
-        (canApplyFirstCharOptimization):
-        (find_firstassertedchar):
-        * pcre/pcre_exec.cpp:
-        (match):
-        * pcre/pcre_internal.h:
-        (putOpcodeValueAtOffset):
-        (getOpcodeValueAtOffset):
-        (putOpcodeValueAtOffsetAndAdvance):
-        (put2ByteOpcodeValueAtOffset):
-        (get2ByteOpcodeValueAtOffset):
-        (moveOpcodePtrPastAnyAlternateBranches):
-        * pcre/pcre_ucp_searchfuncs.cpp:
-        (_pcre_ucp_othercase):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Add inlines for toLowerCase, isWordChar, isSpaceChar for further regexp speedup
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (match):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-        (toLowerCase):
-        (flipCase):
-        (classBitmapForChar):
-        (charTypeForChar):
-        (isWordChar):
-        (isSpaceChar):
-        (CompileData::CompileData):
-        * pcre/pcre_xclass.cpp:
-        (_pcre_xclass):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        cleanup _pcre_ucp_othercase
-
-        * pcre/pcre_ucp_searchfuncs.cpp:
-        (_pcre_ucp_othercase):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Use better variable names for case ignoring options
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (find_firstassertedchar):
-        (printCompiledRegExp):
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (match_ref):
-        (match):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        split first_significant_code into two simpler functions
-
-        * pcre/pcre_compile.cpp:
-        (firstSignificantOpCode):
-        (firstSignificantOpCodeSkippingAssertions):
-        (is_anchored):
-        (canApplyFirstCharOptimization):
-        (find_firstassertedchar):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        clean up is_counted_repeat
-
-        * pcre/pcre_compile.cpp:
-        (is_counted_repeat):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        clean up check_escape
-
-        * pcre/pcre_compile.cpp:
-        (check_escape):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Reformat find_fixedlength
-
-        * pcre/pcre_compile.cpp:
-        (find_fixedlength):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        reformat is_anchored
-
-        * pcre/pcre_compile.cpp:
-        (is_anchored):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Remove unused function could_be_empty_branch
-
-        * pcre/pcre_compile.cpp:
-        (first_significant_code):
-        (find_fixedlength):
-        (compile_branch):
-        (canApplyFirstCharOptimization):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Pass around MatchData objects by reference
-
-        * pcre/pcre_exec.cpp:
-        (pchars):
-        (match_ref):
-        (match):
-        (jsRegExpExecute):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        give PCRE_STARTLINE a better name and rename match_data to MatchData
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (canApplyFirstCharOptimization):
-        (find_firstassertedchar):
-        (printCompiledRegExp):
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (pchars):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Clean up find_firstassertedchar
-
-        * pcre/pcre_compile.cpp:
-        (get_othercase_range):
-        (find_firstassertedchar):
-        (calculateCompiledPatternLengthAndFlags):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Tim Hatcher.
-
-        Pass around CompileData& instead of CompileData*
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-        (jsRegExpCompile):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Clean up compile_branch, move _pcre_ord2utf8, and rename CompileData
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * pcre/pcre_compile.cpp:
-        (_pcre_ord2utf8):
-        (calculateCompiledPatternLengthAndFlags):
-        (jsRegExpCompile):
-        * pcre/pcre_internal.h:
-        * pcre/pcre_ord2utf8.cpp: Removed.
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        removing more macros
-
-        * pcre/pcre_compile.cpp:
-        (could_be_empty_branch):
-        (compile_branch):
-        (calculateCompiledPatternLengthAndFlags):
-        * pcre/pcre_exec.cpp:
-        (match):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-        * pcre/pcre_xclass.cpp:
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        clean up formating in compile_branch
-
-        * pcre/pcre_compile.cpp:
-        (compile_branch):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Fix spacing for read_repeat_counts
-
-        * pcre/pcre_compile.cpp:
-        (read_repeat_counts):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Get rid of PCRE custom char types
-
-        * pcre/pcre_compile.cpp:
-        (check_escape):
-        (complete_callout):
-        (compile_branch):
-        (compile_regex):
-        (calculateCompiledPatternLengthAndFlags):
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (match_ref):
-        (match):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        reformat get_othercase_range
-
-        * pcre/pcre_compile.cpp:
-        (get_othercase_range):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Remove register keyword and more cleanup
-
-        * pcre/pcre_compile.cpp:
-        (find_fixedlength):
-        (compile_branch):
-        (is_anchored):
-        (is_startline):
-        (find_firstassertedchar):
-        (calculateCompiledPatternLengthAndFlags):
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (MatchStack::canUseStackBufferForNextFrame):
-        (MatchStack::allocateNextFrame):
-        (MatchStack::pushNewFrame):
-        (MatchStack::frameIsStackAllocated):
-        (MatchStack::popCurrentFrame):
-        (MatchStack::unrollAnyHeapAllocatedFrames):
-        (getUTF8CharAndIncrementLength):
-        (match):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-        (PUT2INC):
-        (isLeadingSurrogate):
-        (isTrailingSurrogate):
-        (decodeSurrogatePair):
-        (getChar):
-        * pcre/pcre_ord2utf8.cpp:
-        (_pcre_ord2utf8):
-        * pcre/pcre_xclass.cpp:
-        (getUTF8CharAndAdvancePointer):
-        (_pcre_xclass):
-
-2007-11-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Clean up jsRegExpExecute
-
-        * pcre/pcre_compile.cpp:
-        (returnError):
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-
-2007-11-29  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Geoff.
-
-        Merging updated system alloc and spinlock code from r38 of TCMalloc.
-
-        This is needed as a precursor to the merge of TCMalloc proper.
-
-        * wtf/FastMalloc.cpp:
-        (WTF::TCMalloc_PageHeap::GrowHeap):
-        * wtf/TCSpinLock.h:
-        (TCMalloc_SpinLock::TCMalloc_SpinLock):
-        (TCMalloc_SpinLock::):
-        (TCMalloc_SpinLock::Lock):
-        (TCMalloc_SpinLock::Unlock):
-        (TCMalloc_SpinLock::IsHeld):
-        * wtf/TCSystemAlloc.cpp:
-        (TrySbrk):
-        (TryMmap):
-        (TryVirtualAlloc):
-        (TryDevMem):
-        (TCMalloc_SystemAlloc):
-        * wtf/TCSystemAlloc.h:
-
-2007-11-28  Brady Eidson <beidson@apple.com>
-
-        Reviewed by Geoff
-
-        Add copyKeysToVector utility, mirroring copyValuesToVector
-        Also change the copyValuesToVector implementation to be a little more attractive
-
-        * wtf/HashMap.h:
-        (WTF::copyKeysToVector):
-        (WTF::copyValuesToVector):
-
-2007-11-27  Alp Toker  <alp@atoker.com>
-
-        Reviewed by Mark Rowe.
-
-        Add a list of public JavaScriptCore headers for installation.
-
-        This follows the convention used for the Qt and GTK+ header lists.
-
-        * headers.pri: Added.
-
-2007-11-27  Alp Toker  <alp@atoker.com>
-
-        Prospective MSVC build fix.
-
-        Roll back dllexport/dllimport support for now.
-
-        * API/JSBase.h:
-
-2007-11-27  Alp Toker  <alp@atoker.com>
-
-        Reviewed by Maciej.
-
-        http://bugs.webkit.org/show_bug.cgi?id=15569
-        [gtk] GTK JavaScriptCore needs to export symbols for JSC API and WTF
-
-        Introduce JS_EXPORT to mark symbols to be exported as public API.
-
-        Export all public symbols in the JavaScriptCore C API.
-
-        This matches conventions for exporting symbols set by the CF and CG
-        frameworks.
-
-        * API/JSBase.h:
-        * API/JSContextRef.h:
-        * API/JSObjectRef.h:
-        * API/JSStringRef.h:
-        * API/JSStringRefBSTR.h:
-        * API/JSStringRefCF.h:
-        * API/JSValueRef.h:
-
-2007-11-27  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Adam.
-
-        Make PropertyNameArray and ScopeChain COMEnumVariant friendly.
-        
-        * kjs/PropertyNameArray.cpp:
-        (KJS::PropertyNameArray::swap):
-        Implement PropertyNameArray::swap.
-        
-        * kjs/PropertyNameArray.h:
-        Add ValueType typedef. Replace PropertyNameArrayIterator with 
-        PropertyNameArray::const_iterator.
-        
-        * kjs/nodes.cpp:
-        (KJS::ForInNode::execute):
-        * kjs/scope_chain.cpp:
-        (KJS::ScopeChain::print):
-        Update for changes to PropertyNameArray.
-        
-        * kjs/scope_chain.h:
-        Add const_iterator and ValueType typedef.
-        
-2007-11-27  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Darin.
-
-        Add a ValueType typedef.
-        
-        * wtf/Vector.h:
-
-2007-11-26  Darin Adler  <darin@apple.com>
-
-        Reviewed by Mitz.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=16096
-          REGRESSION (r26653-r26699): Plaxo.com addressbook does not load in webkit nightlies
-
-        Test: fast/js/regexp-overflow.html
-
-        * pcre/pcre_compile.cpp: (calculateCompiledPatternLengthAndFlags):
-        Removed a stray "ptr++" that I added by accident when merging the
-        changes between PCRE 6.4 and 6.5. 
-
-2007-11-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Kevin McCullough.
-        
-        Fixed <rdar://problem/5597937> REGRESSION (r27126): Drosera does not 
-        show variables (can't enumerate ActivationImp properties)
-        
-        Implemented a custom ActivationImp::getPropertyNames, since 
-        ActivationImp now uses a custom property storage mechanism for local
-        variables.
-
-        * kjs/function.cpp:
-        (KJS::ActivationImp::getPropertyNames):
-        * kjs/function.h:
-
-2007-11-26  Alp Toker  <alp@atoker.com>
-
-        GTK+/Qt/Wx build fix for breakage introduced in r28039.
-
-        * ForwardingHeaders/JavaScriptCore/JSRetainPtr.h: Added.
-
-2007-11-24  Laszlo Gombos  <laszlo.gombos@gmail.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Fix minor compiler warning (GCC 4.1.3)
-
-        * pcre/pcre_internal.h:
-        * pcre/pcre_ucp_searchfuncs.cpp:
-        (_pcre_ucp_othercase):
-
-2007-11-25  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Dan Bernstein.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=16129
-        Bug 16129: REGRESSION (r27761-r27811): malloc error while visiting http://mysit.es (crashes release build)
-
-        * pcre/pcre_compile.cpp: Change errorcode to be passed by reference so that any error code is propagated
-        to our caller like they expect.
-
-2007-11-23  Kevin Ollivier  <kevino@theolliviers.com>
-
-        MSVC7 build fix. (rand_s doesn't exist there)
-
-        Reviewed by Adam Roben.
-
-        * kjs/config.h:
-        * wtf/MathExtras.h:
-
-2007-11-23  Kevin Ollivier  <kevino@theolliviers.com>
-
-        wx build fix. Move WX_PYTHON logic into project build settings,
-        add WebKitLibraries dirs on Win, and explicitly include JSCore 
-        headers in testkjs rather than getting them from a template.
-        (Include dir order of JSCore/WTF and ICU headers is important due  
-        to wtf/unicode/utf8.h.)
-
-        * jscore.bkl:
-
-2007-11-23  Simon Hausmann  <hausmann@webkit.org>
-
-        Reviewed by George Staikos <staikos@kde.org>.
-
-        Fix make (dist)clean on Windows.
-        
-        OBJECTS_DIR_WTR does not exist anymore, use GENERATED_SOURCES_DIR.
-        
-
-        * JavaScriptCore.pri:
-        * pcre/pcre.pri:
-
-2007-11-22  Simon Hausmann  <hausmann@kde.org>
-
-        Reviewed by George.
-
-        Make the directory of where to put the generated sources configurable through the GENERATED_SOURCE_DIR variable
-
-        * JavaScriptCore.pri:
-        * pcre/pcre.pri:
-
-2007-11-22  Simon Hausmann  <hausmann@kde.org>
-
-        Reviewed by George.
-
-        Centralize the setup for all the extra compilers in a addExtraCompiler function.
-        
-        This allows adding a "generated_files" target that builds all generated files using "make generated_files".
-        For the build inside Qt we do not generate actual rules for the extra compilers but instead
-        do the variable substitution of compiler.output manually and add the generated sources to SOURCES.
-
-        * JavaScriptCore.pri:
-        * pcre/pcre.pri:
-
-2007-11-20  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Tim Hatcher.
-
-        <rdar://problem/5602936> Need to resolve new GCC 4.2 warnings
-
-        Fix all warnings emitted by GCC 4.2 when building JavaScriptCore.  This allows builds with
-        -Werror to succeed.  At present they will crash when executed due to code that is not safe
-        under strict aliasing (<rdar://problem/5536806>).
-
-        * Configurations/Base.xcconfig: Remove the -Wno-long-double flag.
-        * kjs/date_object.cpp:
-        (KJS::formatTime): Test whether the stack-allocated string is empty rather than at a non-null address.
-        * kjs/dtoa.cpp:
-        (Bigint::): Tweak formatting to silence warnings.
-        * pcre/pcre_exec.cpp:
-        (match): Tweak formatting to silence warnings
-        * wtf/Assertions.cpp: Add printf format attribute to functions that warrant it.
-        * wtf/Assertions.h: Ditto.
-
-2007-11-19  Kevin Ollivier  <kevino@theolliviers.com>
-
-        wx port build fix (wx headers include ctype functions).
-
-        * kjs/config.h:
-
-2007-11-19  Kevin Ollivier  <kevino@theolliviers.com>
-
-        Remove outdated and unused Windows port files.
-
-        Reviewed by Adam Roben.
-
-        * Makefile.vc: Removed.
-        * README-Win32.txt: Removed.
-
-2007-11-18  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Oliver.
-
-        * tests/mozilla/jsDriver.pl: exit non-0 when user aborts test run
-
-2007-11-17  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Darin Adler.
-
-        Fix: <rdar://problem/5607032> REGRESSION: testapi exits with assertion failure in debug build
-             <rdar://problem/5440659> JSGlobalContextCreate throws away globalObjectClass's prototype
-             http://bugs.webkit.org/show_bug.cgi?id=16033
-
-        Split Interpreter's initialization into two distinct steps:  the creation of the global prototypes
-        and constructors, and storing them on the global object.  This allows JSClassRef's passed to
-        JSGlobalContextCreate to be instantiated with the correct prototype.
-
-        * API/JSCallbackObject.cpp: Assert at compile-time that the custom global object will fit in a collector cell.
-        * API/JSCallbackObject.h:
-        * API/JSCallbackObjectFunctions.h:
-        (KJS::::JSCallbackObject):
-        (KJS::::init):
-        * API/JSContextRef.cpp:
-        (JSGlobalContextCreate): Construct and set the interpreter's global object separately.  When globalObjectClass
-        is passed we need to set the interpreter's global object before doing the JSCallbackObject's initialization to
-        prevent any JSObjectInitializeCallback's being invoked before a global object is set.
-        * API/testapi.c:
-        (globalObject_initialize): Test the object passed in is correct and that it has the expected global properties.
-        (globalObject_get):
-        (globalObject_set):
-        (main):
-        * API/testapi.js: Test that any static properties exposed by the global object's custom class are found.
-        * JavaScriptCore.exp:
-        * bindings/testbindings.cpp:
-        (main): Update for changes in Interpreter method signatures.
-        * bindings/testbindings.mm:
-        (main): Ditto.
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        (KJS::ExecState::mark):
-        (KJS::ExecState::setGlobalObject):
-        * kjs/ExecState.h: Rename scope to m_scopeChain.
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::Interpreter):
-        (KJS::Interpreter::init):
-        (KJS::Interpreter::globalObject):
-        (KJS::Interpreter::setGlobalObject):
-        (KJS::Interpreter::resetGlobalObjectProperties):
-        (KJS::Interpreter::createObjectsForGlobalObjectProperties):
-        (KJS::Interpreter::setGlobalObjectProperties): Switch to using putDirect to ensure that the global object's put method
-        cannot interfere with setting of the global properties.  This prevents a user-written JSClassRef from attempting to
-        call back into JavaScript from the initialization of the global object's members.
-        * kjs/interpreter.h:
-        * kjs/testkjs.cpp:
-        (setupInterpreter): Update for changes in Interpreter method signatures.
-
-2007-11-17  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Prevent testapi from reporting false leaks.  Clear out local variables pointing at
-        JSObjectRefs to allow their values to be collected.
-
-        * API/testapi.c:
-        (main):
-
-2007-11-17  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Prevent testapi from crashing if testapi.js can not be found by nil-checking the result of createStringWithContentsOfFile.
-
-        * API/testapi.c:
-        (main):
-
-2007-11-17  Alp Toker  <alp@atoker.com>
-
-        Reviewed by Eric.
-
-        http://bugs.webkit.org/show_bug.cgi?id=16032
-        JS minidom is not portable
-
-        Use a plain UTF-8 string instead of a CFString.
-
-        Print to stdout, not stderr like CFShow() would have done, since that
-        behaviour seems unintentional.
-
-        * API/minidom.c:
-        (main):
-
-2007-11-17  Steve Falkenburg  <sfalken@apple.com>
-
-        Windows build fix.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2007-11-16  Mark Rowe  <mrowe@apple.com>
-
-        Windows build fix.
-
-        * kjs/lexer.cpp:
-        (KJS::Lexer::record8):
-
-2007-11-16  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Eric.
-
-        Replace strings, identifier, buffer8 and buffer16 members of Lexer with vectors.
-        SunSpider claims this is a 0.7% speedup.
-
-        * kjs/lexer.cpp:
-        (KJS::Lexer::Lexer):
-        (KJS::Lexer::lex):
-        (KJS::Lexer::record8):
-        (KJS::Lexer::record16):
-        (KJS::Lexer::scanRegExp):
-        (KJS::Lexer::clear):
-        (KJS::Lexer::makeIdentifier):
-        (KJS::Lexer::makeUString):
-        * kjs/lexer.h:
-        * kjs/ustring.cpp:
-        (KJS::UString::UString): Add a convenience constructor that takes a const Vector<UChar>&.
-        * kjs/ustring.h:
-
-2007-11-16  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj: Add a new include path
-        and ignore the int -> bool conversion warning.
-
-2007-11-16  Alexey Proskuryakov  <ap@webkit.org>
-
-        Fix Windows debug build.
-        Rubber-stamped by Eric
-
-        * pcre/pcre_exec.cpp: (match): Removed ASSERT_NOT_REACHED assertions that were making MSVC
-        complain about unreachable code.
-
-2007-11-15  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/Parser.cpp:
-
-2007-11-15  Mark Rowe  <mrowe@apple.com>
-
-        Mac build and header search path sanity fix.
-
-        Reviewed by Sam Weinig and Tim Hatcher.
-
-        Move base setting for HEADER_SEARCH_PATHS into Base.xcconfig, and extend
-        it in JavaScriptCore.xcconfig.  This removes the need to override it on a
-        per-target basis inside the .xcodeproj file.
-
-        * Configurations/Base.xcconfig:
-        * Configurations/JavaScriptCore.xcconfig:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2007-11-15  Mark Rowe  <mrowe@apple.com>
-
-        Qt build fix.
-
-        * kjs/Parser.h:
-
-2007-11-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Eric Seidel.
-
-        Another round of grammar / parsing cleanup.
-        
-        1. Created distinct parser calls for parsing function bodies vs
-        programs. This will help later with optimizing global variable access.
-        
-        2. Turned Parser into a singleton. Cleaned up Lexer's singleton 
-        interface.
-        
-        3. Modified Lexer to free a little more memory when done lexing. (Added
-        FIXMEs for similar issues that I didn't fix.)
-        
-        4. Changed Lexer::makeIdentifier and Lexer::makeUString to start 
-        respecting the arguments passed to them. (No behavior change, but this
-        problem could have caused serious problems for an unsuspecting user of
-        these functions.)
-        
-        5. Removed KJS_DEBUG_MEM because it was bit-rotted.
-        
-        6. Removed Parser::prettyPrint because the same work was simpler to do
-        at the call site.
-        
-        7. Some renames:
-        
-            "Parser::accept" => "Parser::didFinishParsing"
-            "Parser::sid" => "Parser::m_sourceID"
-            "Lexer::doneParsing" => "Lexer::clear"
-            "sid" => "sourceId"
-            "lineno" => "lineNo"
-        
-        * JavaScriptCore.exp:
-        * kjs/Parser.cpp:
-        (KJS::Parser::Parser):
-        (KJS::Parser::parseProgram):
-        (KJS::Parser::parseFunctionBody):
-        (KJS::Parser::parse):
-        (KJS::Parser::didFinishParsing):
-        (KJS::parser):
-        * kjs/Parser.h:
-        (KJS::Parser::sourceId):
-        * kjs/function.cpp:
-        (KJS::GlobalFuncImp::callAsFunction):
-        * kjs/function_object.cpp:
-        (FunctionObjectImp::construct):
-        * kjs/grammar.y:
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::checkSyntax):
-        (KJS::Interpreter::evaluate):
-        * kjs/interpreter.h:
-        * kjs/lexer.cpp:
-        (kjsyylex):
-        (KJS::lexer):
-        (KJS::Lexer::Lexer):
-        (KJS::Lexer::~Lexer):
-        (KJS::Lexer::scanRegExp):
-        (KJS::Lexer::doneParsing):
-        (KJS::Lexer::makeIdentifier):
-        (KJS::Lexer::makeUString):
-        * kjs/lexer.h:
-        (KJS::Lexer::pattern):
-        (KJS::Lexer::flags):
-        (KJS::Lexer::sawError):
-        * kjs/nodes.cpp:
-        (KJS::Node::Node):
-        (KJS::FunctionBodyNode::FunctionBodyNode):
-        * kjs/nodes.h:
-        * kjs/testkjs.cpp:
-        (prettyPrintScript):
-        (kjsmain):
-        * kjs/ustring.cpp:
-        * kjs/ustring.h:
-
-2007-11-15  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Darin.
-
-        <rdar://problem/5601548> REGRESSION: All SourceElements and their children leak after a syntax error
-        
-        Add a stub node to maintain the Vector of SourceElements until assignment.
-
-        * kjs/grammar.y:
-        * kjs/nodes.h:
-        (KJS::SourceElementsStub::SourceElementsStub):
-        (KJS::SourceElementsStub::append):
-        (KJS::SourceElementsStub::release):
-        (KJS::SourceElementsStub::):
-        (KJS::SourceElementsStub::precedence):
-
-2007-11-15  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Abstract most of RMATCH into MatchStack functions.
-        
-        SunSpider claims this, combined with the last 2 patches was a 1% speedup, 10% for dna-regexp.
-
-        * pcre/pcre_exec.cpp:
-        (MatchStack::canUseStackBufferForNextFrame):
-        (MatchStack::allocateNextFrame):
-        (MatchStack::pushNewFrame):
-        (MatchStack::frameIsStackAllocated):
-        (MatchStack::popCurrentFrame):
-        (MatchStack::unrollAnyHeapAllocatedFrames):
-        (match):
-
-2007-11-15  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Remove RETURN_ERROR, add MatchStack
-        
-        * pcre/pcre_exec.cpp:
-        (MatchStack::MatchStack):
-        (MatchStack::unrollAnyHeapAllocatedFrames):
-        (matchError):
-        (match):
-        
-2007-11-15  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-
-        Clean up match function to match WebKit style
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * pcre/pcre_exec.cpp:
-        (match):
-
-2007-11-15  Steve Falkenburg  <sfalken@apple.com>
-
-        Windows build fix.
-
-        * JavaScriptCore.vcproj/JavaScriptCore.make:
-
-2007-11-14  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        http://bugs.webkit.org/show_bug.cgi?id=15982
-        Improve JSString UTF-8 decoding
-
-        * API/JSStringRef.cpp:
-        (JSStringCreateWithUTF8CString): Use strict decoding, return 0 on error.
-
-        * wtf/unicode/UTF8.cpp:
-        (WTF::Unicode::convertUTF16ToUTF8):
-        (WTF::Unicode::convertUTF8ToUTF16):
-        * wtf/unicode/UTF8.h:
-        Made these function names start with a lower case letter.
-
-        * kjs/ustring.cpp: (KJS::UString::UTF8String): Updated for the above renaming.
-
-        * bindings/c/c_utility.cpp:
-        (KJS::Bindings::convertUTF8ToUTF16WithLatin1Fallback): Renamed to highlight the difference
-        from convertUTF8ToUTF16 in wtf/unicode.
-        (KJS::Bindings::convertNPStringToUTF16): Updated for the above renaming.
-        (KJS::Bindings::identifierFromNPIdentifier): Ditto.
-        * bindings/c/c_utility.h: Made convertUTF8ToUTF16WithLatin1Fallback() a file static.
-
-2007-11-14  Sam Weinig  <sam@webkit.org>
-
-        Rubber-stamped by Anders.
-
-        Fix the Xcode project file after it was messed up in r27402.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2007-11-14  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Oliver.
-        
-        More PCRE style cleanup.
-
-        * pcre/pcre_compile.cpp:
-        (compile_regex):
-
-2007-11-14  Adam Roben  <aroben@apple.com>
-
-        Clean up the bison conflict checking script
-
-        Reviewed by Geoff.
-
-        * DerivedSources.make:
-
-2007-11-14  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Geoff.
-
-        Another round of PCRE cleanups: inlines
-        
-        SunSpider claims that this, combined with my previous PCRE cleanup were a 0.7% speedup, go figure.
-
-        * pcre/pcre_compile.cpp:
-        (jsRegExpCompile):
-        * pcre/pcre_exec.cpp:
-        (match):
-        (jsRegExpExecute):
-        * pcre/pcre_internal.h:
-        (PUT):
-        (GET):
-        (PUT2):
-        (GET2):
-        (isNewline):
-
-2007-11-14  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Sam.
-        
-        Give PCRE a (small) bath.
-        Fix some formating and break things off into separate functions
-        http://bugs.webkit.org/show_bug.cgi?id=15993
-
-        * pcre/pcre_compile.cpp:
-        (calculateCompiledPatternLengthAndFlags):
-        (printCompiledRegExp):
-        (returnError):
-        (jsRegExpCompile):
-        * pcre/pcre_internal.h:
-        (compile_data::compile_data):
-
-2007-11-14  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Eric Seidel.
-        
-        Cleaned up the JavaScript grammar a bit.
-        
-        1. Changed BlockNode to always hold a child vector (which may be empty),
-        eliminating a few NULL-check branches in the common execution case.
-        
-        2. Changed the Block production to correctly report its starting and 
-        ending line numbers to the debugger. (It used to report its ending line
-        as its starting line.) Also, removed duplicate line-reporting code
-        inside the BlockNode constructor.
-        
-        3. Moved curly braces up from FunctionBody production into parent
-        productions. (I had to move the line number reporting code, too, since
-        it depends on the location of the curly braces.) This matches the ECMA
-        spec more closely, and makes some future changes I plan easier.
-        
-        4. Fixed statementList* convenience functions to deal appropriately with
-        empty Vectors.
-
-        SunSpider reports a small and statistically insignificant speedup.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::statementListPushFIFO):
-        (KJS::statementListGetDeclarations):
-        (KJS::statementListInitializeDeclarationStack):
-        (KJS::statementListInitializeVariableAccessStack):
-        (KJS::BlockNode::BlockNode):
-        (KJS::BlockNode::optimizeVariableAccess):
-        (KJS::BlockNode::getDeclarations):
-        (KJS::BlockNode::execute):
-        (KJS::FunctionBodyNode::initializeDeclarationStacks):
-        (KJS::FunctionBodyNode::optimizeVariableAccess):
-
-2007-11-13  Anders Carlsson  <andersca@apple.com>
-
-        Add RefCounted.h (And remove Shared.h)
-        
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-
-2007-11-13  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix.
-
-        * kjs/regexp.h:
-
-2007-11-13  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Anders Carlsson.
-
-        Renamed Shared to RefCounted.
-
-        * API/JSClassRef.h:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/interpreter.h:
-        * kjs/regexp.h:
-        * wtf/RefCounted.h: Copied from JavaScriptCore/wtf/Shared.h.
-        (WTF::RefCounted::RefCounted):
-        * wtf/Shared.h: Removed.
-
-2007-11-13  Adam Roben  <aroben@apple.com>
-
-        Build fix
-
-        Reviewed by Geoff.
-
-        * kjs/regexp.h: Added a missing #include.
-
-2007-11-13  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-
-        Moved Shared.h into wtf so it could be used in more places. Deployed
-        Shared in places where JSCore previously had hand-rolled ref-counting
-        classes.
-
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::OpaqueJSClass):
-        * API/JSClassRef.h:
-        * API/JSObjectRef.cpp:
-        (JSClassRetain):
-        (JSClassRelease):
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::init):
-        * kjs/interpreter.h:
-        * kjs/regexp.cpp:
-        (KJS::RegExp::RegExp):
-        * kjs/regexp.h:
-        * wtf/Shared.h: Copied from WebCore/platform/Shared.h.
-
-2007-11-13  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Add an ASSERT to getTruncatedInt32 to enforce proper usage.
-        Best part about this patch?  It doesn't break the web!
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::getTruncatedInt32):
-        (KJS::JSImmediate::toDouble):
-        (KJS::JSImmediate::getUInt32):
-
-2007-11-13  Alexey Proskuryakov  <ap@webkit.org>
-
-        Windows build fix.
-
-        * bindings/c/c_utility.cpp:
-        (KJS::Bindings::convertUTF8ToUTF16):
-        * kjs/ustring.cpp:
-        (KJS::UString::UTF8String):
-        * wtf/unicode/UTF8.cpp:
-        (WTF::Unicode::ConvertUTF8ToUTF16):
-
-2007-11-13  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=11231
-          RegExp bug when handling newline characters
-          and a number of other differences between PCRE behvior
-          and JavaScript regular expressions:
-
-          + single-digit sequences like \4 should be treated as octal
-            character constants, unless there is a sufficient number
-            of brackets for them to be treated as backreferences
-
-          + \8 turns into the character "8", not a binary zero character
-            followed by "8" (same for 9)
-
-          + only the first 3 digits should be considered part of an
-            octal character constant (the old behavior was to decode
-            an arbitrarily long sequence and then mask with 0xFF)
-
-          + if \x is followed by anything other than two valid hex digits,
-            then it should simply be treated a the letter "x"; that includes
-            not supporting the \x{41} syntax
-
-          + if \u is followed by anything less than four valid hex digits,
-            then it should simply be treated a the letter "u"
-
-          + an extra "+" should be a syntax error, rather than being treated
-            as the "possessive quantifier"
-
-          + if a "]" character appears immediately after a "[" character that
-            starts a character class, then that's an empty character class,
-            rather than being the start of a character class that includes a
-            "]" character
-
-          + a "$" should not match a terminating newline; we could have gotten
-            PCRE to handle this the way we wanted by passing an appropriate option
-
-        Test: fast/js/regexp-no-extensions.html
-
-        * pcre/pcre_compile.cpp:
-        (check_escape): Check backreferences against bracount to catch both
-        overflows and things that should be treated as octal. Rewrite octal
-        loop to not go on indefinitely. Rewrite both hex loops to match and
-        remove \x{} support.
-        (compile_branch): Restructure loops so that we don't special-case a "]"
-        at the beginning of a character class. Remove code that treated "+" as
-        the possessive quantifier.
-        (jsRegExpCompile): Change the "]" handling here too.
-
-        * pcre/pcre_exec.cpp: (match): Changed CIRC to match the DOLL implementation.
-        Changed DOLL to remove handling of "terminating newline", a Perl concept
-        which we don't need.
-
-        * tests/mozilla/expected.html: Two tests are fixed now:
-        ecma_3/RegExp/regress-100199.js and ecma_3/RegExp/regress-188206.js.
-        One test fails now: ecma_3/RegExp/perlstress-002.js -- our success before
-        was due to a bug (we treated all 1-character numeric escapes as backreferences).
-        The date tests also now both expect success -- whatever was making them fail
-        before was probably due to the time being close to a DST shift; maybe we need
-        to get rid of those tests.
-
-2007-11-13  Darin Adler  <darin@apple.com>
-
-        * kjs/JSImmediate.h: (KJS::JSImmediate::getTruncatedInt32):
-        Remove too-strong assert that was firing constantly and preventing even basic
-        web browsing from working in a debug build. This function is used in many
-        cases where the immediate value is not a number; the assertion could perhaps
-        be added back later with a bit of reorganization.
-
-2007-11-13  Alp Toker  <alp@atoker.com>
-
-        Build fix for breakage to non-Mac builds introduced in r27746.
-
-        * kjs/ustring.cpp:
-
-2007-11-13  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-
-        Clean up evaluateToBoolean functions to use inlines instead of copy/paste code
-
-        * kjs/JSImmediate.h:
-        * kjs/nodes.cpp:
-        (KJS::GreaterNode::inlineEvaluateToBoolean):
-        (KJS::GreaterNode::evaluate):
-        (KJS::LessEqNode::inlineEvaluateToBoolean):
-        (KJS::LessEqNode::evaluate):
-        (KJS::GreaterEqNode::inlineEvaluateToBoolean):
-        (KJS::GreaterEqNode::evaluate):
-        (KJS::InNode::evaluateToBoolean):
-        (KJS::EqualNode::inlineEvaluateToBoolean):
-        (KJS::EqualNode::evaluate):
-        (KJS::NotEqualNode::inlineEvaluateToBoolean):
-        (KJS::NotEqualNode::evaluate):
-        (KJS::StrictEqualNode::inlineEvaluateToBoolean):
-        (KJS::StrictEqualNode::evaluate):
-        (KJS::NotStrictEqualNode::inlineEvaluateToBoolean):
-        (KJS::NotStrictEqualNode::evaluate):
-        * kjs/nodes.h:
-
-2007-11-12  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Fixed http://bugs.webkit.org/show_bug.cgi?id=15958
-        base64 spends 1.1% of total time checking for special Infinity case
-        
-        Use a fast character test instead of calling strncmp.
-        
-        1.1% speedup on string-base64. SunSpider reports a .4% speedup overall;
-        Sharks reports only .1%. Who are you going to believe? Huh?
-
-        * kjs/ustring.cpp:
-        (KJS::UString::toDouble):
-
-2007-11-12  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Oliver.
-
-        Add evaluateToInt32 and evaluateUInt32 methods and deploy them.
-        Fix a few missing evaluateToBoolean methods
-        Deploy all evaluateTo* functions to more nodes to avoid slowdowns
-        http://bugs.webkit.org/show_bug.cgi?id=15950
-        
-        SunSpider claims this is at least a 1.4% speedup.
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::getTruncatedInt32):
-        (KJS::JSImmediate::toDouble):
-        (KJS::JSImmediate::getUInt32):
-        * kjs/nodes.cpp:
-        (KJS::ExpressionNode::evaluateToNumber):
-        (KJS::ExpressionNode::evaluateToInt32):
-        (KJS::ExpressionNode::evaluateToUInt32):
-        (KJS::NumberNode::evaluateToInt32):
-        (KJS::NumberNode::evaluateToUInt32):
-        (KJS::ImmediateNumberNode::evaluateToInt32):
-        (KJS::ImmediateNumberNode::evaluateToUInt32):
-        (KJS::ResolveNode::evaluate):
-        (KJS::ResolveNode::evaluateToNumber):
-        (KJS::ResolveNode::evaluateToBoolean):
-        (KJS::ResolveNode::evaluateToInt32):
-        (KJS::ResolveNode::evaluateToUInt32):
-        (KJS::LocalVarAccessNode::evaluateToInt32):
-        (KJS::LocalVarAccessNode::evaluateToUInt32):
-        (KJS::BracketAccessorNode::evaluateToNumber):
-        (KJS::BracketAccessorNode::evaluateToBoolean):
-        (KJS::BracketAccessorNode::evaluateToInt32):
-        (KJS::BracketAccessorNode::evaluateToUInt32):
-        (KJS::DotAccessorNode::inlineEvaluate):
-        (KJS::DotAccessorNode::evaluate):
-        (KJS::DotAccessorNode::evaluateToNumber):
-        (KJS::DotAccessorNode::evaluateToBoolean):
-        (KJS::DotAccessorNode::evaluateToInt32):
-        (KJS::DotAccessorNode::evaluateToUInt32):
-        (KJS::NewExprNode::inlineEvaluate):
-        (KJS::NewExprNode::evaluate):
-        (KJS::NewExprNode::evaluateToNumber):
-        (KJS::NewExprNode::evaluateToBoolean):
-        (KJS::NewExprNode::evaluateToInt32):
-        (KJS::NewExprNode::evaluateToUInt32):
-        (KJS::FunctionCallResolveNode::inlineEvaluate):
-        (KJS::FunctionCallResolveNode::evaluate):
-        (KJS::FunctionCallResolveNode::evaluateToNumber):
-        (KJS::FunctionCallResolveNode::evaluateToBoolean):
-        (KJS::FunctionCallResolveNode::evaluateToInt32):
-        (KJS::FunctionCallResolveNode::evaluateToUInt32):
-        (KJS::LocalVarFunctionCallNode::evaluate):
-        (KJS::LocalVarFunctionCallNode::evaluateToNumber):
-        (KJS::LocalVarFunctionCallNode::evaluateToBoolean):
-        (KJS::LocalVarFunctionCallNode::evaluateToInt32):
-        (KJS::LocalVarFunctionCallNode::evaluateToUInt32):
-        (KJS::FunctionCallDotNode::evaluate):
-        (KJS::FunctionCallDotNode::evaluateToNumber):
-        (KJS::FunctionCallDotNode::evaluateToBoolean):
-        (KJS::FunctionCallDotNode::evaluateToInt32):
-        (KJS::FunctionCallDotNode::evaluateToUInt32):
-        (KJS::PostDecLocalVarNode::inlineEvaluateToNumber):
-        (KJS::PostDecLocalVarNode::evaluateToNumber):
-        (KJS::PostDecLocalVarNode::evaluateToBoolean):
-        (KJS::PostDecLocalVarNode::evaluateToInt32):
-        (KJS::PostDecLocalVarNode::evaluateToUInt32):
-        (KJS::typeStringForValue):
-        (KJS::UnaryPlusNode::evaluate):
-        (KJS::UnaryPlusNode::evaluateToBoolean):
-        (KJS::UnaryPlusNode::evaluateToNumber):
-        (KJS::UnaryPlusNode::evaluateToInt32):
-        (KJS::BitwiseNotNode::inlineEvaluateToInt32):
-        (KJS::BitwiseNotNode::evaluate):
-        (KJS::BitwiseNotNode::evaluateToNumber):
-        (KJS::BitwiseNotNode::evaluateToBoolean):
-        (KJS::BitwiseNotNode::evaluateToInt32):
-        (KJS::MultNode::evaluateToBoolean):
-        (KJS::MultNode::evaluateToInt32):
-        (KJS::MultNode::evaluateToUInt32):
-        (KJS::DivNode::evaluateToInt32):
-        (KJS::DivNode::evaluateToUInt32):
-        (KJS::ModNode::evaluateToBoolean):
-        (KJS::ModNode::evaluateToInt32):
-        (KJS::ModNode::evaluateToUInt32):
-        (KJS::AddNode::evaluateToNumber):
-        (KJS::AddNode::evaluateToInt32):
-        (KJS::AddNode::evaluateToUInt32):
-        (KJS::AddNumbersNode::evaluateToInt32):
-        (KJS::AddNumbersNode::evaluateToUInt32):
-        (KJS::SubNode::evaluateToInt32):
-        (KJS::SubNode::evaluateToUInt32):
-        (KJS::LeftShiftNode::inlineEvaluateToInt32):
-        (KJS::LeftShiftNode::evaluate):
-        (KJS::LeftShiftNode::evaluateToNumber):
-        (KJS::LeftShiftNode::evaluateToInt32):
-        (KJS::RightShiftNode::inlineEvaluateToInt32):
-        (KJS::RightShiftNode::evaluate):
-        (KJS::RightShiftNode::evaluateToNumber):
-        (KJS::RightShiftNode::evaluateToInt32):
-        (KJS::UnsignedRightShiftNode::inlineEvaluateToUInt32):
-        (KJS::UnsignedRightShiftNode::evaluate):
-        (KJS::UnsignedRightShiftNode::evaluateToNumber):
-        (KJS::UnsignedRightShiftNode::evaluateToInt32):
-        (KJS::LessNode::inlineEvaluateToBoolean):
-        (KJS::LessNode::evaluate):
-        (KJS::LessNode::evaluateToBoolean):
-        (KJS::LessNumbersNode::inlineEvaluateToBoolean):
-        (KJS::LessNumbersNode::evaluate):
-        (KJS::LessNumbersNode::evaluateToBoolean):
-        (KJS::LessStringsNode::inlineEvaluateToBoolean):
-        (KJS::LessStringsNode::evaluate):
-        (KJS::BitAndNode::evaluate):
-        (KJS::BitAndNode::inlineEvaluateToInt32):
-        (KJS::BitAndNode::evaluateToNumber):
-        (KJS::BitAndNode::evaluateToBoolean):
-        (KJS::BitAndNode::evaluateToInt32):
-        (KJS::BitXOrNode::inlineEvaluateToInt32):
-        (KJS::BitXOrNode::evaluate):
-        (KJS::BitXOrNode::evaluateToNumber):
-        (KJS::BitXOrNode::evaluateToBoolean):
-        (KJS::BitXOrNode::evaluateToInt32):
-        (KJS::BitOrNode::inlineEvaluateToInt32):
-        (KJS::BitOrNode::evaluate):
-        (KJS::BitOrNode::evaluateToNumber):
-        (KJS::BitOrNode::evaluateToBoolean):
-        (KJS::BitOrNode::evaluateToInt32):
-        (KJS::ConditionalNode::evaluateToNumber):
-        (KJS::ConditionalNode::evaluateToInt32):
-        (KJS::ConditionalNode::evaluateToUInt32):
-        (KJS::valueForReadModifyAssignment):
-        (KJS::AssignExprNode::evaluate):
-        (KJS::AssignExprNode::evaluateToBoolean):
-        (KJS::AssignExprNode::evaluateToNumber):
-        (KJS::AssignExprNode::evaluateToInt32):
-        (KJS::VarDeclNode::handleSlowCase):
-        * kjs/nodes.h:
-        (KJS::FunctionCallResolveNode::precedence):
-        (KJS::AddNode::precedence):
-        (KJS::AddNode::):
-        (KJS::LessNumbersNode::):
-        (KJS::LessStringsNode::):
-        * kjs/value.cpp:
-        (KJS::JSValue::toInt32SlowCase):
-        (KJS::JSValue::toUInt32SlowCase):
-        * kjs/value.h:
-        (KJS::JSValue::asCell):
-        (KJS::JSValue::toInt32):
-        (KJS::JSValue::toUInt32):
-
-2007-11-12  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        http://bugs.webkit.org/show_bug.cgi?id=15953
-        Add UTF-8 encoding/decoding to WTF
-
-        * kjs/ustring.h: Moved UTF8SequenceLength() and decodeUTF8Sequence() to wtf/unicode.
-        * kjs/ustring.cpp: (KJS::UString::UTF8String): Changed this function to take a strict/lenient
-        parameter. Callers are not interested in getting decoding results in strict mode, so 
-        this allows for bailing out as soon as an error is seen.
-
-        * kjs/function.cpp:
-        (KJS::encode): Updated for new UString::UTF8String() signature.
-
-        * API/JSStringRef.cpp:
-        (JSStringCreateWithCharacters): Disambiguate UChar.
-        (JSStringCreateWithUTF8CString): Actually use UTF-8 when creating the string!
-        * bindings/c/c_utility.cpp: (KJS::Bindings::convertUTF8ToUTF16): Use ConvertUTF8ToUTF16().
-
-        * wtf/unicode/UTF8.cpp: Added.
-        (WTF::Unicode::inlineUTF8SequenceLengthNonASCII):
-        (WTF::Unicode::inlineUTF8SequenceLength):
-        (WTF::Unicode::UTF8SequenceLength):
-        (WTF::Unicode::decodeUTF8Sequence):
-        (WTF::Unicode::):
-        (WTF::Unicode::ConvertUTF16ToUTF8):
-        (WTF::Unicode::isLegalUTF8):
-        (WTF::Unicode::ConvertUTF8ToUTF16):
-        * wtf/unicode/UTF8.h: Added.
-        (WTF::Unicode::):
-        Some code moved from ustring.h, some adapted from unicode.org sources.
-
-        * JavaScriptCore.exp:
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        Added UTF8.{h,cpp}
-
-2007-11-12  Josh Aas  <joshmoz@gmail.com>
-
-        Reviewed by Darin.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15946
-          add NPPValue NPPVpluginDrawingModel (Mozilla bug 403418 compat)
-
-        * bindings/npapi.h:
-
-2007-11-12  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15951
-          REGRESSION: assertion failure in regexp match() when running JS tests
-
-        Test: fast/js/regexp-many-brackets.html
-
-        * pcre/pcre_exec.cpp: (match): Added back accidentally-removed case for
-        the BRANUMBER opcode.
-
-2007-11-12  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix use of prefix and config.h, got rid of a few unneeded things in
-          the PCRE code; no behavior changes
-
-        * API/JSBase.cpp: Added include of config.h.
-        * API/JSCallbackConstructor.cpp: Ditto.
-        * API/JSCallbackFunction.cpp: Ditto.
-        * API/JSCallbackObject.cpp: Ditto.
-        * API/JSClassRef.cpp: Ditto.
-        * API/JSContextRef.cpp: Ditto.
-        * API/JSObjectRef.cpp: Ditto.
-        * API/JSStringRef.cpp: Ditto.
-        * API/JSValueRef.cpp: Ditto.
-
-        * JavaScriptCorePrefix.h: Removed obsolete <ctype.h> workaround.
-        Moved new/delete macros after includes, as they are in WebCore's prefix.
-        Removed "config.h".
-
-        * pcre/dftables.cpp: (main): Changed back to not use a separate maketables
-        function. This is needed for PCRE, but not helpful for our use. Also changed
-        the tables to all be 128 entries long instead of 256, since only the first
-        128 are ever used.
-
-        * pcre/pcre_compile.cpp: Added include of config.h. Eliminated digitab,
-        which was only being used to check hex digits. Changed all uses of TRUE and
-        FALSE to use the C++ true and false instead.
-        (check_escape): Just the TRUE/FALSE thing.
-        (is_counted_repeat): Ditto.
-        (could_be_empty_branch): Ditto.
-        (get_othercase_range): Ditto.
-        (compile_branch): Ditto.
-        (compile_regex): Ditto.
-        (is_anchored): Ditto.
-        (is_startline): Ditto.
-        (find_firstassertedchar): Ditto.
-        (jsRegExpCompile): Ditto.
-
-        * pcre/pcre_exec.cpp: Added include of config.h. Changed all uses of TRUE and
-        FALSE to use the C++ true and false instead.
-        (match_ref): Just the TRUE/FALSE thing.
-        (match): Ditto. Removed some unneeded braces.
-        (jsRegExpExecute): Just the TRUE/FALSE thing.
-
-        * pcre/pcre_internal.h: Moved the constants needed by dftables.cpp to the top
-        of the file instead of the bottom, so they can be used. Also changed the table
-        sizes to 128 instead of 256. Removed macro definitions of FALSE and TRUE.
-        Set array sizes for all the const arrays. Changed _pcre_utf8_table1_size to
-        be a macro instead of a extern int.
-
-        * pcre/pcre_maketables.cpp: Removed. It's all in dftables.cpp now.
-
-        * pcre/pcre_tables.cpp: Made table sizes explicit.
-
-        * pcre/pcre_xclass.cpp: Just the TRUE/FALSE thing.
-
-2007-11-12  Adam Roben  <aroben@apple.com>
-
-        Build fix
-
-        * wtf/FastMalloc.h: Add missing using statement.
-
-2007-11-11  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Darin.
-
-        Add special fastZeroedMalloc function to replace a 
-        number of fastCalloc calls where one argument was 1.
-        
-        This results in a 0.4% progression in SunSpider, more
-        than making up for the earlier regression caused by 
-        additional overflow checks.
-
-        * JavaScriptCore.exp:
-        * kjs/array_instance.cpp:
-        * kjs/property_map.cpp:
-        * wtf/FastMalloc.cpp:
-        * wtf/FastMalloc.h:
-        * wtf/HashTable.h:
-
-2007-11-11  Adam Roben  <aroben@apple.com>
-
-        Fix <rdar://5578982> ASSERT in HashTable::checkTableConsistencyExceptSize beneath WebNotificationCenter
-
-        The bug was due to a mismatch between HashMap::remove and
-        HashTable::checkTableConsistency. HashMap::remove can delete the value
-        stored in the HashTable (by derefing it), which is not normally
-        allowed by HashTable. It's OK in this case because the value is about
-        to be removed from the table, but HashTable wasn't aware of this.
-
-        HashMap::remove now performs the consistency check itself before
-        derefing the value.
-
-        Darin noticed that the same bug would occur in HashSet, so I've fixed
-        it there as well.
-
-        Reviewed by Darin.
-
-        * wtf/HashMap.h:
-        (WTF::HashMap::remove): Perform the HashTable consistency check
-        manually before calling deref.
-        * wtf/HashSet.h:
-        (WTF::HashSet::remove): Ditto.
-        * wtf/HashTable.h: Made checkTableConsistency public so that HashMap
-        and HashSet can call it.
-        (WTF::HashTable::removeAndInvalidateWithoutEntryConsistencyCheck):
-        Added.
-        (WTF::HashTable::removeAndInvalidate): Added.
-        (WTF::HashTable::remove):
-        (WTF::HashTable::removeWithoutEntryConsistencyCheck): Added.
-
-2007-11-11  Mark Rowe  <mrowe@apple.com>
-
-        Build fix.  Use the correct filename case.
-
-        * kjs/nodes.h:
-
-2007-11-11  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Fixed http://bugs.webkit.org/show_bug.cgi?id=15902
-        15% of string-validate-input.js is spent compiling the same regular expression
-        
-        Store a compiled representation of the regular expression in the AST.
-        
-        Only a .2% SunSpider speedup overall, but a 10.6% speedup on 
-        string-validate-input.js.
-
-        * kjs/nodes.cpp:
-        (KJS::RegExpNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::RegExpNode::):
-        * kjs/nodes2string.cpp:
-        (KJS::RegExpNode::streamTo):
-        * kjs/regexp.cpp:
-        (KJS::RegExp::flags):
-        * kjs/regexp.h:
-        (KJS::RegExp::pattern):
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpObjectImp::construct):
-        (KJS::RegExpObjectImp::createRegExpImp):
-        * kjs/regexp_object.h:
-
-2007-11-11  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Eric.
-
-        Partial fix for <rdar://problem/5585334> numfuzz: integer overflows opening malformed SVG file in WebCore::ImageBuffer::create
-
-        Unfortunately this is a very slight regression, but is unavoidable.
-
-        * wtf/FastMalloc.cpp:
-
-2007-11-10  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-        
-        Add simple type inferencing to the parser, and create custom
-        AddNode and LessNode subclasses based on inferred types.
-        http://bugs.webkit.org/show_bug.cgi?id=15884
-        
-        SunSpider claims this is at least a 0.5% speedup.
-
-        * JavaScriptCore.exp:
-        * kjs/grammar.y:
-        * kjs/internal.cpp:
-        (KJS::NumberImp::getPrimitiveNumber):
-        (KJS::GetterSetterImp::getPrimitiveNumber):
-        * kjs/internal.h:
-        * kjs/lexer.cpp:
-        (KJS::Lexer::lex):
-        * kjs/nodes.cpp:
-        (KJS::Node::Node):
-        (KJS::StringNode::evaluate):
-        (KJS::StringNode::evaluateToNumber):
-        (KJS::StringNode::evaluateToBoolean):
-        (KJS::RegExpNode::evaluate):
-        (KJS::UnaryPlusNode::optimizeVariableAccess):
-        (KJS::AddNode::evaluate):
-        (KJS::AddNode::evaluateToNumber):
-        (KJS::AddNumbersNode::inlineEvaluateToNumber):
-        (KJS::AddNumbersNode::evaluate):
-        (KJS::AddNumbersNode::evaluateToNumber):
-        (KJS::AddStringsNode::evaluate):
-        (KJS::AddStringLeftNode::evaluate):
-        (KJS::AddStringRightNode::evaluate):
-        (KJS::lessThan):
-        (KJS::lessThanEq):
-        (KJS::LessNumbersNode::evaluate):
-        (KJS::LessStringsNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::ExpressionNode::):
-        (KJS::RegExpNode::):
-        (KJS::RegExpNode::precedence):
-        (KJS::TypeOfResolveNode::):
-        (KJS::LocalVarTypeOfNode::):
-        (KJS::UnaryPlusNode::):
-        (KJS::UnaryPlusNode::precedence):
-        (KJS::AddNode::):
-        (KJS::AddNode::precedence):
-        (KJS::AddNumbersNode::):
-        (KJS::AddStringLeftNode::):
-        (KJS::AddStringRightNode::):
-        (KJS::AddStringsNode::):
-        (KJS::LessNode::):
-        (KJS::LessNode::precedence):
-        (KJS::LessNumbersNode::):
-        (KJS::LessStringsNode::):
-        * kjs/nodes2string.cpp:
-        (KJS::StringNode::streamTo):
-        * kjs/object.cpp:
-        * kjs/object.h:
-        * kjs/value.h:
-        (KJS::JSValue::getPrimitiveNumber):
-
-2007-11-11  Darin Adler  <darin@apple.com>
-
-        - try another way of fixing dftables builds -- refactor pcre_internal.h a bit
-
-        * pcre/pcre_internal.h: Make most of this header do nothing when DFTABLES is set.
-        Later we can break it into two files.
-
-        * JavaScriptCore.vcproj/dftables/dftables.vcproj: Take out now-unneeded include paths.
-        * pcre/dftables.cpp: Set DFTABLES. Use delete instead of free.
-        * pcre/dftables.pro: Take out now-unneeded include paths.
-        * pcre/pcre_maketables.cpp: Use new instead of malloc.
-
-2007-11-11  Darin Adler  <darin@apple.com>
-
-        * pcre/dftables.pro: Try fixing Qt builds (I looked at qt-win) by adding
-        another include path.
-
-2007-11-11  Darin Adler  <darin@apple.com>
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Try fixing Mac Tiger builds
-        by adding another include path.
-
-2007-11-11  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15924
-          next round of changes to JSRegExp (formerly PCRE)
-
-        This is a combination of converting to C++, tweaking the API, and adding
-        some additional optimizations.
-
-        Future steps will involve getting rid of the use of UTF-8 completely
-        (we'll use UTF-16 exclusively instead), eliminating more source files,
-        and some more speed-ups.
-
-        SunSpider says the current round is an 0.9% speed-up overall, and a
-        5.3% speed-up for regexp.
-
-        * JavaScriptCore.exp: Updated for new entry points.
-
-        * JavaScriptCore.pri:
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.vcproj/dftables/dftables.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * JavaScriptCoreSources.bkl:
-        * jscore.bkl:
-        Updated for new source file names and ForwardingHeaders.
-
-        * kjs/regexp.cpp:
-        (KJS::RegExp::RegExp): Changed to use the error message without calling
-        strdup on it and to pass the new types and options.
-        (KJS::RegExp::~RegExp): Removed the now-unneeded free of the error message.
-        (KJS::RegExp::match): Pass the new types and options.
-        * kjs/regexp.h: Update type of m_constructionError.
-
-        * pcre/AUTHORS: Update to reflect the status of the project -- we don't include
-        the Google parts, and this isn't the PCRE library, per se.
-        * pcre/COPYING: Ditto.
-
-        * pcre/dftables.cpp: Copied from JavaScriptCore/pcre/dftables.c.
-        (main): Removed unneeded ctype_digit.
-
-        * pcre/pcre.h: Convert to C++, tweak API a bit. Use UChar instead of JSRegExpChar.
-
-        * pcre/pcre_compile.cpp: Copied from JavaScriptCore/pcre/pcre_compile.c.
-        Moved a lot of private stuff used only within this file here from pcre_internal.h.
-        Renumbered the error codes.
-        (error_text): Use a single string with embedded nulls for the error text (I got
-        this idea from newer versions of PCRE).
-        (check_escape): Changed return type to be enum instead of int. Replaced ctype_digit
-        uses with isASCIIDigit.
-        (is_counted_repeat): Ditto.
-        (read_repeat_counts): Ditto.
-        (first_significant_code): Ditto.
-        (find_fixedlength): Ditto.
-        (could_be_empty_branch): Ditto.
-        (compile_branch): Ditto. Also removed some code that handles changing options.
-        JavaScript doesn't have any of the features that allow options to change.
-        (compile_regex): Updated for change to options parameter.
-        (is_anchored): Ditto.
-        (find_firstassertedchar): Ditto.
-        (jsRegExpCompile): Changed to take separate flags instead of an options int.
-        Also changed to call new/delete instead of pcre_malloc/free.
-        (jsRegExpFree): Ditto.
-
-        * pcre/pcre_exec.cpp: Copied from JavaScriptCore/pcre/pcre_exec.c.
-        Added a case that uses computed goto for the opcode loop, but did not turn it on.
-        Changed the RMATCH macro to handle returns more efficiently by putting the where
-        pointer in the new frame instead of the old one, allowing us to branch to the
-        return with a single statement. Switched to new/delete from pcre_malloc/free.
-        Changed many RRETURN callers to not set the return value since it's already
-        set correctly. Replaced the rrc variable with an is_match variable. Values other
-        than "match" and "no match" are now handled differently. This allows us to remove
-        the code to check for those cases in various rules.
-        (match): All the case statements use a macro BEGIN_OPCODE instead. And all the
-        continue statements, or break statements that break out of the outer case use
-        a macro NEXT_OPCODE instead. Replaced a few if statements with assertions.
-        (jsRegExpExecute): Use new/delete instead of pcre_malloc/free. Removed unused
-        start_match field from the match block.
-
-        * pcre/pcre_internal.h: Moved the last few configuration macros from pcre-config.h
-        in here. Removed various unused types. Converted from JSRegExpChar to UChar.
-        Eliminated pcre_malloc/free. Replaced the opcode enum with a macro that can be
-        used in multiple places. Unfortunately we lose the comments for each opcode; we
-        should find a place to put those back. Removed ctype_digit.
-
-        * pcre/pcre_maketables.cpp: Copied from JavaScriptCore/pcre/pcre_maketables.c.
-        (pcre_maketables): Got rid of the conditional code that allows this to be compiled
-        in -- it's only used for dftables now (and soon may be obsolete entirely).
-        Changed code for cbit_digit to not use isdigit, and took the "_" case out of the
-        loop. Removed ctype_digit.
-
-        * pcre/pcre_ord2utf8.cpp: Copied from JavaScriptCore/pcre/pcre_ord2utf8.c.
-
-        * pcre/pcre_tables.cpp: Copied from JavaScriptCore/pcre/pcre_tables.c.
-        Moved _pcre_OP_lengths out of here into pcre_exec.cpp.
-
-        * pcre/pcre_ucp_searchfuncs.cpp: Copied from JavaScriptCore/pcre/pcre_ucp_searchfuncs.c.
-        Updated for other file name changes.
-
-        * pcre/pcre_xclass.cpp: Copied from JavaScriptCore/pcre/pcre_xclass.c.
-
-        * pcre/ucpinternal.h: Updated header.
-
-        * pcre/ucptable.cpp: Copied from JavaScriptCore/pcre/ucptable.c.
-
-        * wtf/ASCIICType.h: (WTF::isASCIIDigit): Removed a branch by changing from && to
-        & for this operation. Also added an overload that takes an int because that's
-        useful for PCRE. Later we could optimize for int and overload other functions in
-        this file; stuck to this simple one for now.
-
-        * wtf/unicode/icu/UnicodeIcu.h: Removed unused isUpper.
-        * wtf/unicode/qt4/UnicodeQt4.h: Ditto.
-
-        * pcre/LICENCE: Removed.
-        * pcre/pcre-config.h: Removed.
-        * wtf/FastMallocPCRE.cpp: Removed.
-
-        * pcre/dftables.c: Renamed to cpp.
-        * pcre/pcre_compile.c: Ditto.
-        * pcre/pcre_exec.c: Ditto.
-        * pcre/pcre_maketables.c: Ditto.
-        * pcre/pcre_ord2utf8.c: Ditto.
-        * pcre/pcre_tables.c: Ditto.
-        * pcre/pcre_ucp_searchfuncs.c: Ditto.
-        * pcre/pcre_xclass.c: Ditto.
-        * pcre/ucptable.c: Ditto.
-
-2007-11-11  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Oliver.
-
-        Add KJS_CHECKEXCEPTIONBOOLEAN to match rest of nodes.cpp
-
-        * kjs/nodes.cpp:
-        (KJS::ExpressionNode::evaluateToBoolean):
-        (KJS::LessNode::evaluateToBoolean):
-        (KJS::GreaterNode::evaluateToBoolean):
-        (KJS::LessEqNode::evaluateToBoolean):
-        (KJS::GreaterEqNode::evaluateToBoolean):
-        (KJS::InstanceOfNode::evaluateToBoolean):
-        (KJS::InNode::evaluateToBoolean):
-        (KJS::EqualNode::evaluateToBoolean):
-        (KJS::NotEqualNode::evaluateToBoolean):
-        (KJS::StrictEqualNode::evaluateToBoolean):
-        (KJS::NotStrictEqualNode::evaluateToBoolean):
-        (KJS::LogicalAndNode::evaluateToBoolean):
-        (KJS::LogicalOrNode::evaluateToBoolean):
-        (KJS::ConditionalNode::evaluateToBoolean):
-
-2007-11-10  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15927
-          REGRESSION(r27487): delete a.c followed by __defineGetter__("c", ...) incorrectly deletes another property
-          and <rdar://problem/5586384> REGRESSION (r27487): Can't switch out of Edit HTML Source mode on Leopard Wiki
-
-        Test: fast/js/delete-then-put.html
-
-        * kjs/property_map.cpp:
-        (KJS::PropertyMap::put): Added a missing "- 1"; code to find an empty slot was not working.
-        (KJS::PropertyMap::checkConsistency): Added a missing range check that would have caught this
-        problem before.
-
-        - roll out a last-minute change to my evaluateToBoolean patch that was incorrect.
-
-        * kjs/nodes.h: (KJS::ExprStatementNode::ExprStatementNode): Take out call to
-        optimizeForUnnecessaryResult, since the result is used in some cases.
-
-2007-11-10  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        Roll out some changes that were (seemingly accidentally) checked in
-        with r27664.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2007-11-10  Darin Adler  <darin@apple.com>
-
-        Reviewed by Sam.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15915
-          add an evaluation path for booleans like the one we have for numbers
-
-        Gives 1.1% on SunSpider.
-
-        * kjs/grammar.y: Create TrueNode and FalseNode instead of BooleanNode.
-
-        * kjs/nodes.h: Changed to use Noncopyable. Moved optimizeForUnnecessaryResult
-        down from Node to ExpressionNode. Changed some classes to not inherit from
-        ExpressionNode where not necessary, and removed unnneeded evaluate functions
-        as well as evaluate functions that need not be virtual. Call the
-        optimizeForUnnecessaryResult function on the start of a for loop too.
-        * kjs/nodes.cpp:
-        (KJS::ExpressionNode::evaluateToBoolean): Added.
-        (KJS::FalseNode::evaluate): Added.
-        (KJS::TrueNode::evaluate): Added.
-        (KJS::NumberNode::evaluateToBoolean): Added.
-        (KJS::StringNode::evaluateToBoolean): Added.
-        (KJS::LocalVarAccessNode::evaluateToBoolean): Added.
-        (KJS::BracketAccessorNode::evaluateToBoolean): Added.
-        (KJS::LogicalNotNode::evaluate): Changed to call evaluateToBoolean.
-        (KJS::LogicalNotNode::evaluateToBoolean): Added.
-        (KJS::lessThan): Changed to return bool.
-        (KJS::lessThanEq): Ditto.
-        (KJS::LessNode::evaluate): Changed since lessThan returns bool.
-        (KJS::LessNode::evaluateToBoolean): Added.
-        (KJS::GreaterNode::evaluate): Changed since lessThanEq returns bool.
-        (KJS::GreaterNode::evaluateToBoolean): Added.
-        (KJS::LessEqNode::evaluate): Changed since lessThanEq returns bool.
-        (KJS::LessEqNode::evaluateToBoolean): Added.
-        (KJS::GreaterEqNode::evaluate): Changed since lessThan returns bool.
-        (KJS::GreaterEqNode::evaluateToBoolean): Added.
-        (KJS::InstanceOfNode::evaluateToBoolean): Added.
-        (KJS::InNode::evaluateToBoolean): Added.
-        (KJS::EqualNode::evaluateToBoolean): Added.
-        (KJS::NotEqualNode::evaluateToBoolean): Added.
-        (KJS::StrictEqualNode::evaluateToBoolean): Added.
-        (KJS::NotStrictEqualNode::evaluateToBoolean): Added.
-        (KJS::ConditionalNode::evaluate): Changed to call evaluateToBoolean.
-        (KJS::IfNode::execute): Ditto.
-        (KJS::DoWhileNode::execute): Ditto.
-        (KJS::WhileNode::execute): Ditto.
-        (KJS::ForNode::execute): Ditto.
-
-        * kjs/nodes2string.cpp:
-        (KJS::FalseNode::streamTo): Added.
-        (KJS::TrueNode::streamTo): Added.
-
-2007-11-09  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        Reviewed by Darin.
-
-        * kjs/value.h:
-        (KJS::jsNumber): Add some explicit casts.
-
-2007-11-08  Darin Adler  <darin@apple.com>
-
-        - fix build
-
-        * kjs/grammar.y:
-        * kjs/nodes.h:
-        * kjs/property_map.cpp:
-
-2007-11-08  Darin Adler  <darin@apple.com>
-
-        - roll out accidentally-checked in changes
-
-        * kjs/nodes.cpp: Back to previous version.
-        * kjs/nodes.h: Ditto.
-        * kjs/grammar.y: Ditto.
-
-2007-11-08  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15912
-          fasta spends a lot of time in qsort
-
-        * kjs/property_map.cpp:
-        (KJS::PropertyMap::getEnumerablePropertyNames):
-        Use insertion sort instead of qsort for small sets of property names.
-        We can probably do some even-better speedups of for/in, but this nets
-        0.6% overall and 6.7% on fasta.
-
-2007-11-08  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15906
-          getting characters by indexing into a string is very slow
-
-        This fixes one source of the slowness -- the conversion to an unused
-        Identifier as we call the get function from the slot -- but doesn't
-        fix others, such as the fact that we have to allocate a new UString::Rep
-        for every single character.
-
-        Speeds up string-base64 30%, and at least 0.5% overall.
-        But does slow down access-fannkuch quite a bit. Might be worth
-        revisiting in the future to see what we can do about that (although
-        I did look at a profile for a while).
-
-        * kjs/property_slot.h: Add a new marker for "numeric" property slots;
-        slots where we don't need to pass the identifier to the get function.
-        (KJS::PropertySlot::getValue): Added code to call the numeric get function.
-        (KJS::PropertySlot::setCustomNumeric): Added.
-        * kjs/string_object.cpp:
-        (KJS::StringInstance::indexGetter): Changed to use substr() instead
-        of constructing a wholly new UString each time.
-        (KJS::stringInstanceNumericPropertyGetter): Added. Like indexGetter, but
-        takes advantage of setCustomNumeric to avoid creating an Identifier.
-        (KJS::StringInstance::getOwnPropertySlot): Changed to use setCustomNumeric.
-
-2007-11-08  Darin Adler  <darin@apple.com>
-
-        Reviewed by Oliver.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15904
-          more speed-ups possible by tightening up int version of JSImmediate
-
-        1% improvement of SunSpider
-
-        * kjs/JSImmediate.h: Eliminate the now-unneeded FPBitValues struct template.
-        (KJS::JSImmediate::from): Overload for most numeric types; many types can
-        do fewer branches and checks.
-        (KJS::JSImmediate::getUInt32): Removed unneeded check for undefined.
-        (KJS::JSImmediate::getTruncatedInt32): Ditto.
-        (KJS::JSImmediate::getTruncatedUInt32): Ditto. There's no difference any more
-        between getUInt32 and getTruncatedUInt32, so that's worth a rename and merge later.
-
-        * kjs/grammar.y: Update since fromDouble is now just from.
-        * kjs/nodes.h: Ditto.
-
-        * kjs/value.h: (KJS::jsNumber): Overload for most numeric types.
-
-2007-11-08  Kevin Ollivier  <kevino@theolliviers.com>
-
-        Bakefiles for building JavaScriptCore, needed by wx port.
-
-        Reviewed by Mark Rowe.
-
-        * JavaScriptCoreSources.bkl: Added.
-        * jscore.bkl: Added.
-
-2007-11-08  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Fix regression caused by earlier bitwise and optimisation.  1 & undefined != 1.
-
-        The implementation of JSImmediate::areBothImmediateNumbers relies on 
-        (JSImmediate::getTag(immediate1) & JSImmediate::getTag(immediate2)) having 
-        a unique result when both immediate values are numbers.
-
-        The regression was due to UndefinedType & NumberType returning NumberType (3 & 1).
-        By swapping the value of NumberType and UndefinedType this ceases to be a problem.
-
-        * kjs/JSType.h:
-
-2007-11-08  Darin Adler  <darin@apple.com>
-
-        - fix build
-
-        * kjs/nodes.h: Add missing parameter name.
-
-2007-11-08  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-
-        Add ExpressionNode subclass of Node, use it.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::ForInNode::ForInNode):
-        * kjs/nodes.h:
-        (KJS::ExpressionNode::):
-        (KJS::NullNode::):
-        (KJS::NullNode::precedence):
-        (KJS::BooleanNode::):
-        (KJS::BooleanNode::precedence):
-        (KJS::RegExpNode::):
-        (KJS::RegExpNode::precedence):
-        (KJS::ThisNode::):
-        (KJS::ThisNode::precedence):
-        (KJS::ResolveNode::):
-        (KJS::ElementNode::):
-        (KJS::ArrayNode::):
-        (KJS::PropertyNode::):
-        (KJS::PropertyNode::precedence):
-        (KJS::PropertyNode::name):
-        (KJS::PropertyListNode::):
-        (KJS::ObjectLiteralNode::):
-        (KJS::ObjectLiteralNode::precedence):
-        (KJS::BracketAccessorNode::):
-        (KJS::DotAccessorNode::):
-        (KJS::DotAccessorNode::precedence):
-        (KJS::ArgumentListNode::):
-        (KJS::ArgumentsNode::):
-        (KJS::NewExprNode::):
-        (KJS::NewExprNode::precedence):
-        (KJS::FunctionCallValueNode::):
-        (KJS::FunctionCallValueNode::precedence):
-        (KJS::FunctionCallResolveNode::):
-        (KJS::FunctionCallBracketNode::):
-        (KJS::FunctionCallBracketNode::precedence):
-        (KJS::FunctionCallDotNode::):
-        (KJS::FunctionCallDotNode::precedence):
-        (KJS::PrePostResolveNode::):
-        (KJS::PostfixBracketNode::):
-        (KJS::PostfixBracketNode::precedence):
-        (KJS::PostIncBracketNode::):
-        (KJS::PostIncBracketNode::isIncrement):
-        (KJS::PostDecBracketNode::):
-        (KJS::PostDecBracketNode::isIncrement):
-        (KJS::PostfixDotNode::):
-        (KJS::PostfixDotNode::precedence):
-        (KJS::PostIncDotNode::):
-        (KJS::PostIncDotNode::isIncrement):
-        (KJS::PostDecDotNode::):
-        (KJS::PostDecDotNode::isIncrement):
-        (KJS::PostfixErrorNode::):
-        (KJS::PostfixErrorNode::precedence):
-        (KJS::DeleteResolveNode::):
-        (KJS::DeleteBracketNode::):
-        (KJS::DeleteBracketNode::precedence):
-        (KJS::DeleteDotNode::):
-        (KJS::DeleteDotNode::precedence):
-        (KJS::DeleteValueNode::):
-        (KJS::DeleteValueNode::precedence):
-        (KJS::VoidNode::):
-        (KJS::VoidNode::precedence):
-        (KJS::TypeOfResolveNode::):
-        (KJS::TypeOfValueNode::):
-        (KJS::PrefixBracketNode::):
-        (KJS::PrefixBracketNode::precedence):
-        (KJS::PreIncBracketNode::):
-        (KJS::PreIncBracketNode::isIncrement):
-        (KJS::PreDecBracketNode::):
-        (KJS::PreDecBracketNode::isIncrement):
-        (KJS::PrefixDotNode::):
-        (KJS::PrefixDotNode::precedence):
-        (KJS::PreIncDotNode::):
-        (KJS::PreIncDotNode::isIncrement):
-        (KJS::PreDecDotNode::):
-        (KJS::PreDecDotNode::isIncrement):
-        (KJS::PrefixErrorNode::):
-        (KJS::PrefixErrorNode::precedence):
-        (KJS::UnaryPlusNode::):
-        (KJS::UnaryPlusNode::precedence):
-        (KJS::NegateNode::):
-        (KJS::NegateNode::precedence):
-        (KJS::BitwiseNotNode::):
-        (KJS::BitwiseNotNode::precedence):
-        (KJS::LogicalNotNode::):
-        (KJS::LogicalNotNode::precedence):
-        (KJS::AddNode::):
-        (KJS::AddNode::precedence):
-        (KJS::LeftShiftNode::):
-        (KJS::LeftShiftNode::precedence):
-        (KJS::RightShiftNode::):
-        (KJS::RightShiftNode::precedence):
-        (KJS::UnsignedRightShiftNode::):
-        (KJS::UnsignedRightShiftNode::precedence):
-        (KJS::LessNode::):
-        (KJS::LessNode::precedence):
-        (KJS::GreaterNode::):
-        (KJS::GreaterNode::precedence):
-        (KJS::LessEqNode::):
-        (KJS::LessEqNode::precedence):
-        (KJS::GreaterEqNode::):
-        (KJS::GreaterEqNode::precedence):
-        (KJS::InstanceOfNode::):
-        (KJS::InstanceOfNode::precedence):
-        (KJS::InNode::):
-        (KJS::InNode::precedence):
-        (KJS::EqualNode::):
-        (KJS::EqualNode::precedence):
-        (KJS::NotEqualNode::):
-        (KJS::NotEqualNode::precedence):
-        (KJS::StrictEqualNode::):
-        (KJS::StrictEqualNode::precedence):
-        (KJS::NotStrictEqualNode::):
-        (KJS::NotStrictEqualNode::precedence):
-        (KJS::BitAndNode::):
-        (KJS::BitAndNode::precedence):
-        (KJS::BitOrNode::):
-        (KJS::BitOrNode::precedence):
-        (KJS::BitXOrNode::):
-        (KJS::BitXOrNode::precedence):
-        (KJS::LogicalAndNode::):
-        (KJS::LogicalAndNode::precedence):
-        (KJS::LogicalOrNode::):
-        (KJS::LogicalOrNode::precedence):
-        (KJS::ConditionalNode::):
-        (KJS::ConditionalNode::precedence):
-        (KJS::ReadModifyResolveNode::):
-        (KJS::ReadModifyResolveNode::precedence):
-        (KJS::AssignResolveNode::):
-        (KJS::AssignResolveNode::precedence):
-        (KJS::ReadModifyBracketNode::):
-        (KJS::ReadModifyBracketNode::precedence):
-        (KJS::AssignBracketNode::):
-        (KJS::AssignBracketNode::precedence):
-        (KJS::AssignDotNode::):
-        (KJS::AssignDotNode::precedence):
-        (KJS::ReadModifyDotNode::):
-        (KJS::ReadModifyDotNode::precedence):
-        (KJS::AssignErrorNode::):
-        (KJS::AssignErrorNode::precedence):
-        (KJS::CommaNode::):
-        (KJS::CommaNode::precedence):
-        (KJS::AssignExprNode::):
-        (KJS::AssignExprNode::precedence):
-        (KJS::ExprStatementNode::):
-        (KJS::IfNode::):
-        (KJS::DoWhileNode::):
-        (KJS::WhileNode::):
-        (KJS::ReturnNode::):
-        (KJS::WithNode::):
-        (KJS::ThrowNode::):
-        (KJS::ParameterNode::):
-        (KJS::CaseClauseNode::):
-        (KJS::CaseClauseNode::precedence):
-        (KJS::ClauseListNode::):
-        (KJS::SwitchNode::):
-
-2007-11-08  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Sam.
-
-        Add a fast path for bitwise-and of two immediate numbers for a 0.7% improvement in SunSpider (4% bitop improvement).
-
-        This only improves bitwise-and performance, as the additional logic required 
-        for similar code paths on or, xor, and shifting requires additional operations
-        and branches that negate (and in certain cases, regress) any advantage we might
-        otherwise receive.
-
-        This improves performance on all bitop tests, the cryptography tests, as well as 
-        the string-base64 and string-unpack-code tests.  No significant degradation on 
-        any other tests.
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::areBothImmediateNumbers):
-        (KJS::JSImmediate::andImmediateNumbers):
-        * kjs/nodes.cpp:
-        (KJS::BitAndNode::evaluate):
-        * kjs/value.h:
-        (KJS::jsNumberFromAnd):
-
-2007-11-08  Adam Roben  <aroben@apple.com>
-
-        Stop using KJS inside of MathExtras.h
-
-        Reviewed by Darin.
-
-        * wtf/MathExtras.h: Removed an unused header, and a now-unused
-        forward-declaration.
-        (wtf_atan2): Use std::numeric_limits intead of KJS.
-
-2007-11-08  Sam Weinig  <sam@webkit.org>
-
-        Windows build fix.
-
-        * kjs/date_object.cpp:
-        (KJS::DateProtoFuncToLocaleString::callAsFunction): Fix unused arg warning.
-        (KJS::DateProtoFuncToLocaleDateString::callAsFunction): ditto
-        (KJS::DateProtoFuncToLocaleTimeString::callAsFunction): ditto
-
-2007-11-08  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/lookup.h: Add missing include.
-
-2007-11-08  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Darin.
-
-        Convert JavaScript internal function objects to use one class per
-        function.  This avoids a switch statement inside what used to be
-        the shared function classes and will allow Shark to better analyze
-        the code.
-
-        To make this switch, the value property of the HashEntry was changed
-        to a union of an intptr_t (which is used to continue handle valueGetters)
-        and function pointer which points to a static constructor for the
-        individual new function objects.
-
-        SunSpider claims this is a 1.0% speedup.
-
-        * kjs/array_object.cpp:
-        (KJS::ArrayPrototype::getOwnPropertySlot):
-        (KJS::getProperty):
-        (KJS::ArrayProtoFuncToString::callAsFunction):
-        (KJS::ArrayProtoFuncToLocaleString::callAsFunction):
-        (KJS::ArrayProtoFuncJoin::callAsFunction):
-        (KJS::ArrayProtoFuncConcat::callAsFunction):
-        (KJS::ArrayProtoFuncPop::callAsFunction):
-        (KJS::ArrayProtoFuncPush::callAsFunction):
-        (KJS::ArrayProtoFuncReverse::callAsFunction):
-        (KJS::ArrayProtoFuncShift::callAsFunction):
-        (KJS::ArrayProtoFuncSlice::callAsFunction):
-        (KJS::ArrayProtoFuncSort::callAsFunction):
-        (KJS::ArrayProtoFuncSplice::callAsFunction):
-        (KJS::ArrayProtoFuncUnShift::callAsFunction):
-        (KJS::ArrayProtoFuncFilter::callAsFunction):
-        (KJS::ArrayProtoFuncMap::callAsFunction):
-        (KJS::ArrayProtoFuncEvery::callAsFunction):
-        (KJS::ArrayProtoFuncForEach::callAsFunction):
-        (KJS::ArrayProtoFuncSome::callAsFunction):
-        (KJS::ArrayProtoFuncIndexOf::callAsFunction):
-        (KJS::ArrayProtoFuncLastIndexOf::callAsFunction):
-        * kjs/array_object.h:
-        (KJS::ArrayPrototype::classInfo):
-        * kjs/create_hash_table:
-        * kjs/date_object.cpp:
-        (KJS::DatePrototype::getOwnPropertySlot):
-        (KJS::DateProtoFuncToString::callAsFunction):
-        (KJS::DateProtoFuncToUTCString::callAsFunction):
-        (KJS::DateProtoFuncToDateString::callAsFunction):
-        (KJS::DateProtoFuncToTimeString::callAsFunction):
-        (KJS::DateProtoFuncToLocaleString::callAsFunction):
-        (KJS::DateProtoFuncToLocaleDateString::callAsFunction):
-        (KJS::DateProtoFuncToLocaleTimeString::callAsFunction):
-        (KJS::DateProtoFuncValueOf::callAsFunction):
-        (KJS::DateProtoFuncGetTime::callAsFunction):
-        (KJS::DateProtoFuncGetFullYear::callAsFunction):
-        (KJS::DateProtoFuncGetUTCFullYear::callAsFunction):
-        (KJS::DateProtoFuncToGMTString::callAsFunction):
-        (KJS::DateProtoFuncGetMonth::callAsFunction):
-        (KJS::DateProtoFuncGetUTCMonth::callAsFunction):
-        (KJS::DateProtoFuncGetDate::callAsFunction):
-        (KJS::DateProtoFuncGetUTCDate::callAsFunction):
-        (KJS::DateProtoFuncGetDay::callAsFunction):
-        (KJS::DateProtoFuncGetUTCDay::callAsFunction):
-        (KJS::DateProtoFuncGetHours::callAsFunction):
-        (KJS::DateProtoFuncGetUTCHours::callAsFunction):
-        (KJS::DateProtoFuncGetMinutes::callAsFunction):
-        (KJS::DateProtoFuncGetUTCMinutes::callAsFunction):
-        (KJS::DateProtoFuncGetSeconds::callAsFunction):
-        (KJS::DateProtoFuncGetUTCSeconds::callAsFunction):
-        (KJS::DateProtoFuncGetMilliSeconds::callAsFunction):
-        (KJS::DateProtoFuncGetUTCMilliseconds::callAsFunction):
-        (KJS::DateProtoFuncGetTimezoneOffset::callAsFunction):
-        (KJS::DateProtoFuncSetTime::callAsFunction):
-        (KJS::DateProtoFuncSetMilliSeconds::callAsFunction):
-        (KJS::DateProtoFuncSetUTCMilliseconds::callAsFunction):
-        (KJS::DateProtoFuncSetSeconds::callAsFunction):
-        (KJS::DateProtoFuncSetUTCSeconds::callAsFunction):
-        (KJS::DateProtoFuncSetMinutes::callAsFunction):
-        (KJS::DateProtoFuncSetUTCMinutes::callAsFunction):
-        (KJS::DateProtoFuncSetHours::callAsFunction):
-        (KJS::DateProtoFuncSetUTCHours::callAsFunction):
-        (KJS::DateProtoFuncSetDate::callAsFunction):
-        (KJS::DateProtoFuncSetUTCDate::callAsFunction):
-        (KJS::DateProtoFuncSetMonth::callAsFunction):
-        (KJS::DateProtoFuncSetUTCMonth::callAsFunction):
-        (KJS::DateProtoFuncSetFullYear::callAsFunction):
-        (KJS::DateProtoFuncSetUTCFullYear::callAsFunction):
-        (KJS::DateProtoFuncSetYear::callAsFunction):
-        (KJS::DateProtoFuncGetYear::callAsFunction):
-        * kjs/date_object.h:
-        * kjs/lookup.cpp:
-        (KJS::Lookup::find):
-        * kjs/lookup.h:
-        (KJS::HashEntry::):
-        (KJS::staticFunctionGetter):
-        (KJS::staticValueGetter):
-        (KJS::getStaticPropertySlot):
-        (KJS::getStaticFunctionSlot):
-        (KJS::lookupPut):
-        * kjs/math_object.cpp:
-        (KJS::MathObjectImp::getOwnPropertySlot):
-        (KJS::MathProtoFuncAbs::callAsFunction):
-        (KJS::MathProtoFuncACos::callAsFunction):
-        (KJS::MathProtoFuncASin::callAsFunction):
-        (KJS::MathProtoFuncATan::callAsFunction):
-        (KJS::MathProtoFuncATan2::callAsFunction):
-        (KJS::MathProtoFuncCeil::callAsFunction):
-        (KJS::MathProtoFuncCos::callAsFunction):
-        (KJS::MathProtoFuncExp::callAsFunction):
-        (KJS::MathProtoFuncFloor::callAsFunction):
-        (KJS::MathProtoFuncLog::callAsFunction):
-        (KJS::MathProtoFuncMax::callAsFunction):
-        (KJS::MathProtoFuncMin::callAsFunction):
-        (KJS::MathProtoFuncPow::callAsFunction):
-        (KJS::MathProtoFuncRandom::callAsFunction):
-        (KJS::MathProtoFuncRound::callAsFunction):
-        (KJS::MathProtoFuncSin::callAsFunction):
-        (KJS::MathProtoFuncSqrt::callAsFunction):
-        (KJS::MathProtoFuncTan::callAsFunction):
-        * kjs/math_object.h:
-        (KJS::MathObjectImp::classInfo):
-        (KJS::MathObjectImp::):
-        * kjs/string_object.cpp:
-        (KJS::StringPrototype::getOwnPropertySlot):
-        (KJS::StringProtoFuncToString::callAsFunction):
-        (KJS::StringProtoFuncValueOf::callAsFunction):
-        (KJS::StringProtoFuncCharAt::callAsFunction):
-        (KJS::StringProtoFuncCharCodeAt::callAsFunction):
-        (KJS::StringProtoFuncConcat::callAsFunction):
-        (KJS::StringProtoFuncIndexOf::callAsFunction):
-        (KJS::StringProtoFuncLastIndexOf::callAsFunction):
-        (KJS::StringProtoFuncMatch::callAsFunction):
-        (KJS::StringProtoFuncSearch::callAsFunction):
-        (KJS::StringProtoFuncReplace::callAsFunction):
-        (KJS::StringProtoFuncSlice::callAsFunction):
-        (KJS::StringProtoFuncSplit::callAsFunction):
-        (KJS::StringProtoFuncSubstr::callAsFunction):
-        (KJS::StringProtoFuncSubstring::callAsFunction):
-        (KJS::StringProtoFuncToLowerCase::callAsFunction):
-        (KJS::StringProtoFuncToUpperCase::callAsFunction):
-        (KJS::StringProtoFuncToLocaleLowerCase::callAsFunction):
-        (KJS::StringProtoFuncToLocaleUpperCase::callAsFunction):
-        (KJS::StringProtoFuncLocaleCompare::callAsFunction):
-        (KJS::StringProtoFuncBig::callAsFunction):
-        (KJS::StringProtoFuncSmall::callAsFunction):
-        (KJS::StringProtoFuncBlink::callAsFunction):
-        (KJS::StringProtoFuncBold::callAsFunction):
-        (KJS::StringProtoFuncFixed::callAsFunction):
-        (KJS::StringProtoFuncItalics::callAsFunction):
-        (KJS::StringProtoFuncStrike::callAsFunction):
-        (KJS::StringProtoFuncSub::callAsFunction):
-        (KJS::StringProtoFuncSup::callAsFunction):
-        (KJS::StringProtoFuncFontcolor::callAsFunction):
-        (KJS::StringProtoFuncFontsize::callAsFunction):
-        (KJS::StringProtoFuncAnchor::callAsFunction):
-        (KJS::StringProtoFuncLink::callAsFunction):
-        * kjs/string_object.h:
-
-2007-11-08  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        Reviewed by Sam and Ada.
-
-        * wtf/MathExtras.h: Get rid of a circular #include dependency to fix
-        the build.
-
-2007-11-08  Adam Roben  <aroben@apple.com>
-
-        Fix a precedence warning on Windows
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::toBoolean):
-
-2007-11-08  Mark Rowe  <mrowe@apple.com>
-
-        Build fix for JavaScriptGlue.
-
-        * wtf/MathExtras.h: Include stdlib.h for srand and RAND_MAX.
-
-2007-11-08  Darin Adler  <darin@apple.com>
-
-        - Windows build fix
-
-        * kjs/JSImmediate.h: Include MathExtras.h rather than math.h since this file uses "signbit".
-
-2007-11-08  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Darin.
-
-        Replace the use of floats for immediate values with the use of integers for a 4.5% improvement in SunSpider.
-
-        Unfortunately this change results in NaN, +Inf, -Inf, and -0 being heap allocated now, but
-        we should now have faster array access, faster immediate to double conversion, and the 
-        potential to further improve bitwise operators in future.
-
-        This also removes the need for unions to avoid strict aliasing problems when extracting 
-        a value from immediates.
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::trueImmediate):
-        (KJS::JSImmediate::falseImmediate):
-        (KJS::JSImmediate::undefinedImmediate):
-        (KJS::JSImmediate::nullImmediate):
-        (KJS::JSImmediate::toBoolean):
-        * kjs/value.h:
-        (KJS::jsNaN):
-
-2007-11-07  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Darin and Oliver.
-        
-        Add evaluateToNumber parallel evaluation tree to speed up number operations.
-        Make ImmediateNumberNode a subclass of NumberNode.
-        Share evaluate logic between evaluate and evaluateToNumber using inline functions
-        There is still a lot of improvement to be made here.
-        
-        SunSpider claims this is a 1.0% speedup overall (nbody 7.9%), base64 slowing 2.0%
-        Given the huge win that this prepares us for with simple type inferencing I see the small
-        regression in base64 being worth the substantial overall improvement.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::Node::evaluateToNumber):
-        (KJS::NumberNode::evaluate):
-        (KJS::NumberNode::evaluateToNumber):
-        (KJS::StringNode::evaluateToNumber):
-        (KJS::LocalVarAccessNode::inlineEvaluate):
-        (KJS::LocalVarAccessNode::evaluate):
-        (KJS::LocalVarAccessNode::evaluateToNumber):
-        (KJS::BracketAccessorNode::inlineEvaluate):
-        (KJS::BracketAccessorNode::evaluate):
-        (KJS::BracketAccessorNode::evaluateToNumber):
-        (KJS::NegateNode::evaluate):
-        (KJS::NegateNode::evaluateToNumber):
-        (KJS::MultNode::inlineEvaluateToNumber):
-        (KJS::MultNode::evaluate):
-        (KJS::MultNode::evaluateToNumber):
-        (KJS::DivNode::inlineEvaluateToNumber):
-        (KJS::DivNode::evaluate):
-        (KJS::DivNode::evaluateToNumber):
-        (KJS::ModNode::inlineEvaluateToNumber):
-        (KJS::ModNode::evaluate):
-        (KJS::ModNode::evaluateToNumber):
-        (KJS::throwOutOfMemoryErrorToNumber):
-        (KJS::addSlowCaseToNumber):
-        (KJS::add):
-        (KJS::addToNumber):
-        (KJS::AddNode::evaluateToNumber):
-        (KJS::SubNode::inlineEvaluateToNumber):
-        (KJS::SubNode::evaluate):
-        (KJS::SubNode::evaluateToNumber):
-        (KJS::valueForReadModifyAssignment):
-        (KJS::ReadModifyLocalVarNode::evaluate):
-        (KJS::ReadModifyResolveNode::evaluate):
-        (KJS::ReadModifyDotNode::evaluate):
-        (KJS::ReadModifyBracketNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::Node::):
-        (KJS::NumberNode::):
-        (KJS::ImmediateNumberNode::):
-        (KJS::AddNode::precedence):
-        * kjs/nodes2string.cpp:
-        (KJS::NumberNode::streamTo):
-
-2007-11-07  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Eric.
-
-        Fix up initialization after being mangled in r27572, and remove the
-        ternary expression as extraCost will always be zero for the numeric
-        heap.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::heapAllocate):
-
-2007-11-07  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/regexp_object.cpp:
-
-2007-11-07  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Beth Dakin.
-        
-        Eliminated a bogus (though compiled-out) branch in the collector.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::heapAllocate):
-
-2007-11-06  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Fixed part of http://bugs.webkit.org/show_bug.cgi?id=15861 
-        5.8% of string-validate-input.js is spent creating RegExpImps
-
-        Put RegExpImp properties into a static hashtable to avoid a slew of
-        PropertyMap churn when creating a RegExpImp.
-        
-        Factored important bits of regular expression implementation out of
-        RegExpImp (the JS object) and into RegExp (the PCRE wrapper class), 
-        making RegExp a ref-counted class. (This will help later.)
-
-        Removed PCRE_POSIX support because I didn't quite know how to test it 
-        and keep it working with these changes.
-        
-        1.1% SunSpider speedup. 5.8% speedup on string-validate-input.js.
-
-        * kjs/regexp.h: A few interface changes:
-        1. Renamed "subpatterns()" => "numSubpatterns()"
-        2. Made flag enumeration private and replaced it with public getters for
-        specific flags.
-        3. Made RegExp ref-counted so RegExps can be shared by RegExpImps.
-        4. Made RegExp take a string of flags instead of an int, eliminating 
-        duplicated flag parsing code elsewhere.
-
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpProtoFunc::callAsFunction): For RegExp.compile: 
-        - Fixed a bug where compile(undefined) would throw an exception. 
-        - Removed some now-redundant code.
-        - Used RegExp sharing to eliminate an allocation and a bunch of 
-        PropertyMap thrash. (Not a big win since compile is a deprecated 
-        function. I mainly did this to test the plubming.)
-
-2007-11-07  Simon Hausmann  <hausmann@kde.org>
-
-        Reviewed by nobody, Qt/Windows build fix.
-
-        JavaScriptCore.pri expects OBJECTS_DIR to be set, so set it in
-        testkjs.pro, too, where it's included from.
-
-        * kjs/testkjs.pro:
-
-2007-11-07  Simon Hausmann  <shausman@trolltech.com>
-
-        Reviewed by Lars.
-
-        Fix "nmake clean" for the Qt/Windows build by replacing tmp/ with a variable that ends with the correct type of slash/backslash depending on the choice of compiler/make tool.
-
-        * JavaScriptCore.pri:
-        * pcre/pcre.pri:
-
-2007-11-07  Lars Knoll  <lars@trolltech.com>
-
-        Reviewed by Simon.
-
-        fix umemcasecmp
-        
-        Pretty embarrassing bug. Has the potential to fix quite a few test failures.
-
-        * wtf/unicode/qt4/UnicodeQt4.h:
-        (WTF::Unicode::umemcasecmp):
-
-2007-11-06  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Eric.        
-        
-        - only collect when the heap is full, unless we have lots of extra cost garbage
-        
-        1.1% SunSpider speedup.
-        
-        This shouldn't hit memory use much since the extra space in those
-        blocks hangs around either way.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::heapAllocate):
-        (KJS::Collector::collect): Fix logic error that reversed the sense of collect's 
-        return value.
-
-2007-11-06  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Avoid unnecessarily boxing the result from post inc/decrement for 0.3% gain in sunspider
-        
-        We now convert the common 'for (...; ...; <var>++) ...' to the semantically identical
-        'for (...; ...; ++<var>) ...'.
-
-        * kjs/nodes.cpp:
-        (KJS::PostIncResolveNode::optimizeForUnnecessaryResult):
-        (KJS::PostIncLocalVarNode::evaluate):
-        (KJS::PostIncLocalVarNode::optimizeForUnnecessaryResult):
-        (KJS::PostDecResolveNode::optimizeForUnnecessaryResult):
-        (KJS::PostDecLocalVarNode::evaluate):
-        (KJS::PostDecLocalVarNode::optimizeForUnnecessaryResult):
-        * kjs/nodes.h:
-        (KJS::PrePostResolveNode::):
-        (KJS::PostIncResolveNode::):
-        (KJS::PostIncLocalVarNode::):
-        (KJS::PostDecResolveNode::):
-        (KJS::PostDecLocalVarNode::):
-        (KJS::PreIncResolveNode::):
-        (KJS::PreDecResolveNode::):
-        (KJS::ForNode::ForNode):
-
-2007-11-06  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-
-        This fixes a regressed layout test for string + object
-        
-        SunSpider claims this was an overall 0.3% speedup, although some individual tests were slower.
-
-        * kjs/nodes.cpp:
-        (KJS::add): remove erroneous "fast path" for string + *
-
-2007-11-06  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Eric Seidel.
-        
-        Added toJSNumber, a fast path for converting a JSValue to a JS number,
-        and deployed it in postfix expressions. In the fast case this 
-        eliminates a call to jsNumber.
-        
-        0.4% speedup on SunSpider.
-
-        * ChangeLog:
-        * kjs/nodes.cpp:
-        (KJS::PostIncResolveNode::evaluate):
-        (KJS::PostIncLocalVarNode::evaluate):
-        (KJS::PostDecResolveNode::evaluate):
-        (KJS::PostDecLocalVarNode::evaluate):
-        (KJS::PostIncBracketNode::evaluate):
-        (KJS::PostDecBracketNode::evaluate):
-        (KJS::PostIncDotNode::evaluate):
-        (KJS::PostDecDotNode::evaluate):
-        (KJS::UnaryPlusNode::evaluate):
-        * kjs/value.h:
-        (KJS::JSValue::toJSNumber):
-
-2007-11-06  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15846
-          REGRESSION (r27387): Memory corruption when running fast/js/kde/delete.html
-
-        There was a mistake in the algorithm used to find an empty slot in the property
-        map entries vector; when we were putting in a new property value and not overwriting
-        an existing deleted sentinel, we would enlarge the entries vector, but would not
-        overwrite the stale data that's in the new part. It was easy to pin this down by
-        turning on property map consistency checks -- I never would have landed with this
-        bug if I had run the regression tests once with consistency checks on!
-
-        * kjs/property_map.cpp: (KJS::PropertyMap::put): Changed logic for the case where
-        foundDeletedElement is false to always use the item at the end of the entries vector.
-        Also allowed me to merge with the logic for the "no deleted sentinels at all" case.
-
-2007-11-06  Oliver Hunt  <oliver@apple.com>
-
-        RS=Darin.
-
-        Fix previous patch to use a 3 bit shift, a 16 bit shift causes a regression in sunspider.
-
-        * kjs/nodes.cpp:
-        (KJS::add):
-
-2007-11-06  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Darin.
-
-        Replace boolean comparisons in AddNode with mask
-        comparisons for a 0.2% improvement in sunspider.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/nodes.cpp:
-        (KJS::add):
-
-2007-11-06  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-        
-        SunSpider claims this is a 1.1% speedup.
-
-        * kjs/nodes.cpp:
-        (KJS::throwOutOfMemoryError): Added, non inline.
-        (KJS::addSlowCase): renamed from add(), non inline.
-        (KJS::add): add fast path for String + String, Number + Number and String + *
-
-2007-11-06  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by mjs.
-        
-        Avoid more UString creation.
-        
-        SunSpider claims this is a 0.4% speedup.
-
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpObjectImp::construct): use UString::find(UChar)
-
-2007-11-05  Mark Rowe  <mrowe@apple.com>
-
-        Mac build fix.
-
-        * kjs/array_object.cpp:
-        (KJS::ArrayProtoFunc::callAsFunction):
-
-2007-11-05  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * kjs/list.h:
-
-2007-11-05  Mark Rowe  <mrowe@apple.com>
-
-        Build fix.  Add missing #include.
-
-        * kjs/operations.cpp:
-
-2007-11-05  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by mjs.
-        
-        Remove another call to toString(exec)
-        
-        SunSpider claims this is a 0.5% speedup.
-
-        * kjs/operations.cpp:
-        (KJS::equal): remove another toString
-
-2007-11-05  Eric Seidel  <eric@webkit.org>
-
-        * kjs/operations.cpp:
-        (KJS::equal): correct broken change.
-
-2007-11-05  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by mjs.
-
-        Remove one more call to toString(exec).
-        
-        SunSpider claims this is a 0.7% speedup.
-
-        * kjs/operations.cpp:
-        (KJS::equal): remove a call to toString()
-
-2007-11-05  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * pcre/pcre.pri:
-
-2007-11-05  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/list.cpp:
-
-2007-11-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Touched a file to test my new HTTP access.
-
-        * kjs/scope_chain.cpp:
-
-2007-11-05  Alp Toker  <alp@atoker.com>
-
-        Unreviewed build fix for qmake-based ports.
-
-        Someone with a better understanding of qmake still needs to sort out
-        the INCLUDEPATH/DEPENDPATH mess.
-
-        * JavaScriptCore.pri:
-
-2007-11-05  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        http://bugs.webkit.org/show_bug.cgi?id=15835
-
-        Switched List implementation from a custom heap allocator to an inline
-        Vector, for a disappointing .5% SunSpider speedup.
-        
-        Also renamed List::slice to List::getSlice because "get" is the 
-        conventional prefix for functions returning a value through an out 
-        parameter.
-
-        * kjs/array_object.cpp:
-        (KJS::ArrayProtoFunc::callAsFunction): Removed some redundant function
-        calls and memory accesses.
-
-        * kjs/bool_object.cpp:
-        (BooleanObjectImp::construct): Removed questionable use of iterator.
-
-        * kjs/list.cpp:
-        * kjs/list.h: New List class, implemented in terms of Vector. Two 
-        interesting differences:
-            1. The inline capacity is 8, not 5. Many of the Lists constructed 
-            during a SunSpider run are larger than 5; almost none are larger
-            than 8.
-
-            2. The growth factor is 4, not 2. Since we can guarantee that Lists
-            aren't long-lived, we can grow them more aggressively, to avoid
-            excessive copying.
-
-        * kjs/regexp_object.cpp:
-        (RegExpObjectImp::construct): Removed redundant function calls.
-
-        * kjs/string_object.cpp:
-        (KJS::StringObjectImp::construct): Removed questionable use of iterator.
-
-        * wtf/Vector.h:
-        (WTF::::uncheckedAppend): Added a fast, unchecked version of append.
-
-2007-11-05  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Alp Toker.
-
-        Add DEPENDPATH to JavaScriptCore and pcre to help qmake with dependencies.
-
-        * JavaScriptCore.pri:
-        * pcre/pcre.pri:
-
-2007-11-04  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15826
-          optimize opcode loop and case insensitive ASCII compares for a 30% speedup
-
-        SunSpider says it's 2.6% faster overall, 32.5% in the regular expression tests.
-
-        * pcre/pcre_internal.h: Added OP_ASCII_CHAR and OP_ASCII_LETTER_NC.
-
-        * pcre/pcre_compile.c:
-        (find_fixedlength): Added cases for OP_ASCII_CHAR and OP_ASCII_LETTER_NC. Also
-        added OP_NOT since there was no reason it should not be in here.
-        (could_be_empty_branch): Ditto.
-        (compile_branch): Streamlined all the single-character cases; there was a bit of
-        duplicate code. Added cases for OP_ASCII_CHAR and OP_ASCII_LETTER_NC as needed.
-        But in particular, compile to those opcodes when the single character match is
-        ASCII.
-        (find_firstassertedchar): Added cases for OP_ASCII_CHAR and OP_ASCII_LETTER_NC.
-
-        * pcre/pcre_exec.c: (match): Removed the "min", "minimize", and "op" fields from
-        the matchframe, after I discovered that none of them needed to be saved and restored
-        across recursive match calls. Also eliminated the ignored result field from the
-        matchframe, since I discovered that rrc ("recursive result code") was already the
-        exact same thing. Moved the handling of opcodes higher than OP_BRA into the default
-        statement of the switch instead of doing them before the switch. This removes a
-        branch from each iteration of the opcode interpreter, just as removal of "op"
-        removed at least one store from each iteration. Last, but not least, add the
-        OP_ASCII_CHAR and OP_ASCII_LETTER_NC functions. Neither can ever match a
-        surrogate pair and the letter case can be handled efficiently.
-
-2007-11-04  Darin Adler  <darin@apple.com>
-
-        * pcre/pcre_exec.c: (match): Try to fix the Windows build by removing unreachable code.
-
-2007-11-03  Darin Adler  <darin@apple.com>
-
-        - fix non-Mac builds; remove some more unused PCRE stuff
-
-        * pcre/pcre_compile.c:
-        (compile_branch): Removed branch chain and some unused ESC values.
-        (compile_regex): Ditto.
-        (jsRegExpCompile): Ditto.
-        * pcre/pcre_exec.c:
-        (match): Removed unused branch targets. Don't use macros any more.
-        (jsRegExpExecute): More of the same.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Update for removed files.
-        * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
-        * pcre/pcre.pri: Ditto.
-
-        * pcre/MERGING: Removed.
-        * pcre/pcre_fullinfo.c: Removed.
-        * pcre/pcre_get.c: Removed.
-        * pcre/pcre_internal.h:
-        * pcre/ucp.h: Removed.
-
-2007-11-03  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15821
-          remove unused PCRE features for speed
-
-        A first step toward removing the PCRE features we don't use.
-        This gives a 0.8% speedup on SunSpider, and a 6.5% speedup on
-        the SunSpider regular expression test.
-
-        Replaced the public interface with one that doesn't use the
-        name PCRE. Removed code we don't need for JavaScript and various
-        configurations we don't use. This is in preparation for still
-        more changes in the future. We'll probably switch to C++ and
-        make some even more significant changes to the regexp engine
-        to get some additional speed.
-
-        There's probably additional unused stuff that I haven't
-        deleted yet.
-
-        This does mean that our PCRE is now a fork, but I think that's
-        not really a big deal.
-
-        * JavaScriptCore.exp: Remove the 5 old entry points and add
-        the 3 new entry points for WebCore's direct use of the regular
-        expression engine.
-
-        * kjs/config.h: Remove the USE(PCRE16) define. I decided to flip
-        its sense and now there's a USE(POSIX_REGEX) instead, which should
-        probably not be set by anyone. Maybe later we'll just get rid of it
-        altogether.
-
-        * kjs/regexp.h:
-        * kjs/regexp.cpp:
-        (KJS::RegExp::RegExp): Switch to new jsRegExp function names and
-        defines. Cut down on the number of functions used.
-        (KJS::RegExp::~RegExp): Ditto.
-        (KJS::RegExp::match): Ditto.
-
-        * pcre/dftables.c: (main): Get rid of ctype_letter and ctype_meta,
-        which are unused.
-
-        * pcre/pcre-config.h: Get rid of EBCIDIC, PCRE_DATA_SCOPE, const,
-        size_t, HAVE_STRERROR, HAVE_MEMMOVE, HAVE_BCOPY, NEWLINE,
-        POSIX_MALLOC_THRESHOLD, NO_RECURSE, SUPPORT_UCP, SUPPORT_UTF8,
-        and JAVASCRIPT. These are all no longer configurable in our copy
-        of the library.
-
-        * pcre/pcre.h: Remove the macro-based kjs prefix hack, the PCRE
-        version macros, PCRE_UTF16, the code to set up PCRE_DATA_SCOPE,
-        the include of <stdlib.h>, and most of the constants and
-        functions defined in this header. Changed the naming scheme to
-        use a JSRegExp prefix rather than a pcre prefix. In the future,
-        we'll probably change this to be a C++ header.
-
-        * pcre/pcre_compile.c: Removed all unused code branches,
-        including many whole functions and various byte codes.
-        Kept changes outside of removal to a minimum.
-        (check_escape):
-        (first_significant_code):
-        (find_fixedlength):
-        (find_recurse):
-        (could_be_empty_branch):
-        (compile_branch):
-        (compile_regex):
-        (is_anchored):
-        (is_startline):
-        (find_firstassertedchar):
-        (jsRegExpCompile): Renamed from pcre_compile2 and changed the
-        parameters around a bit.
-        (jsRegExpFree): Added.
-
-        * pcre/pcre_exec.c: Removed many unused opcodes and variables.
-        Also started tearing down the NO_RECURSE mechanism since it's
-        now the default. In some cases there were things in the explicit
-        frame that could be turned into plain old local variables and
-        other small like optimizations.
-        (pchars):
-        (match_ref):
-        (match): Changed parameters quite a bit since it's now not used
-        recursively.
-        (jsRegExpExecute): Renamed from pcre_exec.
-
-        * pcre/pcre_internal.h: Get rid of PCRE_DEFINITION, PCRE_SPTR,
-        PCRE_IMS, PCRE_ICHANGED, PCRE_NOPARTIAL, PCRE_STUDY_MAPPED,
-        PUBLIC_OPTIONS, PUBLIC_EXEC_OPTIONS, PUBLIC_DFA_EXEC_OPTIONS,
-        PUBLIC_STUDY_OPTIONS, MAGIC_NUMBER, 16 of the opcodes,
-        _pcre_utt, _pcre_utt_size, _pcre_try_flipped, _pcre_ucp_findprop,
-        and _pcre_valid_utf8. Also moved pcre_malloc and pcre_free here.
-
-        * pcre/pcre_maketables.c: Changed to only compile in dftables.
-        Also got rid of many of the tables that we don't use.
-
-        * pcre/pcre_tables.c: Removed the unused Unicode property tables.
-
-        * pcre/pcre_ucp_searchfuncs.c: Removed everything except for
-        _pcre_ucp_othercase.
-
-        * pcre/pcre_xclass.c: (_pcre_xclass): Removed uneeded support
-        for classes based on Unicode properties.
-
-        * wtf/FastMallocPCRE.cpp: Removed unused bits. It would be good
-        to eliminate this completely, but we need the regular expression
-        code to be C++ first.
-
-        * pcre/pcre_fullinfo.c:
-        * pcre/pcre_get.c:
-        * pcre/ucp.h:
-        Files that are no longer needed. I didn't remove them with this
-        check-in, because I didn't want to modify all the project files.
-
-2007-11-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Sam.
-        
-        - remove NaN check from JSImmediate::fromDouble for 0.5% SunSpider speedup
-
-        It turns out that doing this check costs more than it saves.
-        
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::fromDouble):
-
-2007-11-03  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Oliver.
-
-        Remove dummy variable from ClassInfo reducing the size of the struct by 1 word.
-        The variable had been kept around for binary compatibility, but since nothing
-        else is there is no point in continuing to keep it around.
-
-        * API/JSCallbackConstructor.cpp:
-        * API/JSCallbackFunction.cpp:
-        * API/JSCallbackObject.cpp:
-        * bindings/objc/objc_runtime.mm:
-        * bindings/runtime_array.cpp:
-        * bindings/runtime_object.cpp:
-        * kjs/array_instance.cpp:
-        * kjs/array_object.cpp:
-        * kjs/bool_object.cpp:
-        * kjs/date_object.cpp:
-        * kjs/error_object.cpp:
-        * kjs/function.cpp:
-        * kjs/internal.cpp:
-        * kjs/lookup.h:
-        * kjs/math_object.cpp:
-        * kjs/number_object.cpp:
-        * kjs/object.h:
-        * kjs/regexp_object.cpp:
-        * kjs/string_object.cpp:
-
-2007-11-03  Kevin McCullough  <kmccullough@apple.com>
-
-        - Updated testkjs results to make the build bots green until we
-        can fix the tests that are failing.  The new failures are in DST.
-
-        * tests/mozilla/expected.html:
-
-2007-11-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Adam.
-        
-        - don't print the var twice for ForInNodes with a var declaration
-
-        * kjs/nodes2string.cpp:
-        (KJS::ForInNode::streamTo):
-
-2007-11-03  Darin Adler  <darin@apple.com>
-
-        * pcre/pcre_compile.c: (check_escape): Windows build fix. Get rid of
-        C-incompatible declaration.
-
-2007-11-03  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/nodes.cpp:  Add missing include.
-
-2007-11-03  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15814
-          <rdar://problem/5536644> fast/js/kde/encode_decode_uri.html fails
-
-        These changes cause us to match the JavaScript specification and pass the
-        fast/js/kde/encode_decode_uri.html test.
-
-        * kjs/function.cpp: (KJS::encode): Call the UTF-8 string conversion in its
-        new strict mode, throwing an exception if there are malformed UTF-16 surrogate
-        pairs in the text.
-
-        * kjs/ustring.h: Added a strict version of the UTF-8 string conversion.
-        * kjs/ustring.cpp:
-        (KJS::decodeUTF8Sequence): Removed code to disallow U+FFFE and U+FFFF; while
-        those might be illegal in some sense, they aren't supposed to get any special
-        handling in the place where this function is currently used.
-        (KJS::UString::UTF8String): Added the strictness.
-
-2007-11-03  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15812
-          some JavaScript tests (from the Mozilla test suite) are failing
-
-        Two or three fixes get 7 more of the Mozilla tests passing.
-        This gets us down from 61 failing tests to 54.
-
-        * kjs/interpreter.h: (KJS::Interpreter::builtinRegExp):
-        Made this inline and gave it a more specific type. Some day we should
-        probably do that for all of these -- might even get a bit of a speed
-        boost from it.
-        * kjs/interpreter.cpp: Removed Interpreter::builtinRegExp now that it's
-        inline in the header.
-
-        * kjs/regexp_object.h:
-        * kjs/regexp_object.cpp:
-        (KJS::RegExpProtoFunc::callAsFunction): Moved test and exec out of the
-        switch statement into the RegExpImp object, so they can be shared with
-        RegExpImp::callAsFunction.
-        (KJS::RegExpImp::match): Added. Common code used by both test and exec.
-        (KJS::RegExpImp::test): Added.
-        (KJS::RegExpImp::exec): Added.
-        (KJS::RegExpImp::implementsCall): Added.
-        (KJS::RegExpImp::callAsFunction): Added.
-        (KJS::RegExpObjectImpPrivate::RegExpObjectImpPrivate): Initialize
-        lastInput to null rather than empty string -- we take advantage of the
-        difference in RegExpImp::match.
-        (KJS::RegExpObjectImp::input): Added. No reason to go through hash tables
-        just to get at a field like this.
-
-        * pcre/pcre_compile.c: (check_escape): Changed the \u handling to match
-        the JavaScript specification. If there are not 4 hex digits after the \u,
-        then it's processed as if it wasn't an escape sequence at all.
-
-        * pcre/pcre_internal.h: Added IS_NEWLINE, with the appropriate definition
-        for JavaScript (4 specific Unicode values).
-        * pcre/pcre_exec.c:
-        (match): Changed all call sites to use IS_NEWLINE.
-        (pcre_exec): Ditto.
-
-        * tests/mozilla/expected.html: Updated to expect 7 more successful tests.
-
-2007-11-03  David D. Kilzer  <ddkilzer@webkit.org>
-
-        Sort files(...); sections of Xcode project files.
-
-        Rubber-stamped by Darin.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2007-11-03  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - remove VarDeclListNode and simplify VarDeclNode evaluation for 0.4% SunSpider speedup
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::VarDeclNode::optimizeVariableAccess):
-        (KJS::VarDeclNode::getDeclarations):
-        (KJS::VarDeclNode::handleSlowCase):
-        (KJS::VarDeclNode::evaluateSingle):
-        (KJS::VarDeclNode::evaluate):
-        (KJS::VarStatementNode::execute):
-        * kjs/nodes.h:
-        (KJS::VarDeclNode::):
-        (KJS::VarStatementNode::):
-        * kjs/nodes2string.cpp:
-        (KJS::VarDeclNode::streamTo):
-
-2007-11-03  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        http://bugs.webkit.org/show_bug.cgi?id=15800
-        REGRESSION (r27303): RegExp leaks
-
-        * kjs/regexp_object.h:
-        (KJS::RegExpImp::setRegExp):
-        (KJS::RegExpImp::regExp):
-        (KJS::RegExpImp::classInfo):
-        * kjs/regexp_object.cpp:
-        (RegExpImp::RegExpImp):
-        (RegExpImp::~RegExpImp):
-        Renamed reg member variable to m_regExp, changed it to use OwnPtr.
-
-2007-11-02  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - add SourceElements as a typedef for Vector<RefPtr<StatementNode> >.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::statementListPushFIFO):
-        (KJS::statementListGetDeclarations):
-        (KJS::statementListInitializeDeclarationStacks):
-        (KJS::statementListInitializeVariableAccessStack):
-        (KJS::statementListExecute):
-        (KJS::BlockNode::BlockNode):
-        (KJS::FunctionBodyNode::FunctionBodyNode):
-        (KJS::ProgramNode::ProgramNode):
-        * kjs/nodes.h:
-        (KJS::CaseClauseNode::):
-
-2007-11-02  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15791
-          change property map data structure for less memory use, better speed
-
-        The property map now has an array of indices and a separate array of
-        property map entries. This slightly slows down lookup because of a second
-        memory acess, but makes property maps smaller and faster to iterate in
-        functions like mark().
-
-        SunSpider says this is 1.2% faster, although it makes the bitwise-end test
-        more than 10% slower. To fix that we'll need to optimize global variable lookup.
-
-        * kjs/property_map.cpp:
-        (KJS::PropertyMapEntry::PropertyMapEntry):
-        (KJS::PropertyMapHashTable::entries):
-        (KJS::PropertyMapHashTable::allocationSize):
-        (KJS::SavedProperties::SavedProperties):
-        (KJS::SavedProperties::~SavedProperties):
-        (KJS::PropertyMap::checkConsistency):
-        (KJS::PropertyMap::~PropertyMap):
-        (KJS::PropertyMap::clear):
-        (KJS::PropertyMap::get):
-        (KJS::PropertyMap::getLocation):
-        (KJS::PropertyMap::put):
-        (KJS::PropertyMap::insert):
-        (KJS::PropertyMap::createTable):
-        (KJS::PropertyMap::rehash):
-        (KJS::PropertyMap::remove):
-        (KJS::PropertyMap::mark):
-        (KJS::comparePropertyMapEntryIndices):
-        (KJS::PropertyMap::containsGettersOrSetters):
-        (KJS::PropertyMap::getEnumerablePropertyNames):
-        (KJS::PropertyMap::save):
-        (KJS::PropertyMap::restore):
-        * kjs/property_map.h:
-
-2007-11-02  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15807
-          HashMap needs a take() function that combines get and remove
-
-        * wtf/HashMap.h: Added take function. Simplistic implementation for now,
-        but still does only one hash table lookup.
-
-        * kjs/array_instance.cpp: (KJS::ArrayInstance::put): Use take rather than
-        a find followed by a remove.
-
-2007-11-02  David Carson  <dacarson@gmail.com>
-
-        Reviewed by Darin.
-
-        Fix compiler warning "warning: suggest parentheses around && within ||"
-        http://bugs.webkit.org/show_bug.cgi?id=15764
-
-        * kjs/value.h: (KJS::JSValue::isNumber): Add parentheses.
-
-2007-11-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        In preparation for making List a simple stack-allocated Vector:
-
-        Removed all instances of List copying and/or assignment, and made List 
-        inherit from Noncopyable.
-        
-        Functions that used to return a List by copy now take List& out 
-        parameters.
-        
-        Layout tests and JS tests pass.
-
-        * kjs/list.cpp:
-        (KJS::List::slice): Replaced copyTail with a more generic slice 
-        alternative. (JavaScriptCore only calls slice(1), but WebCore calls 
-        slice(2)).
-
-2007-11-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Fixed http://bugs.webkit.org/show_bug.cgi?id=15785
-        REGRESSION(r27344): Crash on load at finance.yahoo.com
-        
-        Reverted a small portion of my last check-in. (The speedup and the List 
-        removal are still there, though.)
-        
-        ActivationImp needs to hold a pointer to its function, and mark that 
-        pointer (rather than accessing its function through its ExecState, and 
-        counting on the active scope to mark its function) because a closure 
-        can cause an ActivationImp to outlive its ExecState along with any 
-        active scope.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        * kjs/function.cpp:
-        (KJS::FunctionImp::~FunctionImp):
-        (KJS::ActivationImp::ActivationImp):
-        * kjs/function.h:
-        (KJS::ActivationImp::ActivationImpPrivate::ActivationImpPrivate):
-
-        Also made HashTable a little more crash-happy in debug builds, so 
-        problems like this will show up earlier:
-        
-        * wtf/HashTable.h:
-        (WTF::HashTable::~HashTable):
-
-2007-11-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Adam Roben.
-        
-        Addressed some of Darin's review comments.
-        
-        Used perl -p, which is the shorthand while(<>) {}.
-        
-        Made sure not to suppress bison's output.
-        
-        Added line to removed bison_out.txt, since this script removes other 
-        intermediate files, too.
-
-        * DerivedSources.make:
-
-2007-11-01  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Removed List from ActivationImp, in preparation for making all lists
-        stack-allocated.
-        
-        Tests pass.
-        
-        1.0% speedup on SunSpider, presumably due to reduced List refcount thrash.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        (KJS::ExecState::~ExecState):
-        * kjs/function.cpp:
-        (KJS::ActivationImp::ActivationImp):
-        (KJS::ActivationImp::createArgumentsObject):
-        * kjs/function.h:
-        (KJS::ActivationImp::ActivationImpPrivate::ActivationImpPrivate):
-
-2007-11-01  Adam Roben  <aroben@apple.com>
-
-        Use jsNumberCell instead of jsNumber when converting double constants to JSValues
-
-        This fixes fast/js/math.html, ecma/Date/15.9.5.10-1.js, and
-        ecma/Date/15.9.5.12-1.js, which were suffering from a bug in MSVC.
-
-        It also gets rid of an MSVC warning that we previously had to silence.
-
-        Reviewed by Geoff.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Turn
-        back on the "overflow in constant arithmetic" warning.
-        * kjs/number_object.cpp:
-        (NumberObjectImp::getValueProperty): Use jsNumberCell instead of
-        jsNumber.
-
-2007-10-31  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * kjs/ExecState.h:
-
-2007-10-31  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - shave some cycles off of local storage access for a 1% SunSpider speedup
-        
-        Keep the LocalStorage pointer in the ExecState, instead of getting
-        it from the ActivationImp all the time.
-
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::updateLocalStorage):
-        * kjs/ExecState.h:
-        (KJS::ExecState::localStorage):
-        * kjs/nodes.cpp:
-        (KJS::LocalVarAccessNode::evaluate):
-        (KJS::LocalVarFunctionCallNode::evaluate):
-        (KJS::PostIncLocalVarNode::evaluate):
-        (KJS::PostDecLocalVarNode::evaluate):
-        (KJS::LocalVarTypeOfNode::evaluate):
-        (KJS::PreIncLocalVarNode::evaluate):
-        (KJS::PreDecLocalVarNode::evaluate):
-        (KJS::ReadModifyLocalVarNode::evaluate):
-        (KJS::AssignLocalVarNode::evaluate):
-        (KJS::FunctionBodyNode::processDeclarationsForFunctionCode):
-
-2007-10-31  Adam Roben  <aroben@apple.com>
-
-        Fix a crash on launch due to a static initializer race
-
-        We now use fast inline assembler spinlocks which can be statically
-        initialized at compile time.
-
-        As a side benefit, this speeds up SunSpider by 0.4%.
-
-        Reviewed by Oliver.
-
-        * wtf/FastMalloc.cpp:
-        * wtf/TCSpinLock.h:
-        (TCMalloc_SpinLock::Lock):
-        (TCMalloc_SpinLock::Unlock):
-        (TCMalloc_SlowLock):
-        * wtf/TCSystemAlloc.cpp:
-
-2007-10-31  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Sam.
-
-        - Corrected spelling.
-
-        * wtf/HashTraits.h:
-
-2007-10-31  Mark Rowe  <mrowe@apple.com>
-
-        Further Gtk build fixage.
-
-        * kjs/regexp_object.cpp:
-
-2007-10-31  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/regexp.h:
-
-2007-10-31  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15749
-          RegExp/RegExpObjectImp cause needless UString creation
-
-        Speeds things up 0.4% according to SunSpider.
-
-        * kjs/config.h: Define USE(PCRE16) instead of HAVE(PCREPOSIX),
-        because this library doesn't use the real PCRE -- it uses its
-        own PCRE that works on UTF-16.
-
-        * kjs/regexp.h: Removed a few unused functions. Changed the ifdef.
-        Use Noncopyable. Change the return value of match.
-        * kjs/regexp.cpp:
-        (KJS::RegExp::RegExp): Call pcre_compile2, for a slight speed boost.
-        (KJS::RegExp::~RegExp): PCRE16 rather than PCREPOSIX.
-        (KJS::RegExp::match): Change to return the position as an int and the
-        ovector as a OwnArrayPtr<int> for efficiency and clearer storage management.
-
-        * kjs/regexp_object.h: Change performMatch and arrayOfMatches to no longer
-        require a result string.
-        * kjs/regexp_object.cpp:
-        (RegExpProtoFunc::callAsFunction): Update for new signature of performMatch.
-        (RegExpObjectImp::performMatch): Change so it doesn't return a string.
-        (RegExpObjectImp::arrayOfMatches): Simplify by unifying the handling of
-        the main result with the backreferences; now it doesn't need to take
-        a result parameter.
-        (RegExpObjectImp::getBackref): Minor tweaks.
-        (RegExpObjectImp::getLastParen): Ditto.
-        (RegExpObjectImp::getLeftContext): Ditto.
-        (RegExpObjectImp::getRightContext): Ditto.
-        (RegExpObjectImp::getValueProperty): Change LastMatch case to call
-        getBackref(0) so we don't need a separate getLastMatch function.
-
-        * kjs/string_object.cpp:
-        (KJS::replace): Update to use new performMatch, including merging the
-        matched string section with the other substrings.
-        (KJS::StringProtoFunc::callAsFunction): Update functions to use the
-        new performMatch and match. Also change to use OwnArrayPtr.
-
-2007-10-31  Oliver Hunt  <oliver@apple.com>
-
-        * kjs/nodes.h: include OwnPtr.h
-
-2007-10-31  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Remove SourceCodeElement class and replaced with a Vector for a 0.8% gain on sunspider
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::statementListPushFIFO):
-        (KJS::statementListGetDeclarations):
-        (KJS::statementListInitializeDeclarationStacks):
-        (KJS::statementListInitializeVariableAccessStack):
-        (KJS::statementListExecute):
-        (KJS::BlockNode::optimizeVariableAccess):
-        (KJS::BlockNode::BlockNode):
-        (KJS::BlockNode::getDeclarations):
-        (KJS::BlockNode::execute):
-        (KJS::CaseClauseNode::optimizeVariableAccess):
-        (KJS::CaseClauseNode::getDeclarations):
-        (KJS::CaseClauseNode::evalStatements):
-        (KJS::FunctionBodyNode::initializeDeclarationStacks):
-        (KJS::FunctionBodyNode::optimizeVariableAccess):
-        * kjs/nodes.h:
-        * kjs/nodes2string.cpp:
-        (KJS::statementListStreamTo):
-        (KJS::BlockNode::streamTo):
-        (KJS::CaseClauseNode::streamTo):
-
-2007-10-30  Mark Rowe  <mrowe@apple.com>
-
-        * kjs/property_map.cpp: Added a missing using directive to fix the build
-        for non-Mac ports. Mac worked only because it does the AllInOneFile compile.
-
-2007-10-31  Maciej Stachowiak  <mjs@apple.com>
-
-        * kjs/property_map.cpp: Include HashTable.h the right way to fix the build
-        for non-Mac ports.
-
-2007-10-31  Alexey Proskuryakov  <ap@webkit.org>
-
-        Reviewed by Darin.
-
-        http://bugs.webkit.org/show_bug.cgi?id=11001
-        WebKit doesn't support RegExp.compile method
-
-        Test: fast/js/regexp-compile.html
-
-        * kjs/regexp_object.cpp:
-        (RegExpPrototype::RegExpPrototype):
-        (RegExpProtoFunc::callAsFunction):
-        * kjs/regexp_object.h:
-        (KJS::RegExpProtoFunc::):
-        Added RegExp.compile.
-
-        * tests/mozilla/expected.html: js1_2/regexp/compile.js now passes.
-
-2007-10-31  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - get rid of integer divide in PropertyMap and HashTable for 1% SunSpider speedup
-        
-        Integer divide sucks. Fortunately, a bunch of shifts and XORs
-        biased towards the high bits is sufficient to provide a good
-        double hash. Besides the SunSpider win, I used the dump statistics
-        mode for both to verify that collisions did not increase and that
-        the longest collision chain is not any longer.
-
-        * kjs/property_map.cpp:
-        (KJS::doubleHash):
-        (KJS::PropertyMap::get):
-        (KJS::PropertyMap::getLocation):
-        (KJS::PropertyMap::put):
-        (KJS::PropertyMap::insert):
-        (KJS::PropertyMap::remove):
-        (KJS::PropertyMap::checkConsistency):
-        * wtf/HashTable.h:
-        (WTF::doubleHash):
-        (WTF::::lookup):
-        (WTF::::lookupForWriting):
-        (WTF::::fullLookupForWriting):
-        (WTF::::add):
-
-2007-10-30  Adam Roben  <aroben@apple.com>
-
-        * kjs/collector.h: Make HeapType public so it can be used for non-member
-        things like the HeapConstants struct template. Fixes the build on Windows.
-
-2007-10-30  Adam Roben  <aroben@apple.com>
-
-        Change ALWAYS_INLINE and WTF_PRIVATE_INLINE to use __forceinline on Windows
-
-        Speeds up SunSpider by 0.4%.
-
-        Reviewed by Steve and Maciej.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Disable
-        a warning during LTCG in release builds about double -> float
-        conversion.
-        * wtf/AlwaysInline.h:
-        * wtf/FastMalloc.h:
-
-2007-10-30  Adam Roben  <aroben@apple.com>
-
-        Use GetCurrentThreadId instead of pthread_self in FastMalloc
-
-        Speeds up SunSpider by 0.3%.
-
-        Reviewed by Steve.
-
-        * wtf/FastMalloc.cpp:
-        (WTF::TCMalloc_ThreadCache::InitTSD):
-        (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
-
-2007-10-30  Adam Roben  <aroben@apple.com>
-
-        Switch to a Win32 critical section implementation of spinlocks
-        
-        Speeds up SunSpider by 0.4%.
-        
-        Reviewed by Steve.
-        
-        * wtf/FastMalloc.cpp:
-        * wtf/TCSpinLock.h:
-        (TCMalloc_SpinLock::TCMalloc_SpinLock):
-        (TCMalloc_SpinLock::Init):
-        (TCMalloc_SpinLock::Finalize):
-        (TCMalloc_SpinLock::Lock):
-        (TCMalloc_SpinLock::Unlock):
-        * wtf/TCSystemAlloc.cpp:
-
-2007-10-30  Adam Roben  <aroben@apple.com>
-
-        Fix Bug 15586: REGRESSION (r26759-r26785): Windows nightly builds crash with Safari 3 Public Beta
-
-        http://bugs.webkit.org/show_bug.cgi?id=15586
-
-        Also fixes: <rdar://5565303> Cannot use regsvr32.exe to register WebKit.dll
-
-        Use Win32 TLS functions instead of __declspec(thread), which breaks
-        delay-loading.
-
-        Reviewed by Steve.
-
-        * wtf/FastMalloc.cpp:
-        (WTF::getThreadHeap):
-        (WTF::TCMalloc_ThreadCache::InitModule):
-
-2007-10-30  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - allocate numbers in half-size cells, for an 0.5% SunSpider speedup
-        http://bugs.webkit.org/show_bug.cgi?id=15772
-        
-        We do this by using a single mark bit per two number cells, and
-        tweaking marking.
-        
-        Besides being an 0.5% win overall, this is a 7.1% win on morph.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::heapAllocate):
-        (KJS::Collector::markStackObjectsConservatively):
-        (KJS::Collector::sweep):
-        * kjs/collector.h:
-        (KJS::SmallCollectorCell::):
-
-2007-10-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Adam Roben, Sam Weinig.
-        
-        Made conflicts in grammar.y a persistent build failure.
-
-        * DerivedSources.make:
-
-2007-10-30  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Adam and Geoff.
-
-        - Added a new cast so all the casts are in the same place.
-
-        * API/APICast.h:
-        (toGlobalRef):
-
-2007-10-30  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-
-        Fixed <rdar://problem/5567504> shift/reduce conflict introduced in r24457
-        
-        JS tests, including 
-
-            ecma_2/Statements/dowhile-001.js
-            ecma_2/Statements/dowhile-002.js
-            ecma_2/Statements/dowhile-003.js
-            ecma_2/Statements/dowhile-004.js
-            ecma_2/Statements/dowhile-005.js
-            ecma_2/Statements/dowhile-006.js
-            ecma_2/Statements/dowhile-007.js
-            js1_2/statements/do_while.js
-
-        and layout tests, including
-
-            do-while-expression-value.html
-            do-while-semicolon.html
-            do-while-without-semicolon.html
-        
-        pass.
-        
-        * kjs/grammar.y: Use the explicit "error" production, as we do with other
-        automatic semicolon insertions, to disambiguate "do { } while();" from
-        "do { } while()" followed by ";" (the empty statement).
-
-2007-10-29  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Debranching remaining assignment nodes, and miscellaneous cleanup
-        
-        Split read-modify code paths out of AssignBracketNode and AssignDotNode
-        Removed now unnecessary check for write-only assignment in ReadModifyLocalVarNode 
-        and ReadModifyResolveNode evaluate methods
-
-        Leads to a 1% gain in SunSpider.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::ReadModifyLocalVarNode::evaluate):
-        (KJS::ReadModifyResolveNode::evaluate):
-        (KJS::AssignDotNode::evaluate):
-        (KJS::ReadModifyDotNode::optimizeVariableAccess):
-        (KJS::ReadModifyDotNode::evaluate):
-        (KJS::AssignBracketNode::evaluate):
-        (KJS::ReadModifyBracketNode::optimizeVariableAccess):
-        (KJS::ReadModifyBracketNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::AssignBracketNode::):
-        (KJS::AssignBracketNode::precedence):
-        (KJS::AssignDotNode::):
-        (KJS::AssignDotNode::precedence):
-        * kjs/nodes2string.cpp:
-        (KJS::ReadModifyBracketNode::streamTo):
-        (KJS::AssignBracketNode::streamTo):
-        (KJS::ReadModifyDotNode::streamTo):
-        (KJS::AssignDotNode::streamTo):
-
-2007-10-29  Oliver Hunt  <oliver@apple.com>
-
-        Debranching various Node::evaluate implementations
-        
-        Reviewed by Maciej.
-        
-        Split the read-modify-write assignment cases out of AssignResolveNode and into ReadModifyResolveNode
-        Split the increment and decrement cases for Prefix- and Postfix- ResolveNode, BracketNode, and DotNode
-        
-        Gains 1.6% on SunSpider
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::PostIncResolveNode::optimizeVariableAccess):
-        (KJS::PostIncResolveNode::evaluate):
-        (KJS::PostIncLocalVarNode::evaluate):
-        (KJS::PostDecResolveNode::optimizeVariableAccess):
-        (KJS::PostDecResolveNode::evaluate):
-        (KJS::PostDecLocalVarNode::evaluate):
-        (KJS::PostIncBracketNode::evaluate):
-        (KJS::PostDecBracketNode::evaluate):
-        (KJS::PostIncDotNode::evaluate):
-        (KJS::PostDecDotNode::evaluate):
-        (KJS::PreIncResolveNode::optimizeVariableAccess):
-        (KJS::PreIncLocalVarNode::evaluate):
-        (KJS::PreIncResolveNode::evaluate):
-        (KJS::PreDecResolveNode::optimizeVariableAccess):
-        (KJS::PreDecLocalVarNode::evaluate):
-        (KJS::PreDecResolveNode::evaluate):
-        (KJS::PreIncBracketNode::evaluate):
-        (KJS::PreDecBracketNode::evaluate):
-        (KJS::PreIncDotNode::evaluate):
-        (KJS::PreDecDotNode::evaluate):
-        (KJS::ReadModifyResolveNode::optimizeVariableAccess):
-        (KJS::AssignResolveNode::optimizeVariableAccess):
-        (KJS::AssignLocalVarNode::evaluate):
-        (KJS::AssignResolveNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::PostDecResolveNode::):
-        (KJS::PostDecResolveNode::precedence):
-        (KJS::PostDecLocalVarNode::):
-        (KJS::PostfixBracketNode::):
-        (KJS::PostfixBracketNode::precedence):
-        (KJS::PostIncBracketNode::):
-        (KJS::PostIncBracketNode::isIncrement):
-        (KJS::PostDecBracketNode::):
-        (KJS::PostDecBracketNode::isIncrement):
-        (KJS::PostfixDotNode::):
-        (KJS::PostfixDotNode::precedence):
-        (KJS::PostIncDotNode::):
-        (KJS::PostIncDotNode::isIncrement):
-        (KJS::PostDecDotNode::):
-        (KJS::PreIncResolveNode::):
-        (KJS::PreDecResolveNode::):
-        (KJS::PreDecResolveNode::precedence):
-        (KJS::PreDecLocalVarNode::):
-        (KJS::PrefixBracketNode::):
-        (KJS::PrefixBracketNode::precedence):
-        (KJS::PreIncBracketNode::):
-        (KJS::PreIncBracketNode::isIncrement):
-        (KJS::PreDecBracketNode::):
-        (KJS::PreDecBracketNode::isIncrement):
-        (KJS::PrefixDotNode::):
-        (KJS::PrefixDotNode::precedence):
-        (KJS::PreIncDotNode::):
-        (KJS::PreIncDotNode::isIncrement):
-        (KJS::PreDecDotNode::):
-        (KJS::ReadModifyResolveNode::):
-        (KJS::ReadModifyLocalVarNode::):
-        (KJS::AssignResolveNode::):
-        (KJS::AssignResolveNode::precedence):
-        * kjs/nodes2string.cpp:
-        (KJS::PostIncResolveNode::streamTo):
-        (KJS::PostDecResolveNode::streamTo):
-        (KJS::PostfixBracketNode::streamTo):
-        (KJS::PostfixDotNode::streamTo):
-        (KJS::PreIncResolveNode::streamTo):
-        (KJS::PreDecResolveNode::streamTo):
-        (KJS::ReadModifyResolveNode::streamTo):
-        (KJS::AssignResolveNode::streamTo):
-
-2007-10-29  Maciej Stachowiak  <mjs@apple.com>
-
-        Not reviewed, build fix.
-        
-        - Include Vector.h in a way that actually works.
-
-        * kjs/LocalStorage.h:
-
-2007-10-29  Maciej Stachowiak  <mjs@apple.com>
-
-        Not reviewed, build fix.
-        
-        - Install LocalStorage.h as a private header.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2007-10-29  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Darin.
-        
-        - Define good VectorTraits for LocalStorage entry for 0.5% speed improvement on SunSpider.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/LocalStorage.h: Added.
-        (KJS::LocalStorageEntry::LocalStorageEntry):
-        (WTF::):
-        * kjs/function.h:
-        * kjs/nodes.cpp:
-        (KJS::FunctionBodyNode::processDeclarationsForFunctionCode):
-
-2007-10-29  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Some small tweaks that I notice while reviewing Oliver's last patch.
-        
-        Includes removal of an unnecessary KJS_CHECKEXCEPTIONVALUE.
-        
-        No change in SunSpider because SunSpider doesn't take the code path that
-        would execute the unnecessary KJS_CHECKEXCEPTIONVALUE much.
-
-        * kjs/nodes.cpp:
-        (KJS::LocalVarPostfixNode::evaluate):
-        (KJS::TypeOfResolveNode::optimizeVariableAccess):
-        (KJS::LocalVarTypeOfNode::evaluate):
-        (KJS::PrefixResolveNode::optimizeVariableAccess):
-        (KJS::LocalVarPrefixNode::evaluate):
-        (KJS::AssignResolveNode::optimizeVariableAccess):
-        (KJS::LocalVarAssignNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::LocalVarTypeOfNode::):
-        (KJS::PrefixResolveNode::):
-        (KJS::LocalVarPrefixNode::):
-        (KJS::AssignResolveNode::):
-        (KJS::LocalVarAssignNode::):
-
-2007-10-29  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-        
-        SunSpider claims this was a 0.7% speedup.
-
-        * kjs/string_object.cpp:
-        (KJS::StringProtoFunc::callAsFunction): avoid mallocing a jsString in the common case
-
-2007-10-29  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Mark.
-        
-        - re-enable asserts for access to empty or deleted keys
-
-        * wtf/HashTable.h:
-        (WTF::::lookup):
-        (WTF::::lookupForWriting):
-        (WTF::::fullLookupForWriting):
-        (WTF::::add):
-
-2007-10-29  Eric Seidel  <eric@webkit.org>
-
-        Build fix only, no review.
-
-        * JavaScriptCore.exp: Export symbol for new StringInstance::getOwnPropertySlot
-
-2007-10-29  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.  Move struct declarations into nodes.h.
-
-        * kjs/grammar.y:
-        * kjs/nodes.h:
-
-2007-10-29  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-        
-        Give StringInstance a getOwnPropertySlot(ExecState, unsigned, PropertySlot) fastpath, just like Arrays.
-        Make it a compile time error to use toString(ExecState) on a StringInstance
-        
-        SunSpider claims this was a 6.6% speedup overall (22% on string-base64)
-
-        * kjs/internal.h:
-        (KJS::StringImp::getLength):
-        * kjs/string_object.cpp:
-        (KJS::StringInstance::lengthGetter):
-        (KJS::StringInstance::inlineGetOwnPropertySlot):
-        (KJS::StringInstance::getOwnPropertySlot):
-        * kjs/string_object.h:
-
-2007-10-28  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Darin.
-
-        Add nodes to allow Assignment, TypeOf, and prefix operators to 
-        make use of the new optimised local variable look up.
-
-        5% gain on sunspider
-
-        * kjs/nodes.cpp:
-        (KJS::TypeOfResolveNode::optimizeVariableAccess):
-        (KJS::LocalTypeOfAccessNode::evaluate):
-        (KJS::PrefixResolveNode::optimizeVariableAccess):
-        (KJS::PrefixLocalAccessNode::evaluate):
-        (KJS::AssignResolveNode::optimizeVariableAccess):
-        (KJS::AssignLocalAccessNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::TypeOfResolveNode::):
-        (KJS::TypeOfResolveNode::precedence):
-        (KJS::LocalTypeOfAccessNode::):
-        (KJS::PrefixResolveNode::):
-        (KJS::PrefixResolveNode::precedence):
-        (KJS::PrefixLocalAccessNode::):
-        (KJS::AssignResolveNode::):
-        (KJS::AssignLocalAccessNode::):
-
-2007-10-28  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Darin.
-        
-        - avoid creating and then breaking circular lists in the parser, instead track head and tail pointers at parse time
-        http://bugs.webkit.org/show_bug.cgi?id=15748
-        
-        Not a significant speedup or slowdown on SunSpider.
-
-        * kjs/Parser.cpp:
-        (KJS::clearNewNodes):
-        * kjs/Parser.h:
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::BlockNode::BlockNode):
-        (KJS::CaseBlockNode::CaseBlockNode):
-        (KJS::FunctionBodyNode::FunctionBodyNode):
-        (KJS::SourceElementsNode::SourceElementsNode):
-        (KJS::ProgramNode::ProgramNode):
-        * kjs/nodes.h:
-        (KJS::ElementNode::):
-        (KJS::ArrayNode::):
-        (KJS::PropertyListNode::):
-        (KJS::ObjectLiteralNode::):
-        (KJS::ArgumentListNode::):
-        (KJS::ArgumentsNode::):
-        (KJS::VarDeclListNode::):
-        (KJS::VarStatementNode::):
-        (KJS::ForNode::):
-        (KJS::ParameterNode::):
-        (KJS::FuncExprNode::):
-        (KJS::FuncDeclNode::):
-        (KJS::SourceElementsNode::):
-        (KJS::CaseClauseNode::):
-        (KJS::ClauseListNode::):
-
-2007-10-28  Mark Rowe  <mrowe@apple.com>
-
-        Disable assertions in a manner that doesn't break the Qt Windows build.
-
-        * wtf/HashTable.h:
-        (WTF::::lookup):
-        (WTF::::lookupForWriting):
-        (WTF::::fullLookupForWriting):
-
-2007-10-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Temporarily disabling some ASSERTs I introduced in my last check-in 
-        because of http://bugs.webkit.org/show_bug.cgi?id=15747
-        Lots of layout tests fail the !HashTranslator::equal(KeyTraits::emptyValue() ASSERT
-
-        * wtf/HashTable.h:
-        (WTF::::lookup):
-        (WTF::::lookupForWriting):
-        (WTF::::fullLookupForWriting):
-        (WTF::::add):
-
-2007-10-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Fixed http://bugs.webkit.org/show_bug.cgi?id=15746
-        #ifndef ASSERT_DISABLED is no good!
-        
-        Replaced with #if !ASSERT_DISABLED.
-
-        * wtf/HashTable.h:
-        (WTF::::lookup):
-        (WTF::::lookupForWriting):
-        (WTF::::fullLookupForWriting):
-        (WTF::::add):
-
-2007-10-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Added FunctionCallResolveNode, PostfixResolveNode, and DeleteResolveNode
-        to the AST transfom that replaces slow resolve nodes with fast local 
-        variable alternatives.
-        
-        2.5% speedup on SunSpider.
-        
-        Also added some missing copyright notices.
-        
-        * kjs/nodes.cpp:
-        (KJS::FunctionCallResolveNode::optimizeVariableAccess):
-        (KJS::FunctionCallResolveNode::evaluate):
-        (KJS::LocalVarFunctionCallNode::evaluate):
-        (KJS::PostfixResolveNode::optimizeVariableAccess):
-        (KJS::PostfixResolveNode::evaluate):
-        (KJS::LocalVarPostfixNode::evaluate):
-        (KJS::DeleteResolveNode::optimizeVariableAccess):
-        (KJS::DeleteResolveNode::evaluate):
-        (KJS::LocalVarDeleteNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::FunctionCallResolveNode::):
-        (KJS::LocalVarFunctionCallNode::LocalVarFunctionCallNode):
-        (KJS::PostfixResolveNode::):
-        (KJS::LocalVarPostfixNode::LocalVarPostfixNode):
-        (KJS::DeleteResolveNode::):
-        (KJS::LocalVarDeleteNode::LocalVarDeleteNode):
-
-2007-10-28  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-        
-        Inline UString::Rep::deref() for a 0.8% improvement in SunSpider
-        Add virtual keyword to a few virtual functions previously unmarked.
-
-        * kjs/internal.h:
-        (KJS::StringImp::type):
-        (KJS::NumberImp::type):
-        * kjs/ustring.h:
-        (KJS::UString::Rep::deref):
-
-2007-10-28  Darin Adler  <darin@apple.com>
-
-        - fix "broken everything" from the storage leak fix
-
-        * wtf/RefPtr.h: (WTF::RefPtr::RefPtr): Added a PlacementNewAdopt constructor.
-        * kjs/ustring.h: (KJS::UString::UString): Pass PlacementNewAdopt along to RefPtr.
-
-2007-10-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Adam.
-
-        - turn on unused parameter waring on Mac OS X because it's already on elsewhere
-
-        * Configurations/Base.xcconfig: Took out -wno-unused-parameter.
-
-        * API/JSNode.c:
-        * API/JSNodeList.c:
-        * API/minidom.c:
-        * API/testapi.c:
-        Fixed unused variables by using them or marked them with UNUSED_PARAM.
-
-        * kjs/CollectorHeapIntrospector.h: (KJS::CollectorHeapIntrospector::zoneCalloc):
-        Removed parameter names to indicate they are unused.
-
-2007-10-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - fix a storage leak where we ref the UString every time we replace
-          a ResolveNode with a LocalVarAccessNode
-
-        * kjs/identifier.h: (KJS::Identifier::Identifier): Added a constructor
-        that takes PlacementNewAdopt.
-
-        * kjs/nodes.h: (KJS::ResolveNode::ResolveNode): Initialize the ident
-        with PlacementNewAdopt instead of the old value of ident.
-
-        * kjs/ustring.h: (KJS::UString::UString): Added a constructor that
-        takes PlacementNewAdopt.
-
-2007-10-28  Darin Adler  <darin@apple.com>
-
-        - Windows build fix; get rid of unused parameter
-
-        * kjs/nodes.cpp: (KJS::ResolveNode::optimizeVariableAccess): Don't pass it.
-        * kjs/nodes.h: (KJS::LocalVarAccessNode::LocalVarAccessNode): Remove it.
-        The assertions weren't all that helpful.
-
-2007-10-28  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.  Add include of MathExtras.h.
-
-        * kjs/string_object.cpp:
-
-2007-10-28  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Maciej and Tim.
-
-        Replace uses of isNaN and isInf with isnan and isinf, and
-        remove isNaN and isInf.
-
-        * kjs/config.h: Remove unused HAVE_'s.
-        * kjs/date_object.cpp:
-        (KJS::DateInstance::getTime):
-        (KJS::DateInstance::getUTCTime):
-        (KJS::DateProtoFunc::callAsFunction):
-        (KJS::DateObjectImp::construct):
-        (KJS::DateObjectFuncImp::callAsFunction):
-        * kjs/function.cpp:
-        (KJS::GlobalFuncImp::callAsFunction):
-        * kjs/math_object.cpp:
-        (MathFuncImp::callAsFunction):
-        * kjs/nodes2string.cpp:
-        (KJS::isParserRoundTripNumber):
-        * kjs/number_object.cpp:
-        (NumberProtoFunc::callAsFunction):
-        * kjs/operations.cpp:
-        * kjs/operations.h:
-        * kjs/string_object.cpp:
-        (KJS::StringProtoFunc::callAsFunction):
-        * kjs/ustring.cpp:
-        (KJS::UString::from):
-        * kjs/value.cpp:
-        (KJS::JSValue::toInteger):
-        (KJS::JSValue::toInt32SlowCase):
-        (KJS::JSValue::toUInt32SlowCase):
-
-2007-10-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: use the new-fangled missingSymbolMarker().
-
-        * kjs/nodes.cpp:
-        (KJS::ResolveNode::optimizeVariableAccess):
-        * kjs/nodes.h:
-        (KJS::LocalVarAccessNode::LocalVarAccessNode):
-
-2007-10-28  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak, Darin Adler.
-        
-        Much supporting work done by Maciej Stachowiak, Maks Orlovich, and 
-        Cameron Zwarich.
-        
-        AST transfom to replace slow resolve nodes with fast local variable
-        alternatives that do direct memory access. Currently, only ResolveNode
-        provides a fast local variable alternative. 6 others are soon to come.
-        
-        16.7% speedup on SunSpider.
-        
-        Most of this patch is just scaffolding to support iterating all the 
-        resolve nodes in the AST through optimizeResolveNodes(). In 
-        optimizeResolveNodes(), most classes just push their child nodes onto 
-        the processing stack, while ResolveNodes actually replace themselves in 
-        the tree with more optimized alternatives, if possible.
-
-        Here are the interesting bits:
-
-        * kjs/nodes.h: Added PlacementNewAdoptTag, along with implementations 
-        in Node and ResolveNode. This tag allows you to use placement new to 
-        swap out a base class Node in favor of a subclass copy that holds the
-        same data. (Without this tag, default initialization would NULL out
-        RefPtrs, change line numbers, etc.)
-
-        * kjs/nodes.cpp:
-        (KJS::ResolveNode::evaluate): Since we're taking the slow path, ASSERT
-        that the fast path is impossible, to make sure we didn't leave anything
-        on the table.
-
-        (KJS::FunctionBodyNode::optimizeResolveNodes): Here's where the AST 
-        transformation happens.
-        
-        (KJS::ResolveNode::optimizeResolveNodes): Here's where the ResolveNode
-        optimization happens.
-
-        * kjs/function.h: Added symbolTable() accessor for, for the sake of 
-        an ASSERT.
-
-2007-10-28  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Maciej.
-
-        Fix "AllInOneFile.o has a global initializer in it".
-
-        Some versions of gcc generate a global initializer for std::numeric_limits<size_t>::max().
-        We can avoid this by moving it inside an inline function.
-
-        * kjs/SymbolTable.h:
-        (KJS::missingSymbolMarker):
-        * kjs/function.cpp:
-        (KJS::ActivationImp::getOwnPropertySlot):
-        (KJS::ActivationImp::put):
-
-2007-10-28  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Mark.
-        
-        - Added assertions to protect against adding empty or deleted keys to a HashTable
-
-        * wtf/HashTable.h:
-        (WTF::HashTable::lookup):
-        (WTF::HashTable::lookupForWriting):
-        (WTF::HashTable::fullLookupForWriting):
-        (WTF::HashTable::add):
-
-2007-10-28  Darin Adler  <darin@apple.com>
-
-        - fix GTK build
-
-        * kjs/nodes2string.cpp: (KJS::isParserRoundTripNumber):
-        Use isNaN and isInf instead of isnan and isinf.
-
-2007-10-28  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15735
-          remove GroupNode to simplify AST and possibly get a modest speedup
-
-        This patch removes 4 node types: GroupNode, PropertyNameNode,
-        FunctionCallParenBracketNode, and FunctionCallParenDotNode.
-
-        To remove GroupNode, we add knowledge of precedence to the tree nodes,
-        and use that when serializing to determine where parentheses are needed.
-        This means we no longer have to represent parentheses in the tree.
-
-        The precedence values are named after productions in the grammar from the
-        JavaScript standard.
-
-        SunSpider says this is an 0.4% speedup.
-
-        * kjs/function.h:
-        * kjs/function.cpp: Removed escapeStringForPrettyPrinting -- it's part of
-        serialization, so I moved it to the file that takes care of that.
-
-        * kjs/grammar.y: Changed makeGetterOrSetterPropertyNode to use 0 to
-        indicate failure instead of a separate boolean. Got rid of PropertyNameNode
-        by merging the PropertyName rule into the Property rule (which was easier
-        than figuring out how to pass the Identifier from one node to another).
-        Got rid of GroupNode, nodeInsideAllParens(), FunctionCallParenBracketNode,
-        and FunctionCallParenDotNode.
-
-        * kjs/nodes.h: Removed unused forward declarations and Operator values.
-        Added Precedence enum, and precedence function to all nodes. Removed
-        nodeInsideAllParens. Added streamBinaryOperator function for serialization.
-        Removed GroupNode and PropertyNameNode. Made PropertyNode store an Identifier.
-        Removed FunctionCallParenBracketNode and FunctionCallParenDotNode.
-
-        * kjs/nodes.cpp: Removed Node::nodinsideAllParens, GroupNode, and PropertyNameNode.
-        (KJS::PropertyListNode::evaluate): Changed code to get name directly instead
-        of converting it from an Identifier to a jsString then back to a UString
-        then into an Identifier again!
-
-        * kjs/nodes2string.cpp: Changed special-token implementation to use a separate
-        function for each of Endl, Indent, Unindent, and DotExpr instead of using a
-        single function with a switch. Added a precedence that you can stream in, to
-        cause the next node serialized to add parentheses based on that precedence value.
-        (KJS::operatorString): Moved to the top of the file.
-        (KJS::escapeStringForPrettyPrinting): Moved here from function.cpp. Removed old
-        workaround for snprintf, since StringExtras.h takes care of that.
-        (KJS::operator<<): Made the char and char* versions faster by using UString's
-        character append functions instead of constructing a UString. Added the logic
-        to the Node* version to add parentheses if needed.
-        (KJS::Node::streamLeftAssociativeBinaryOperator): Added helper function.
-        (KJS::ElementNode::streamTo): Use PrecAssignment for the elements.
-        (KJS::BracketAccessorNode::streamTo): Use PrecCall for the expression before
-        the bracket.
-        (KJS::DotAccessorNode::streamTo): Use PrecCall for the expression before the dot.
-        (KJS::ArgumentListNode::streamTo): Use PrecAssignment for the arguments.
-        (KJS::NewExprNode::streamTo): Use PrecMember for the expression.
-        (KJS::FunctionCallValueNode::streamTo): Use PrecCall.
-        (KJS::FunctionCallBracketNode::streamTo): Ditto.
-        (KJS::FunctionCallDotNode::streamTo): Ditto.
-        (KJS::PostfixBracketNode::streamTo): Ditto.
-        (KJS::PostfixDotNode::streamTo): Ditto.
-        (KJS::PostfixErrorNode::streamTo): Use PrecLeftHandSide.
-        (KJS::DeleteBracketNode::streamTo): Use PrecCall.
-        (KJS::DeleteDotNode::streamTo): Ditto.
-        (KJS::DeleteValueNode::streamTo): Use PrecUnary.
-        (KJS::VoidNode::streamTo): Ditto.
-        (KJS::TypeOfValueNode::streamTo): Ditto.
-        (KJS::PrefixBracketNode::streamTo): Use PrecCall.
-        (KJS::PrefixDotNode::streamTo): Ditto.
-        (KJS::PrefixErrorNode::streamTo): Use PrecUnary.
-        (KJS::UnaryPlusNode::streamTo): Ditto.
-        (KJS::NegateNode::streamTo): Ditto.
-        (KJS::BitwiseNotNode::streamTo): Ditto.
-        (KJS::LogicalNotNode::streamTo): Ditto.
-        (KJS::MultNode::streamTo): Use streamLeftAssociativeBinaryOperator.
-        (KJS::DivNode::streamTo): Ditto.
-        (KJS::ModNode::streamTo): Ditto.
-        (KJS::AddNode::streamTo): Ditto.
-        (KJS::SubNode::streamTo): Ditto.
-        (KJS::LeftShiftNode::streamTo): Ditto.
-        (KJS::RightShiftNode::streamTo): Ditto.
-        (KJS::UnsignedRightShiftNode::streamTo): Ditto.
-        (KJS::LessNode::streamTo): Ditto.
-        (KJS::GreaterNode::streamTo): Ditto.
-        (KJS::LessEqNode::streamTo): Ditto.
-        (KJS::GreaterEqNode::streamTo): Ditto.
-        (KJS::InstanceOfNode::streamTo): Ditto.
-        (KJS::InNode::streamTo): Ditto.
-        (KJS::EqualNode::streamTo): Ditto.
-        (KJS::NotEqualNode::streamTo): Ditto.
-        (KJS::StrictEqualNode::streamTo): Ditto.
-        (KJS::NotStrictEqualNode::streamTo): Ditto.
-        (KJS::BitAndNode::streamTo): Ditto.
-        (KJS::BitXOrNode::streamTo): Ditto.
-        (KJS::BitOrNode::streamTo): Ditto.
-        (KJS::LogicalAndNode::streamTo): Ditto.
-        (KJS::LogicalOrNode::streamTo): Ditto.
-        (KJS::ConditionalNode::streamTo): Ditto.
-        (KJS::AssignResolveNode::streamTo): Use PrecAssignment for the right side.
-        (KJS::AssignBracketNode::streamTo): Use PrecCall for the expression before
-        the bracket and PrecAssignment for the right side.
-        (KJS::AssignDotNode::streamTo): Ditto.
-        (KJS::AssignErrorNode::streamTo): Use PrecLeftHandSide for the left side
-        and PrecAssignment for the right side.
-        (KJS::CommaNode::streamTo): Use PrecAssignment for both expressions.
-        (KJS::AssignExprNode::streamTo): Use PrecAssignment.
-
-2007-10-28  Kevin Ollivier  <kevino@theolliviers.com>
-
-        Define wx port and set wx port USE options.
-
-        Reviewed by Adam Roben.
-
-        * wtf/Platform.h:
-
-2007-10-28  Mark Rowe  <mrowe@apple.com>
-
-        We don't include "config.h" in headers.
-
-        * bindings/jni/jni_instance.h:
-        * kjs/regexp.h:
-        * wtf/TCPageMap.h:
-        * wtf/TCSpinLock.h:
-
-2007-10-28  Maciej Stachowiak  <mjs@apple.com>
-
-        Rubber stamped by Mark.
-        
-        - avoid using non-portable SIZE_T_MAX in favor of std::numeric_limits
-
-        * kjs/SymbolTable.h:
-        (KJS::SymbolTableIndexHashTraits::emptyValue):
-        * kjs/function.cpp:
-        (KJS::ActivationImp::getOwnPropertySlot):
-        (KJS::ActivationImp::put):
-
-2007-10-28  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Eric.
-        
-        - switch SymbolTable to be a HashMap instead of a PropertyMap for 3% SunSpider speedup
-
-        * kjs/SymbolTable.h:
-        (KJS::IdentifierRepHash::hash): Special hash function for identifier reps.
-        (KJS::IdentifierRepHash::equal): ditto
-        (KJS::SymbolTableIndexHashTraits::emptyValue): Special HashTraits for the index value.
-        (KJS::SymbolTable): change to a typedef for a HashMap.
-        * kjs/function.cpp:
-        (KJS::ActivationImp::getOwnPropertySlot): Adjusted for new SymbolTable API.
-        (KJS::ActivationImp::deleteProperty): ditto
-        (KJS::ActivationImp::put): ditto
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionBodyNode::initializesymbolTable): Adjusted, since
-        you now have to store a UString::rep, not an identifier.
-
-2007-10-27  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - numerous HashTable performance improvements
-        
-        This does not quite add up to a measurable win on SunSpider, but it allows a
-        follow-on > 3% improvement and probably helps WebCore too.
-        
-        I made the following improvements, among others:
-        
-        - Made HashFunctions note whether it is ok to compare a real value with the equal() function
-        to the empty or deleted value, and used this to optimize the comparisons done in hash lookup.
-        
-        - Specialized lookup so it doesn't have to do so many extra branches and build so many extra
-        std::pairs for cases that don't need them. There are now four versions, one for read-only access,
-        two for writing, and one folded directly into add() (these all were improvments).
-        
-        - Made HashMap::get() use lookup() directly instead of find() to avoid having to build iterators.
-        
-        - Made a special constructor for iterators that knows it points to
-        a valid filled cell and so skips updating itself.
-
-        - Reordered memory accesses in the various lookup functions for better code generation
-        
-        - Made simple translators avoid passing a hash code around
-        
-        - Other minor tweaks
-        
-        * wtf/HashTable.h:
-        (WTF::):
-        (WTF::HashTableConstIterator::HashTableConstIterator):
-        (WTF::HashTableIterator::HashTableIterator):
-        (WTF::IdentityHashTranslator::translate):
-        (WTF::HashTable::end):
-        (WTF::HashTable::lookup):
-        (WTF::HashTable::lookupForWriting):
-        (WTF::HashTable::makeKnownGoodIterator):
-        (WTF::HashTable::makeKnownGoodConstIterator):
-        (WTF::::lookup):
-        (WTF::::lookupForWriting):
-        (WTF::::fullLookupForWriting):
-        (WTF::::add):
-        (WTF::::addPassingHashCode):
-        (WTF::::reinsert):
-        (WTF::::find):
-        (WTF::::contains):
-        * kjs/identifier.cpp:
-        (WTF::):
-        * wtf/HashFunctions.h:
-        (WTF::):
-        * wtf/HashMap.h:
-        (WTF::):
-        (WTF::::get):
-        * wtf/HashSet.h:
-        (WTF::):
-        (WTF::::add):
-        * wtf/ListHashSet.h:
-        (WTF::ListHashSetTranslator::translate):
-
-2007-10-27  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        - fix ASCIICType.h for some Windows compiles
-
-        * wtf/ASCIICType.h: Check the compiler, not the OS, since it's the
-        compiler/library that has the wchar_t that is just a typedef.
-
-2007-10-27  Kevin McCullough  <kmccullough@apple.com>
-
-        - BuildFix
-        - Forgot to change the build step when I changed the filename.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2007-10-27  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Fixed the rest of "ASSERTION FAILED: _hash in KJS::UString::Rep::
-        computedHash()"
-        http://bugs.webkit.org/show_bug.cgi?id=15718
-
-        * kjs/identifier.cpp: Fixed more cases where an Identifier didn't get a 
-        hash value. Also changed O(n) strlen to O(1) check for empty string.
-        (KJS::Identifier::add):
-
-        * kjs/ustring.cpp: Changed O(n) strlens to O(1) checks for empty string.
-        (KJS::UString::UString):
-        (KJS::UString::operator=):
-
-2007-10-27  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        - fix pow on Windows
-
-        * wtf/MathExtras.h: (wtf_pow): Add a special case for MSVC, which has
-        a "pow" function that does not properly handle the case where arg1 is
-        NaN and arg2 is 0.
-
-        * kjs/math_object.cpp: (MathFuncImp::callAsFunction): Don't explicity
-        specify "::pow" -- just "pow" is fine.
-
-2007-10-27  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15711
-          force JSImmediate to be inlined for roughly 1.2% SunSpider speedup
-
-        * kjs/JSImmediate.h: Put ALWAYS_INLINE on everything.
-
-        * kjs/object.h: Removed redundant includes.
-        * kjs/value.h: Ditto.
-
-2007-10-27  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Mark.
-        
-        - fixed "ASSERTION FAILED: _hash in KJS::UString::Rep::computedHash()"
-        http://bugs.webkit.org/show_bug.cgi?id=15718
-
-        * kjs/identifier.cpp:
-        (KJS::Identifier::addSlowCase): Ensure that empty Identifiers have a hash computed,
-        now that we count on all Identifiers already having one.
-
-2007-10-27  Mark Rowe  <mrowe@apple.com>
-
-        Silence a warning.
-
-        * kjs/SymbolTable.h:
-
-2007-10-27  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/function.h:
-
-2007-10-26  Kevin McCullough  <kmccullough@apple.com>
-
-       Rubber stamp by Adam. 
-
-        - Renamed JSStringRefCOM to JSStringRefBSTR since it he only thing the
-        files contain are functions that operate on BSTRs.
-
-        * API/JSStringRefBSTR.cpp: Copied from API/JSStringRefCOM.cpp.
-        * API/JSStringRefBSTR.h: Copied from API/JSStringRefCOM.h.
-        * API/JSStringRefCOM.cpp: Removed.
-        * API/JSStringRefCOM.h: Removed.
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2007-10-26  Kevin McCullough  <kmccullough@apple.com>
-
-        Reviewed by Adam.
-
-        - Made JSStringCreateWithBSTR capable of handling null BSTRs.
-
-        * API/JSStringRefCOM.cpp:
-        (JSStringCreateWithBSTR):
-
-2007-10-26  Sam Weinig  <sam@webkit.org>
-
-        Windows build fix.
-
-        * kjs/SymbolTable.h: Add header gaurd.
-        * kjs/nodes.h: #include "SymbolTable.h"
-
-2007-10-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Suggested by Anders Carlsson.
-        
-        Fixed tyop.
-
-        * kjs/function.cpp:
-        (KJS::ActivationImp::getOwnPropertySlot):
-
-2007-10-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Suggested by Darin Adler.
-        
-        Use computedHash(), which is safer than just directly accessing _hash.
-
-        * kjs/lookup.cpp:
-        (KJS::Lookup::findEntry):
-        (KJS::Lookup::find):
-
-2007-10-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: svn add SymbolTable.h
-
-        * kjs/SymbolTable.h: Added.
-        (KJS::SymbolTable::set):
-        (KJS::SymbolTable::get):
-
-2007-10-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix: export SymbolTable.h to WebCore.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-
-2007-10-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Comment tweak suggested by Maciej.
-
-        * kjs/function.cpp:
-        (KJS::ActivationImp::getOwnPropertySlot):
-
-2007-10-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Tweaked property maps to remove 2 branches. 2.5% speedup on SunSpider.
-
-        * kjs/property_map.cpp: Use a special no branch accessor to the UString's
-        hash value. Also, return immediately instead of branching to the end
-        of the loop if the value is not found.
-        (KJS::PropertyMap::get):
-        (KJS::PropertyMap::getLocation):
-        (KJS::PropertyMap::put):
-        (KJS::PropertyMap::insert):
-        (KJS::PropertyMap::remove):
-        (KJS::PropertyMap::checkConsistency):
-
-        * kjs/ustring.h:
-        (KJS::UString::Rep::computedHash): Special no branch accessor to the
-        UString's hash value. Used when the caller knows that the hash value
-        has already been computed. (For example, if the caller got the UString
-        from an Identifier.)
-
-2007-10-26  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Switched ActivationImp to using a symbol table. For now, though, all
-        clients take the slow path.
-        
-        Net .6% speedup on SunSpider.
-        
-        Slowdowns:
-            - ActivationImp now mallocs in its constructor
-            - Local variable hits use an extra level of indirection to retrieve 
-            data
-            - Local variable misses do two lookups
-
-        Speedups:
-            - Fast initialization of local variables upon function entry
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: Added SymbolTable.h
-        
-        * kjs/function.cpp:
-        (KJS::ActivationImp::ActivationImp): Malloc a private structure to hold
-        data that won't fit in a JSCell.
-        (KJS::ActivationImp::argumentsGetter): Use slow symbol table path for 
-        lookup.
-        (KJS::ActivationImp::getOwnPropertySlot): ditto
-        (KJS::ActivationImp::deleteProperty): ditto
-        (KJS::ActivationImp::put): ditto
-        (KJS::ActivationImp::createArgumentsObject): ditto
-
-        (KJS::ActivationImp::mark): Call JSObject::mark first so that one of
-        our properties doesn't try to recursively mark us. (This caused a crash
-        in earlier testing. Not sure why we haven't run into it before.)
-
-        * kjs/nodes.cpp: Functions now build a symbol table the first time 
-        they're called.
-        (KJS::VarDeclNode::evaluate):
-        (KJS::FunctionBodyNode::FunctionBodyNode):
-        (KJS::FunctionBodyNode::initializeSymbolTable):
-        (KJS::FunctionBodyNode::processDeclarations):
-        (KJS::FunctionBodyNode::processDeclarationsForFunctionCode):
-        (KJS::FunctionBodyNode::processDeclarationsForProgramCode):
-
-        * kjs/nodes.h:
-        (KJS::FunctionBodyNode::symbolTable):
-
-        * wtf/Forward.h: Added Vector.
-
-2007-10-26  Kevin McCullough  <kmccullough@apple.com>
-
-        - Corrected function name mistake in this changelog.
-
-2007-10-26  Kevin McCullough  <kmccullough@apple.com>
-        Reviewed by Sam and Steve.
-
-        - Added convenience methods for converting between BSTR and JSStringRefs
-
-        * API/JSStringRefCOM.cpp: Added.
-        (JSStringCreateWithBSTR):
-        (JSStringCopyBSTR):
-        * API/JSStringRefCOM.h: Added.
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2007-10-26  Mark Rowe  <mrowe@apple.com>
-
-        Windows build fix.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::collect):
-
-2007-10-26  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Make the JSC GC use a separate heap for JSNumbers to get a 0.7-1.4% progression in SunSpider.
-
-        * kjs/CollectorHeapIntrospector.cpp:
-        (KJS::CollectorHeapIntrospector::init):
-        (KJS::CollectorHeapIntrospector::enumerate):
-        * kjs/CollectorHeapIntrospector.h:
-        * kjs/collector.cpp:
-        (KJS::Collector::recordExtraCost):
-        (KJS::Collector::heapAllocate):
-        (KJS::Collector::allocate):
-        (KJS::Collector::allocateNumber):
-        (KJS::Collector::registerThread):
-        (KJS::Collector::markStackObjectsConservatively):
-        (KJS::Collector::markMainThreadOnlyObjects):
-        (KJS::Collector::sweep):
-        (KJS::Collector::collect):
-        * kjs/collector.h:
-        * kjs/internal.h:
-        (KJS::NumberImp::operator new):
-          Force numbers to be allocated in the secondary heap.
-
-2007-10-26  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - encourage GCC a little harder to inline a few hot functions for 1.5% improvement on SunSpider.
-
-        * kjs/value.h:
-        (KJS::JSValue::getUInt32):
-        (KJS::JSValue::getTruncatedInt32):
-        (KJS::JSValue::toNumber):
-        * wtf/PassRefPtr.h:
-        (WTF::PassRefPtr::~PassRefPtr):
-        * wtf/RefPtr.h:
-        (WTF::RefPtr::operator->):
-
-2007-10-26  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/ExecState.h:
-
-2007-10-26  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Mark.
-
-        - Merge Context class fully into ExecState, since they are always created and used together.
-
-        No measurable performance impact but this is a useful cleanup.
-
-        * JavaScriptCore.pri:
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::ExecState):
-        (KJS::ExecState::~ExecState):
-        (KJS::ExecState::mark):
-        (KJS::ExecState::lexicalInterpreter):
-        * kjs/ExecState.h:
-        (KJS::ExecState::dynamicInterpreter):
-        (KJS::ExecState::setException):
-        (KJS::ExecState::clearException):
-        (KJS::ExecState::exception):
-        (KJS::ExecState::exceptionSlot):
-        (KJS::ExecState::hadException):
-        (KJS::ExecState::scopeChain):
-        (KJS::ExecState::callingExecState):
-        (KJS::ExecState::propertyNames):
-        * kjs/collector.cpp:
-        (KJS::Collector::reportOutOfMemoryToAllInterpreters):
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-        (KJS::FunctionImp::argumentsGetter):
-        (KJS::FunctionImp::callerGetter):
-        (KJS::GlobalFuncImp::callAsFunction):
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::Interpreter):
-        (KJS::Interpreter::init):
-        (KJS::Interpreter::evaluate):
-        (KJS::Interpreter::mark):
-        * kjs/interpreter.h:
-        (KJS::Interpreter::setCurrentExec):
-        (KJS::Interpreter::currentExec):
-        * kjs/nodes.cpp:
-        (KJS::currentSourceId):
-        (KJS::currentSourceURL):
-        (KJS::ThisNode::evaluate):
-        (KJS::ResolveNode::evaluate):
-        (KJS::FunctionCallResolveNode::evaluate):
-        (KJS::PostfixResolveNode::evaluate):
-        (KJS::DeleteResolveNode::evaluate):
-        (KJS::TypeOfResolveNode::evaluate):
-        (KJS::PrefixResolveNode::evaluate):
-        (KJS::AssignResolveNode::evaluate):
-        (KJS::VarDeclNode::evaluate):
-        (KJS::DoWhileNode::execute):
-        (KJS::WhileNode::execute):
-        (KJS::ForNode::execute):
-        (KJS::ForInNode::execute):
-        (KJS::ContinueNode::execute):
-        (KJS::BreakNode::execute):
-        (KJS::ReturnNode::execute):
-        (KJS::WithNode::execute):
-        (KJS::SwitchNode::execute):
-        (KJS::LabelNode::execute):
-        (KJS::TryNode::execute):
-        (KJS::FunctionBodyNode::processDeclarationsFunctionCode):
-        (KJS::FunctionBodyNode::processDeclarationsProgramCode):
-        (KJS::FunctionBodyNode::processDeclarations):
-        (KJS::FuncDeclNode::makeFunction):
-        (KJS::FuncExprNode::evaluate):
-
-2007-10-26  Mark Rowe  <mrowe@apple.com>
-
-        Windows build fix.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2007-10-26  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * JavaScriptCore.pri:
-        * kjs/ExecState.cpp:
-
-2007-10-26  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - moved Context class into ExecState.{h,cpp} in preparation for merging 
-        ExecState and Context classes.
-
-        * kjs/ExecState.h: Moved CodeType enum and Context class here in
-        preparation for merging ExecState and Context.
-        * kjs/ExecState.cpp: Moved Context class here from Context.cpp.
-        (KJS::Context::Context):
-        (KJS::Context::~Context):
-        (KJS::Context::mark):
-        * kjs/context.h: Removed.
-        * kjs/Context.cpp: Removed.
-        * kjs/function.h: Removed CodeType enum.
-        * kjs/LabelStack.h: Added. Pulled LabelStack class out of internal.h.
-        * kjs/internal.h: Removed LabelStack.
-        * JavaScriptCore.xcodeproj/project.pbxproj: Added new file, removed ones that are gone.
-        * kjs/collector.cpp: Fixed includes.
-        * kjs/function.cpp: ditto
-        * kjs/internal.cpp: ditto
-        * kjs/interpreter.cpp: ditto
-        * kjs/lookup.h: ditto
-        * kjs/nodes.cpp: ditto
-
-2007-10-26  Mark Rowe  <mrowe@apple.com>
-
-        Windows build fix.
-
-        * kjs/string_object.cpp:
-        (KJS::StringObjectFuncImp::callAsFunction):
-
-2007-10-25  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15703
-          fix numeric functions -- improve correctness and speed
-
-        Gives about 1% gain on SunSpider.
-
-        * kjs/value.h: Added toIntegerPreserveNan, removed toUInt16.
-        (KJS::JSValue::toInt32): Changed to call getTruncatedInt32 in a way that works
-        with both immediate and number values.
-        (KJS::JSValue::toUInt32): Ditto.
-        * kjs/value.cpp:
-        (KJS::JSValue::toInteger): Moved the logic from roundValue here, with a couple
-        differences. One is that it now correctly returns 0 for NaN, and another is that
-        there's no special case for 0 or infinity, since the general case already handles
-        those correctly.
-        (KJS::JSValue::toIntegerPreserveNaN): Added. Like toInteger, but without the
-        check for NaN.
-        (KJS::JSValue::toInt32SlowCase): Call toNumber instead of roundValue. The
-        truncation done by the typecast already does the necessary truncation that
-        roundValue was doing.
-        (KJS::JSValue::toUInt32SlowCase): Ditto.
-        (KJS::JSValue::toUInt16): Removed.
-
-        * kjs/internal.h: Removed roundValue.
-        * kjs/internal.cpp: Ditto.
-
-        * kjs/array_object.cpp: (KJS::ArrayProtoFunc::callAsFunction): Remove unneeded
-        code to handle NaN in Array.slice; toInteger now never returns NaN as specified.
-
-        * kjs/date_object.cpp:
-        (KJS::fillStructuresUsingTimeArgs): Replaced call to roundValue with a call to
-        toNumber as specified.
-        (KJS::DateProtoFunc::callAsFunction): In SetTime case, replaced call to roundValue
-        with a call to toNumber and timeClip as specified.
-        (KJS::DateObjectImp::construct): Removed unnecessary checks of numArgs in cases
-        where the default behavior of toInt32 (returning 0) was already correct. Replaced
-        call to roundValue with a call to toNumber as specified.
-        (KJS::DateObjectFuncImp::callAsFunction): Ditto.
-
-        * kjs/math_object.cpp: (MathFuncImp::callAsFunction): Removed unnecessary special
-        cases for the pow function that the library already handles correctly.
-
-        * kjs/number_object.cpp: (NumberProtoFunc::callAsFunction): Changed ToString to
-        call toIntegerPreserveNaN, so we can continue to handle the NaN case differently.
-        The real toInteger now returns 0 for NaN. Took out unneeded special case in
-        ToFixed for undefined; was only needed because our toInteger was wrong. Same
-        thing in ToExponential. Changed ToPrecision to call toIntegerPreserveNaN.
-
-        * kjs/string_object.cpp:
-        (KJS::StringProtoFunc::callAsFunction): Took out CharAt and CharCodeAt special
-        cases for undefined that were only needed because toInteger was wrong. Same in
-        IndexOf, and was able to remove some special cases. In LastIndexOf, used
-        toIntegerPreserveNaN, but was able to remove some special cases there too.
-        Changed Substr implementation to preserve correct behavior with the change
-        to toInteger and match the specification. Also made sure we weren't converting
-        an out of range double to an int.
-        (KJS::StringObjectFuncImp::callAsFunction): Changed constructor to just use
-        toUInt32, because truncating toUInt32 to 16 bits is the same thing and there's
-        no reason to have toUInt16 as a second, less-optimized function that's only
-        called at this one call site.
-
-        * wtf/MathExtras.h: Added trunc function for Windows.
-
-2007-10-25  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Tweaked the inner hashtable lookup loop to remove a branch in the "not 
-        found" case. .5% speedup on SunSpider.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * wtf/HashTable.h:
-        (WTF::::lookup):
-
-2007-10-25  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-
-        - fold together toPrimitive() and toNumber() conversions for 0.5% gain on SunSpider
-
-        * kjs/nodes.cpp:
-        (KJS::SubNode::evaluate): Subtract directly, since toPrimitive() is not
-        adding any value over toNumber() here.
-        (KJS::valueForReadModifyAssignment): Ditto.
-        (KJS::lessThan): Use new getPrimitiveNumber() method to avoid some virtual calls
-        and branches.
-        (KJS::lessThanEq): Ditto.
-        * JavaScriptCore.exp: Export new functions as needed.
-        * kjs/value.h:
-        (KJS::JSValue::toPrimitive): Fixed formatting.
-        (KJS::JSValue::getPrimitiveNumber): New method - this simultaneously converts
-        to number and tells you whether a toPrimitive() conversion with a Number hint
-        would have given a string.
-        * kjs/internal.cpp:
-        (KJS::StringImp::getPrimitiveNumber): Implemented. 
-        (KJS::NumberImp::getPrimitiveNumber): ditto
-        (KJS::GetterSetterImp::getPrimitiveNumber): ditto
-        (KJS::StringImp::toPrimitive): Fixed formatting.
-        (KJS::NumberImp::toPrimitive): ditto
-        (KJS::GetterSetterImp::toPrimitive): ditto
-        * kjs/internal.h:
-        * kjs/object.cpp:
-        (KJS::JSObject::getPrimitiveNumber): Implemented.
-        * kjs/object.h:
-
-2007-10-25  Sam Weinig  <sam@webkit.org>
-
-        Reviewed by Adam Roben.
-
-        Remove JSStringRefCFHack from windows as it is no longer needed.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-
-2007-10-25  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Rolled out my last patch. It turns out that I needed 2 words, not 1,
-        so it didn't help.
-
-2007-10-25  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Oliver Hunt.
-        
-        Fixed http://bugs.webkit.org/show_bug.cgi?id=15694
-        Shrink the size of an activation object by 1 word
-        
-        This is in preparation for adding a symbol table to the activation 
-        object.
-        
-        The basic strategy here is to rely on the mutual exclusion between
-        the arguments object pointer and the function pointer (you only need
-        the latter in order to create the former), and store them in the same 
-        place. The LazyArgumentsObject class encapsulates this strategy.
-        
-        Also inlined the ArgumentsImp constructor, for good measure.
-        
-        SunSpider reports no regression. Regression tests pass.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/Context.cpp:
-        (KJS::Context::~Context):
-        * kjs/function.cpp:
-        (KJS::ActivationImp::LazyArgumentsObject::createArgumentsObject):
-        (KJS::ActivationImp::LazyArgumentsObject::mark):
-        (KJS::ActivationImp::argumentsGetter):
-        (KJS::ActivationImp::mark):
-        * kjs/function.h:
-        (KJS::ActivationImp::LazyArgumentsObject::LazyArgumentsObject):
-        (KJS::ActivationImp::LazyArgumentsObject::getOrCreate):
-        (KJS::ActivationImp::LazyArgumentsObject::resetArguments):
-        (KJS::ActivationImp::LazyArgumentsObject::setArgumentsObject):
-        (KJS::ActivationImp::LazyArgumentsObject::argumentsObject):
-        (KJS::ActivationImp::LazyArgumentsObject::setFunction):
-        (KJS::ActivationImp::LazyArgumentsObject::function):
-        (KJS::ActivationImp::LazyArgumentsObject::createdArgumentsObject):
-        (KJS::ActivationImp::LazyArgumentsObject::):
-        (KJS::ActivationImp::ActivationImp::ActivationImp):
-        (KJS::ActivationImp::resetArguments):
-
-2007-10-25  Adam Roben  <aroben@apple.com>
-
-        Change JavaScriptCore.vcproj to use DerivedSources.make
-
-        We were trying to emulate the logic of make in
-        build-generated-files.sh, but we got it wrong. We now use a
-        build-generated-files very much like the one that WebCore uses to
-        invoke make.
-
-        We also now only have a Debug configuration of dftables which we build
-        even when doing a Release build of JavaScriptCore. dftables also no
-        longer has the "_debug" name suffix.
-
-        Changes mostly made by Darin, reviewed by me.
-
-        * DerivedSources.make: Add a variable to set the extension used for
-        the dftables executable.
-        * JavaScriptCore.vcproj/JavaScriptCore.sln: Updated to use Debug
-        dftables in Release configurations.
-        * JavaScriptCore.vcproj/JavaScriptCoreSubmit.sln: Ditto.
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-           - Updated include path to point to the new location of the derived
-             sources.
-           - Modified pre-build event to pass the right arguments to
-             build-generated-files.sh and not call dftables directly.
-           - Added the derived source files to the project.
-           - Removed grammarWrapper.cpp, which isn't needed now that we're
-             compiling grammar.cpp directly.
-        * JavaScriptCore.vcproj/JavaScriptCore/build-generated-files.sh:
-        Slightly modified from the WebCore version.
-        * JavaScriptCore.vcproj/JavaScriptCore/grammarWrapper.cpp: Removed.
-        * JavaScriptCore.vcproj/dftables/dftables.vcproj:
-            - Changed the output location to match Mac.
-            - Removed the Release configuration.
-            - Removed the _debug suffix.
-
-2007-10-25  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Eric Seidel.
-        
-        Slightly elaborated the differences between declaration procesing in 
-        Function Code and Program Code.
-        
-        .3% speedup on SunSpider.
-
-        * kjs/nodes.cpp:
-        (KJS::FunctionBodyNode::processDeclarationsFunctionCode): 
-        (KJS::FunctionBodyNode::processDeclarationsProgramCode): Store a 
-        minimum set of attributes instead of recomputing all the time. Also,
-        ignore m_parameters, since programs don't have arguments.
-
-2007-10-25  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-        
-        More preparation work before adding long-running mode to testkjs.
-
-        * kjs/testkjs.cpp:
-        (TestFunctionImp::callAsFunction):
-        (prettyPrintScript):
-        (runWithScripts):
-        (parseArguments):
-        (kjsmain):
-        (fillBufferWithContentsOfFile):
-
-2007-10-25  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-        
-        Bring testkjs code out of the dark ages in preparation for more
-        radical improvements (like long-running testing support!)
-
-        * kjs/testkjs.cpp:
-        (TestFunctionImp::callAsFunction):
-        (setupInterpreter):
-        (doIt):
-        (fillBufferWithContentsOfFile):
-
-2007-10-25  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Make a fast path for declaration processing inside Function Code.
-        
-        Lifted declaration processing code up from individual declaration nodes
-        and into processDeclarations.
-        
-        Broke out processDeclarations into two cases, depending on the type of 
-        code. This eliminates 2 branches, and facilitates more radical 
-        divergeance in the future.
-        
-        2.5% SunSpider speedup.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/nodes.cpp:
-        (KJS::FunctionBodyNode::initializeDeclarationStacks):
-        (KJS::FunctionBodyNode::processDeclarationsFunctionCode):
-        (KJS::FunctionBodyNode::processDeclarationsProgramCode):
-        (KJS::FunctionBodyNode::execute):
-        (KJS::FuncDeclNode::makeFunction):
-        * kjs/nodes.h:
-
-2007-10-25  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Adam.
-        
-        - add header includes needed on platforms that don't use AllInOneFile.cpp
-
-        * API/JSCallbackObject.cpp:
-        * kjs/Context.cpp:
-        * kjs/ExecState.cpp:
-        * kjs/array_instance.cpp:
-        * kjs/function_object.cpp:
-        * kjs/interpreter.cpp:
-        * kjs/nodes.cpp:
-
-2007-10-25  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Geoff.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj: re-mark JSGlobalObject.h as private
-
-2007-10-25  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed http://bugs.webkit.org/show_bug.cgi?id=15683
-        Re-order declaration initialization to avoid calling hasProperty inside
-        VarDeclNode::processDeclaration
-        
-        .7% speedup on SunSpider.
-
-        * kjs/function.h:
-        * kjs/function.cpp: Merged parameter processing into FunctionBodyNode's
-        other processing of declared symbols, so the order of execution could 
-        change.
-
-        * kjs/nodes.cpp:
-        (KJS::VarDeclNode::getDeclarations): Added special case for the 
-        "arguments" property name, explained in the comment.
-
-        (KJS::VarDeclNode::processDeclaration): Removed call to hasProperty
-        in the case of function code, since we know the declared symbol
-        management will resolve conflicts between symbols. Yay!
-
-        (KJS::VarDeclListNode::getDeclarations): Now that VarDeclNode's 
-        implementation of getDeclarations is non-trivial, we can't take a 
-        short-cut here any longer -- we need to put the VarDecl node on the 
-        stack so it gets processed normally.
-
-        (KJS::FunctionBodyNode::processDeclarations): Changed the order of 
-        processing to enforce mutual exclusion rules.
-
-        * kjs/nodes.h:
-        (KJS::DeclarationStacks::DeclarationStacks): Structure includes an 
-        ExecState now, for fast access to the "arguments" property name.
-
-2007-10-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-        
-        Add a JSGlobalObject class and remove the InterpreterMap
-        http://bugs.webkit.org/show_bug.cgi?id=15681
-        
-        This required making JSCallbackObject a template class to allow for
-        JSGlobalObjects with JSCallbackObject functionality.
-        
-        SunSpider claims this was a 0.5% speedup.
-
-        * API/JSCallbackObject.cpp:
-        * API/JSCallbackObject.h:
-        * API/JSCallbackObjectFunctions.h: Copied from API/JSCallbackObject.cpp.
-        (KJS::::JSCallbackObject):
-        (KJS::::init):
-        (KJS::::~JSCallbackObject):
-        (KJS::::initializeIfNeeded):
-        (KJS::::className):
-        (KJS::::getOwnPropertySlot):
-        (KJS::::put):
-        (KJS::::deleteProperty):
-        (KJS::::implementsConstruct):
-        (KJS::::construct):
-        (KJS::::implementsHasInstance):
-        (KJS::::hasInstance):
-        (KJS::::implementsCall):
-        (KJS::::callAsFunction):
-        (KJS::::getPropertyNames):
-        (KJS::::toNumber):
-        (KJS::::toString):
-        (KJS::::setPrivate):
-        (KJS::::getPrivate):
-        (KJS::::inherits):
-        (KJS::::cachedValueGetter):
-        (KJS::::staticValueGetter):
-        (KJS::::staticFunctionGetter):
-        (KJS::::callbackGetter):
-        * API/JSClassRef.cpp:
-        (OpaqueJSClass::prototype):
-        * API/JSContextRef.cpp:
-        (JSGlobalContextCreate):
-        * API/JSObjectRef.cpp:
-        (JSObjectMake):
-        (JSObjectGetPrivate):
-        (JSObjectSetPrivate):
-        * API/JSValueRef.cpp:
-        (JSValueIsObjectOfClass):
-        * JavaScriptCore.exp:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * bindings/c/c_utility.cpp:
-        (KJS::Bindings::convertValueToNPVariant):
-        * bindings/jni/jni_jsobject.cpp:
-        * bindings/objc/objc_utility.mm:
-        (KJS::Bindings::convertValueToObjcValue):
-        * kjs/Context.cpp:
-        (KJS::Context::Context):
-        * kjs/ExecState.cpp:
-        (KJS::ExecState::lexicalInterpreter):
-        * kjs/JSGlobalObject.h: Added.
-        (KJS::JSGlobalObject::JSGlobalObject):
-        (KJS::JSGlobalObject::isGlobalObject):
-        (KJS::JSGlobalObject::interpreter):
-        (KJS::JSGlobalObject::setInterpreter):
-        * kjs/array_instance.cpp:
-        * kjs/context.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-        (KJS::GlobalFuncImp::callAsFunction):
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::Interpreter):
-        (KJS::Interpreter::init):
-        (KJS::Interpreter::~Interpreter):
-        (KJS::Interpreter::globalObject):
-        (KJS::Interpreter::initGlobalObject):
-        (KJS::Interpreter::evaluate):
-        * kjs/interpreter.h:
-        * kjs/lookup.h:
-        (KJS::cacheGlobalObject):
-        * kjs/object.h:
-        (KJS::JSObject::isGlobalObject):
-        * kjs/testkjs.cpp:
-
-2007-10-24  Eric Seidel  <eric@webkit.org>
-
-        Build fix for Gtk, no review.
-
-        * kjs/collector.cpp: #include "context.h"
-
-2007-10-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by Maciej.
-        
-        Stop checking isOutOfMemory after every allocation, instead let the collector
-        notify all ExecStates if we ever hit this rare condition.
-        
-        SunSpider claims this was a 2.2% speedup.
-
-        * kjs/collector.cpp:
-        (KJS::Collector::collect):
-        (KJS::Collector::reportOutOfMemoryToAllInterpreters):
-        * kjs/collector.h:
-        * kjs/nodes.cpp:
-        (KJS::TryNode::execute):
-
-2007-10-24  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/identifier.h:  Remove extra qualification.
-
-2007-10-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Disable ALWAYS_INLINE in debug builds, since it drives the debugger
-        crazy.
-
-        * wtf/AlwaysInline.h:
-
-2007-10-24  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Sam Weinig.
-        
-        Inlined the fast path for creating an Identifier from an Identifier. 
-        
-        This is a .4% speedup on SunSpider overall, but as big as a 2.5% 
-        speedup on certain individual tests. 65% of the Identifiers creating 
-        by SunSpider are already Identifiers.
-        
-        (The main reason I'm making this change is that it resolves a large
-        regression in a patch I haven't checked in yet.)
-
-        * JavaScriptCore.exp:
-        * kjs/identifier.cpp:
-        (KJS::Identifier::addSlowCase):
-        * kjs/identifier.h:
-        (KJS::Identifier::Identifier::add):
-
-2007-10-24  Lars Knoll  <lars@trolltech.com>
-
-        Reviewed by Simon.
-
-        some changes to the way JS values are converted to Qt values in the script bindings. Added support for converting JS arrays into QStringList's.
-
-        * bindings/qt/qt_instance.cpp:
-        (KJS::Bindings::QtInstance::invokeMethod):
-        * bindings/qt/qt_runtime.cpp:
-        (KJS::Bindings::convertValueToQVariant):
-        (KJS::Bindings::QtField::setValueToInstance):
-
-2007-10-24  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Darin.
-
-        Remove old relation method, replace with specialised LessThan and lessThenEq functions for a 0.5-0.6% improvement in SunSpider
-
-        * kjs/nodes.cpp:
-        (KJS::lessThan):
-        (KJS::lessThanEq):
-        (KJS::LessNode::evaluate):
-        (KJS::GreaterNode::evaluate):
-        (KJS::LessEqNode::evaluate):
-        (KJS::GreaterEqNode::evaluate):
-        * kjs/operations.cpp:
-        * kjs/operations.h:
-
-2007-10-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-
-        * kjs/nodes.h:
-        (KJS::ImmediateNumberNode::): Fix ASSERT correctness (and debug build!)
-
-2007-10-24  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        * kjs/object.cpp: (KJS::JSObject::defaultValue): Get rid of a little
-        Identifier ref/deref for what SunSpider claims is a 0.4% speedup.
-
-2007-10-24  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - separate out the code to create a hash table the first time from the code
-          to rehash
-
-        SunSpider claims this was a 0.7% speedup.
-
-        * kjs/property_map.cpp:
-        (KJS::PropertyMap::expand): Changed to call either createTable or rehash.
-        (KJS::PropertyMap::createTable): Added. For the case where we had no table.
-        (KJS::PropertyMap::rehash): Removed code needed only in the case where we
-        had no table.
-        * kjs/property_map.h: Added createTable.
-
-2007-10-24  Eric Seidel  <eric@webkit.org>
-
-        Reviewed by darin.
-        
-        Add ImmediateNumberNode to hold a JSValue* instead of a double for numbers
-        which can be represented by JSImmediate.
-        
-        SunSpider claims this was a 0.6% speedup.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::NumberNode::evaluate):
-        (KJS::ImmediateNumberNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::Node::):
-        (KJS::ImmediateNumberNode::):
-        * kjs/nodes2string.cpp:
-        (ImmediateNumberNode::streamTo):
-
-2007-10-24  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15657
-          change static hash tables to use powers of two for speed
-
-        Seems to give 0.7% SunSpider speedup.
-
-        * kjs/create_hash_table: Updated to generate new format.
-        * kjs/lookup.cpp:
-        (KJS::keysMatch): Took out unneeded typecast.
-        (KJS::findEntry): Updated to expect table type 3 -- changed the printf to a plain old assert.
-        Replaced the modulus with a bit mask.
-        (KJS::Lookup::findEntry): Get the hash directly, since we know identifiers already have computed
-        their hash -- saves a branch.
-        (KJS::Lookup::find): Ditto.
-        * kjs/lookup.h: Changed attr from 2-byte value to one-byte value. Replaced hashSize with hashSizeMask.
-
-2007-10-24  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Darin.
-        
-        - remove KJS_CHECKEXCEPTIONs in places where exceptions can't happen for 0.6% SunSpider speedup
-
-        * kjs/nodes.cpp:
-        (KJS::DoWhileNode::execute):
-        (KJS::WhileNode::execute):
-        (KJS::ForNode::execute):
-        (KJS::ForInNode::execute):
-        (KJS::SourceElementsNode::execute):
-
-2007-10-23  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        * kjs/JSImmediate.h: (KJS::JSImmediate::getUInt32):
-        Changed an && to an & for a 1% gain in SunSpider.
-
-2007-10-23  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Reduce branching in implementations of some operator implementations, yielding 1.3% boost to SunSpider.
-
-        * kjs/nodes.cpp:
-        (KJS::MultNode::evaluate):
-        (KJS::DivNode::evaluate):
-        (KJS::ModNode::evaluate):
-        (KJS::add):
-        (KJS::sub):
-        (KJS::AddNode::evaluate):
-        (KJS::SubNode::evaluate):
-        (KJS::valueForReadModifyAssignment):
-        * kjs/operations.cpp:
-        * kjs/operations.h:
-
-2007-10-23  Oliver Hunt  <oliver@apple.com>
-
-        Reviewed by Maciej.
-
-        Separating all of the simple (eg. non-read-modify-write) binary operators
-        into separate classes in preparation for further JS optimisations.
-        
-        Happily this produces a 0.8% to 1.0% performance increase in SunSpider with
-        no further work.
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (KJS::MultNode::evaluate):
-        (KJS::DivNode::evaluate):
-        (KJS::ModNode::evaluate):
-        (KJS::AddNode::evaluate):
-        (KJS::SubNode::evaluate):
-        (KJS::LeftShiftNode::evaluate):
-        (KJS::RightShiftNode::evaluate):
-        (KJS::UnsignedRightShiftNode::evaluate):
-        (KJS::LessNode::evaluate):
-        (KJS::GreaterNode::evaluate):
-        (KJS::LessEqNode::evaluate):
-        (KJS::GreaterEqNode::evaluate):
-        (KJS::InstanceOfNode::evaluate):
-        (KJS::InNode::evaluate):
-        (KJS::EqualNode::evaluate):
-        (KJS::NotEqualNode::evaluate):
-        (KJS::StrictEqualNode::evaluate):
-        (KJS::NotStrictEqualNode::evaluate):
-        (KJS::BitAndNode::evaluate):
-        (KJS::BitXOrNode::evaluate):
-        (KJS::BitOrNode::evaluate):
-        (KJS::LogicalAndNode::evaluate):
-        (KJS::LogicalOrNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::MultNode::):
-        (KJS::DivNode::):
-        (KJS::ModNode::):
-        (KJS::AddNode::):
-        (KJS::SubNode::):
-        (KJS::LeftShiftNode::):
-        (KJS::RightShiftNode::):
-        (KJS::UnsignedRightShiftNode::):
-        (KJS::LessNode::):
-        (KJS::GreaterNode::):
-        (KJS::LessEqNode::):
-        (KJS::GreaterEqNode::):
-        (KJS::InstanceOfNode::):
-        (KJS::InNode::):
-        (KJS::EqualNode::):
-        (KJS::NotEqualNode::):
-        (KJS::StrictEqualNode::):
-        (KJS::NotStrictEqualNode::):
-        (KJS::BitAndNode::):
-        (KJS::BitOrNode::):
-        (KJS::BitXOrNode::):
-        (KJS::LogicalAndNode::):
-        (KJS::LogicalOrNode::):
-        * kjs/nodes2string.cpp:
-        (MultNode::streamTo):
-        (DivNode::streamTo):
-        (ModNode::streamTo):
-        (AddNode::streamTo):
-        (SubNode::streamTo):
-        (LeftShiftNode::streamTo):
-        (RightShiftNode::streamTo):
-        (UnsignedRightShiftNode::streamTo):
-        (LessNode::streamTo):
-        (GreaterNode::streamTo):
-        (LessEqNode::streamTo):
-        (GreaterEqNode::streamTo):
-        (InstanceOfNode::streamTo):
-        (InNode::streamTo):
-        (EqualNode::streamTo):
-        (NotEqualNode::streamTo):
-        (StrictEqualNode::streamTo):
-        (NotStrictEqualNode::streamTo):
-        (BitAndNode::streamTo):
-        (BitXOrNode::streamTo):
-        (BitOrNode::streamTo):
-        (LogicalAndNode::streamTo):
-
-2007-10-23  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15639
-          fix Math.abs(0), Math.ceil(-0), and Math.floor(-0)
-
-        Test: fast/js/math.html
-
-        * kjs/math_object.cpp: (MathFuncImp::callAsFunction):
-        Fix abs to look at the sign bit. Add a special case for values in the range
-        between -0 and -1 and a special case for ceil and for -0 for floor.
-
-2007-10-23  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric.
-
-        - streamline exception handling code for a >1% speed-up of SunSpider
-
-        * kjs/nodes.cpp: Changed macros to use functions for everything that's not
-        part of normal execution. We'll take function call overhead when propagating
-        an exception or out of memory.
-        (KJS::createOutOfMemoryCompletion): Added.
-        (KJS::substitute): Use append instead of the relatively inefficient + operator.
-        (KJS::Node::rethrowException): Added.
-        * kjs/nodes.h: Added rethrowException.
-
-2007-10-22  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15636
-          some JavaScriptCore regression tests are failing due to numeric conversion
-
-        This should restore correctness and make speed better too, restoring some
-        of the optimization we lost in my last check-in.
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::getTruncatedInt32): Added. Uses the range checking idiom
-        I used in my patch yesterday.
-        (KJS::JSImmediate::getTruncatedUInt32): Ditto.
-
-        * kjs/internal.h: Removed getInt32 and added getTruncatedInt/UInt32.
-        * kjs/internal.cpp:
-        (KJS::NumberImp::getUInt32): Changed to always use double, since I can't find
-        a way to write this more efficiently for float.
-        (KJS::NumberImp::getTruncatedInt32): Added.
-        (KJS::NumberImp::getTruncatedUInt32): Added.
-
-        * kjs/value.h: Removed getInt32 and added getTruncatedInt/UInt32.
-        (KJS::JSValue::getUInt32):
-        (KJS::JSValue::getTruncatedInt32): Added.
-        (KJS::JSValue::getTruncatedUInt32): Added.
-        (KJS::JSValue::toInt32): Changed getInt32 call to getTruncatedInt32.
-        (KJS::JSValue::toUInt32): Changed getUInt32 call to getTruncatedUInt32.
-        * kjs/value.cpp:
-        (KJS::JSCell::getTruncatedInt32): Added.
-        (KJS::JSCell::getTruncatedUInt32): Added.
-        (KJS::JSValue::toInteger): Changed getUInt32 call to getTruncatedInt32.
-        (KJS::JSValue::toInt32SlowCase): Removed extra getInt32 call I accidentally
-        had left in here.
-        (KJS::JSValue::toUInt32SlowCase): Ditto.
-        (KJS::JSValue::toUInt16): Changed getUInt32 call to getTruncatedUInt32.
-
-        * JavaScriptCore.exp: Updated.
-
-2007-10-22  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15632
-          js1_5/Array/array-001.js test failing
-
-        One of the JavaScriptCore tests was failing; it failed because of
-        my change to NumberImp::getUInt32. The incorrect code I copied was
-        from JSImmediate::getUInt32, and was a pre-existing bug.
-
-        This patch fixes correctness, but will surely slow down SunSpider.
-        We may be able to code this tighter and get the speed back.
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::getInt32): Renamed from toInt32 to more accurately
-        reflect the fact that this function only returns true if the value is
-        accurate (no fractional part, etc.). Changed code so that it returns
-        false when the value has a fraction.
-        (KJS::JSImmediate::getUInt32): Ditto.
-
-        * kjs/internal.cpp:
-        (KJS::NumberImp::getInt32): Changed code so that it returns false when
-        the value has a fraction. Restores the old behavior.
-        (KJS::NumberImp::getUInt32): Ditto.
-
-        * kjs/value.h:
-        (KJS::JSValue::getInt32): Updated for name change.
-        (KJS::JSValue::getUInt32): Ditto.
-        (KJS::JSValue::toInt32): Ditto.
-        (KJS::JSValue::toUInt32): Ditto.
-
-2007-10-22  Darin Adler  <darin@apple.com>
-
-        Reviewed by Brady.
-
-        - fix crash seen when running JavaScriptCore tests
-
-        * kjs/array_instance.cpp: (KJS::ArrayInstance::mark):
-        Copy and paste error: I accidentally had code here that was
-        making a copy of the HashMap -- that's illegal inside a mark
-        function and was unnecessary. The other callsite was modifying
-        the map as it iterated it, but this function is not.
-
-2007-10-22  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Oliver.
-        
-        - Avoid moving floats into integer registers in jsNumber() for 3% speedup on SunSpider
-        http://bugs.webkit.org/show_bug.cgi?id=15627
-
-        * kjs/JSImmediate.h:
-        (KJS::JSImmediate::fromDouble): Avoid moving floats to integer
-        registers since this is very slow.
-
-2007-10-22  Darin Adler  <darin@apple.com>
-
-        Reviewed by Eric Seidel.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15617
-          improve speed of integer conversions
-
-        Makes SunSpider 6% faster.
-
-        * kjs/JSImmediate.h: Added toInt32 and toUInt32, with separate versions for
-        32-bit and 64-bit.
-        * kjs/value.h:
-        (KJS::JSValue::getUInt32): Call JSImmediate::toUInt32.
-
-        * kjs/internal.h: Added getInt32.
-        * kjs/internal.cpp:
-        (KJS::NumberImp::getInt32): Added.
-        (KJS::NumberImp::getUInt32): Replaced with more-optimal implementation
-        stolen from JSValue.
-
-        * kjs/value.h:
-        (KJS::jsNumber): Marked ALWAYS_INLINE, because this wasn't getting
-        inlined.
-        (KJS::JSValue::getInt32): Added.
-        (KJS::JSValue::getUInt32): Changed to call the new JSImmediate::toUInt32
-        to avoid converting from float to double.
-        (KJS::JSValue::toInt32): Made inline, separated out the slow case.
-        (KJS::JSValue::toUInt32): Ditto.
-        * kjs/value.cpp:
-        (KJS::JSCell::getInt32): Added.
-        (KJS::JSValue::toInt32SlowCase): Renamed from toInt32. Changed to use the
-        new getInt32. Added a faster case for in-range numbers.
-        (KJS::JSValue::toUInt32SlowCase): Ditto.
-        (KJS::JSValue::toUInt16): Added a faster case for in-range numbers.
-
-        * JavaScriptCore.exp: Updated for changes.
-
-2007-10-22  Adam Roben  <aroben@apple.com>
-
-        Windows build fix
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Turn off
-        warning about implicit conversion to bool.
-
-2007-10-22  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * kjs/array_instance.cpp:
-
-2007-10-22  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15606
-          make cut-off for sparse vs. dense arrays smarter for speed with large arrays
-
-        Makes the morph test in SunSpider 26% faster, and the overall
-        benchmark 3% faster.
-
-        This also fixes some small problems we had with the distinction
-        between nonexistent and undefined values in arrays.
-
-        * kjs/array_instance.h: Tweaked formatting and naming.
-        * kjs/array_instance.cpp: Copied from kjs/array_object.cpp.
-        (KJS::storageSize): Added. Computes the size of the storage given a vector length.
-        (KJS::increasedVectorLength): Added. Implements the rule for resizing the vector.
-        (KJS::isDenseEnoughForVector): Added.
-        (KJS::ArrayInstance::ArrayInstance): Initialize the new fields.
-        (KJS::ArrayInstance::~ArrayInstance): Since m_storage is now never 0, delete it.
-        (KJS::ArrayInstance::getItem): Updated for name changes.
-        (KJS::ArrayInstance::lengthGetter): Ditto.
-        (KJS::ArrayInstance::inlineGetOwnPropertySlot): Added. Allows both versions of
-        getOwnPropertySlot to share more code.
-        (KJS::ArrayInstance::getOwnPropertySlot): Just refactored, no code change.
-        (KJS::ArrayInstance::put): Added logic for extending the vector as long as the
-        array is dense enough. Also keep m_numValuesInVector up to date.
-        (KJS::ArrayInstance::deleteProperty): Added code to keep m_numValuesInVector
-        up to date.
-        (KJS::ArrayInstance::getPropertyNames): Fixed bug where this would omit names
-        for array indices with undefined values.
-        (KJS::ArrayInstance::increaseVectorLength): Renamed from resizeStorage. Also
-        simplified to only handle getting larger.
-        (KJS::ArrayInstance::setLength): Added code to update m_numValuesInVector, to
-        zero out the unused part of the vector and to delete the map if it's no longer
-        needed.
-        (KJS::ArrayInstance::mark): Tweaked formatting.
-        (KJS::compareByStringForQSort): Ditto.
-        (KJS::ArrayInstance::sort): Ditto.
-        (KJS::CompareWithCompareFunctionArguments::CompareWithCompareFunctionArguments):
-        Ditto.
-        (KJS::compareWithCompareFunctionForQSort): Ditto.
-        (KJS::ArrayInstance::compactForSorting): Fixed bug where this would turn
-        undefined values into nonexistent values in some cases.
-
-        * kjs/array_object.h: Removed MAX_ARRAY_INDEX.
-        * kjs/array_object.cpp: Removed ArrayInstance. Moved to a separate file.
-
-        * JavaScriptCore.pri: Added array_instance.cpp.
-        * JavaScriptCore.xcodeproj/project.pbxproj: Ditto.
-        * kjs/AllInOneFile.cpp: Ditto.
-
-2007-10-22  Andrew Wellington  <proton@wiretapped.net>
-
-        Reviewed by Mark Rowe.
-        
-        Fix for local database support after r26879
-        Ensure that ENABLE_DATABASE and ENABLE_ICONDATABASE are correctly set
-
-        * Configurations/JavaScriptCore.xcconfig:
-
-2007-10-22  Simon Hausmann  <hausmann@kde.org>
-
-        Reviewed by Alp.
-
-        Build fix for the non-qmake builds.
-
-        * wtf/Platform.h: Default to enabling the database features unless
-        otherwise specified. (similar to ENABLE_ICONDATABASE)
-
-2007-10-22  Holger Freyther  <zecke@selfish.org>
-
-        Reviewed by Simon Hausmann <hausmann@kde.org>.
-
-        * Do not build testkjs as an application bundle. This is
-        needed for run-javascriptcore-tests on OSX.
-        * Also, based on r26633, allow to test the WebKit/Qt port on OSX.
-        * Set DYLD_LIBRARY_PATH if it was set in the environment. It must be set
-        as we do not have -rpath on OSX.
-
-        * kjs/testkjs.pro:
-
-2007-10-21  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Alp.
-
-        http://bugs.webkit.org/show_bug.cgi?id=15575
-        Bug 15575: [GTK] Implement threading using GThread
-
-        * wtf/Platform.h: Do not enable pthreads for Gtk.
-
-2007-10-21  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Mitz.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=15603
-        Bug 15603: Regression(r26847): Crash when sorting an empty array from JavaScript
-
-        * kjs/array_object.cpp:
-        (KJS::freeStorage): Reinstate null-check that was removed in r26847.
-
-2007-10-21  Darin Adler  <darin@apple.com>
-
-        - fix Windows build
-
-        * kjs/array_instance.h: Removed unused ExecState parameter.
-        * kjs/array_object.cpp:
-        (KJS::ArrayInstance::put): Ditto.
-        (KJS::ArrayInstance::setLength): Ditto.
-
-2007-10-21  Darin Adler  <darin@apple.com>
-
-        * kjs/array_object.cpp: (KJS::ArrayInstance::put):
-        Add missing assignment that was causing regression test crash.
-
-2007-10-21  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15585
-          speed up sparse arrays by using a custom map
-    
-        Speeds up SunSpider by 10%.
-
-        * kjs/array_object.cpp:
-        (allocateStorage): Leave room for an additional pointer.
-        (reallocateStorage): Ditto.
-        (freeStorage): Ditto.
-        (ArrayInstance::~ArrayInstance): Delete the overflow map if present.
-        (ArrayInstance::getItem): Read values from the overflow map if present.
-        Removed the check of length, since it slows down the common case.
-        (ArrayInstance::getOwnPropertySlot): Ditto. Also removed the fallback
-        to the property map.
-        (ArrayInstance::put): Write values into the overflow map as needed.
-        Also create overflow map when needed.
-        (ArrayInstance::deleteProperty): Remove values from the overflow map
-        as appropriate.
-        (ArrayInstance::getPropertyNames): Add a name for each identifier in
-        the property map. This is extremely inefficient.
-        (ArrayInstance::setLength): Remove any values in the overflow map
-        that are past the new length, as we formerly did with the property map.
-        (ArrayInstance::mark): Mark any values in the overflow map.
-        (compareByStringForQSort): Removed unneeded undefined case, since
-        compactForSorting guarantees we will have no undefined values.
-        (compareWithCompareFunctionForQSort): Ditto.
-        (ArrayInstance::compactForSorting): Copy all the values out of the
-        overflow map and destroy it.
-
-        * kjs/property_map.h: Removed now-unused getSparseArrayPropertyNames.
-        * kjs/property_map.cpp: Ditto.
-
-2007-10-20  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej.
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15579
-          stop churning identifier reference counts copying Completion objects
-
-        * kjs/completion.h: Replace the Identifier with an Identifier*.
-        * kjs/nodes.cpp:
-        (ForInNode::execute): Update for change to Completion constructor.
-        (ContinueNode::execute): Ditto.
-        (BreakNode::execute): Ditto.
-
-2007-10-20  Mark Rowe  <mrowe@apple.com>
-
-        Reviewed by Alp.
-
-        Gtk changes needed to enable HTML 5 client-side database storage.
-
-        * wtf/Platform.h: Have Gtk use pthreads for now.
-
-2007-10-20  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-
-        Fixed http://bugs.webkit.org/show_bug.cgi?id=15570
-        Store gathered declaration nodes in the function body node.
-        
-        This means that you only have to gather the declaration nodes the first 
-        time the function executes. Performance gain of 2.10% on SunSpider, 
-        0.90% on command-line JS iBench.
-
-        * kjs/nodes.cpp: Split declaration stack initialization code off into 
-        initializeDeclarationStacks().
-        (FunctionBodyNode::FunctionBodyNode):
-        (FunctionBodyNode::initializeDeclarationStacks):
-        (FunctionBodyNode::processDeclarations):
-
-        * kjs/nodes.h: Changed DeclarationStacks structure to hold references, 
-        since the actual Vectors are now stored either on the stack or in the 
-        function body node.
-
-2007-10-19  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        http://bugs.webkit.org/show_bug.cgi?id=15559
-        Moved processDeclarations call into FunctionBodyNode::execute
-
-        To improve encapsulation, moved processDeclarations call into
-        FunctionBodyNode::execute. Also marked processDeclarations 
-        ALWAYS_INLINE, since it has only 1 caller now. This is a .71% speedup 
-        on command-line JS iBench.
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-        (KJS::GlobalFuncImp::callAsFunction):
-        * kjs/function.h:
-        * kjs/interpreter.cpp:
-        (KJS::Interpreter::evaluate):
-        * kjs/nodes.cpp:
-        (FunctionBodyNode::execute):
-        * kjs/nodes.h:
-
-2007-10-19  Brady Eidson  <beidson@apple.com>
-
-        Reviewed by Sam
-
-        Queue -> Deque! and small style tweaks
-
-        * JavaScriptCore.vcproj/WTF/WTF.vcproj:
-        * JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
-        * wtf/Deque.h: Added.
-        (WTF::DequeNode::DequeNode):
-        (WTF::Deque::Deque):
-        (WTF::Deque::~Deque):
-        (WTF::Deque::size):
-        (WTF::Deque::isEmpty):
-        (WTF::Deque::append):
-        (WTF::Deque::prepend):
-        (WTF::Deque::first):
-        (WTF::Deque::last):
-        (WTF::Deque::removeFirst):
-        (WTF::Deque::clear):
-        * wtf/Queue.h: Removed.
-
-
-2007-10-19  Brady Eidson <beidson@apple.com>
-
-        Reviewed by Oliver
-
-        Added a simple LinkedList based Queue to wtf
-        We can make a better, more sophisticated an efficient one later, but have
-        needed one for some time, now!
-
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        * wtf/Queue.h: Added.
-        (WTF::QueueNode::QueueNode):
-        (WTF::Queue::Queue):
-        (WTF::Queue::~Queue):
-        (WTF::Queue::size):
-        (WTF::Queue::isEmpty):
-        (WTF::Queue::append):
-        (WTF::Queue::prepend):
-        (WTF::Queue::first):
-        (WTF::Queue::last):
-        (WTF::Queue::removeFirst):
-        (WTF::Queue::clear):
-
-2007-10-19  Nikolas Zimmermann  <zimmermann@kde.org>
-
-        Reviewed by Anders.
-
-        Try to fix Qt/Win build slave, by including windows.h also on Qt/Win.
-
-        * kjs/testkjs.cpp: Change PLATFORM(WIN) to PLATFORM(WIN_OS)
-
-2007-10-19  Simon Hausmann  <hausmann@kde.org>
-
-        Reviewed by Lars.
-
-        Fix compilation on Windows when wchar_t is a typedef instead of a native type (triggered by -Zc:wchar_t-).
-        Don't provide the wchar_t overloads then as they conflict with the unsigned short ones.
-
-        * wtf/ASCIICType.h:
-        (WTF::isASCIIAlpha):
-        (WTF::isASCIIAlphanumeric):
-        (WTF::isASCIIDigit):
-        (WTF::isASCIIHexDigit):
-        (WTF::isASCIILower):
-        (WTF::isASCIISpace):
-        (WTF::toASCIILower):
-        (WTF::toASCIIUpper):
-
-2007-10-19  Simon Hausmann  <hausmann@kde.org>
-
-        Reviewed by Lars.
-
-        Another build fix for the windows/qt build: Apply the same fix as in revision 26686 also to kjs/config.h to disable the disallowctype feature.
-
-        * kjs/config.h:
-
-2007-10-18  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Adam.
-        
-        - use __declspec(thread) for fast thread-local storage on Windows
-        
-        - 2.2% speedup on sunspider (on Windows)
-        - 7% speedup on the string section
-        - 6% speedup on JS iBench
-        
-        - fixed <rdar://problem/5473084> PLT on Windows got 2.5% slower between r25406 and r25422
-        - fixed at least some of <rdar://5527965? i-Bench JS was 14% slower in 310A11 than 310A10
-        
-        
-        * wtf/FastMalloc.cpp:
-        (WTF::getThreadHeap):
-        (WTF::setThreadHeap):
-        (WTF::TCMalloc_ThreadCache::GetCache):
-        (WTF::TCMalloc_ThreadCache::GetCacheIfPresent):
-        (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
-
-2007-10-17  Darin Adler  <darin@apple.com>
-
-        Reviewed by Mark Rowe.
-
-        - fix http://bugs.webkit.org/show_bug.cgi?id=15543
-          <rdar://problem/5545639> REGRESSION (r26697):
-          GoogleDocs: Can't create new documents or open existing ones
-
-        Test: fast/js/regexp-non-character.html
-
-        * pcre/pcre_compile.c: (check_escape): Take out the checks for valid characters
-        in the \u sequences -- not needed and actively harmful.
-
-2007-10-17  Anders Carlsson  <andersca@apple.com>
-
-        Reviewed by Oliver.
-
-        * wtf/Platform.h:
-        #define USE_PTHREADS on Mac.
-
-2007-10-17  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Merged DeclaredFunctionImp into FunctionImp (the base class) because 
-        the distinction between the two was unused.
-        
-        Removed codeType() from FunctionImp because FunctionImp and its 
-        subclasses all returned FunctionCode, so it was unused, practically 
-        speaking.
-        
-        Removed a different codeType() from GlobalFuncImp because it was unused.
-        (Perhaps it was vestigial from a time when GlobalFuncImp used to 
-        inherit from FunctionImp.)
-
-        * bindings/runtime_method.cpp:
-        * bindings/runtime_method.h:
-        * kjs/function.cpp:
-        (KJS::FunctionImp::FunctionImp):
-        (KJS::FunctionImp::callAsFunction):
-        (KJS::FunctionImp::construct):
-        (KJS::FunctionImp::execute):
-        (KJS::FunctionImp::processVarDecls):
-        * kjs/function.h:
-        (KJS::FunctionImp::implementsConstruct):
-        (KJS::FunctionImp::scope):
-        * kjs/function_object.cpp:
-        (FunctionProtoFunc::callAsFunction):
-        (FunctionObjectImp::construct):
-        * kjs/nodes.cpp:
-        (FuncDeclNode::processFuncDecl):
-        (FuncExprNode::evaluate):
-
-2007-10-17  Adam Roben  <aroben@apple.com>
-
-        Windows build fix part 2.
-
-        Fix was by Darin, reviewed by Anders and Adam.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Add
-        FastMallocPCRE.cpp to the project, and let Visual Studio have its way
-        with the post-build step.
-        * pcre/pcre.h: Don't DLL export the entry points just because this
-        is Win32 -- this is an internal copy of PCRE and should be private.
-        * pcre/pcre_compile.c: Fix an uninitialized variable warning --
-        there's no real problem but it's better to quiet the compiler by
-        tweaking the code slightly than turn off the warning entirely.
-
-2007-10-17  Adam Roben  <aroben@apple.com>
-
-        Windows build fix.
-
-        Reviewed by Anders.
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj: Disable
-        some mismatched signed/unsigned comparison warnings.
-        * pcre/pcre_exec.c:
-        (match): #if-out some labels that don't seem to exist.
-
-2007-10-17  Mark Rowe  <mrowe@apple.com>
-
-        Gtk build fix.
-
-        * JavaScriptCore.pri: Add FastMallocPCRE.cpp.
-        * pcre/pcre_get. #if out two functions that depend on pcre_get_stringnumber, which
-        is currently unavailable for UTF-16.
-
-2007-10-16  Darin Adler  <darin@apple.com>
-
-        Reviewed by Geoff.
-
-        - merged PCRE changes between 6.4 and 6.5
-
-        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
-        * JavaScriptCore.xcodeproj/project.pbxproj:
-        Removed pcre_config.c, pcre_globals.c, pcre_info.c, pcre_maketables.c,
-        pcre_printint.src, pcre_refcount.c, pcre_study.c, pcre_try_flipped.c,
-        pcre_ucp_findchar.c, pcre_version.c, and ucptable.c. Added pcre_ucp_searchfuncs.c.
-
-        * pcre/AUTHORS:
-        * pcre/LICENCE:
-        * pcre/MERGING:
-        * pcre/dftables.c:
-        * pcre/pcre-config.h:
-        * pcre/pcre.h:
-        * pcre/pcre.pri:
-        * pcre/pcre_compile.c:
-        * pcre/pcre_exec.c:
-        * pcre/pcre_fullinfo.c:
-        * pcre/pcre_get.c:
-        * pcre/pcre_internal.h:
-        * pcre/pcre_maketables.c:
-        * pcre/pcre_ord2utf8.c:
-        * pcre/pcre_tables.c:
-        * pcre/pcre_ucp_searchfuncs.c: Copied from pcre/pcre_ucp_findchar.c.
-        * pcre/pcre_xclass.c:
-        * pcre/ucp.h:
-        * pcre/ucpinternal.h:
-        * pcre/ucptable.c:
-        Updated with new versions from the PCRE 6.5 release, merged with changes.
-
-        * pcre/pcre_config.c: Removed.
-        * pcre/pcre_globals.c: Removed.
-        * pcre/pcre_info.c: Removed.
-        * pcre/pcre_printint.src: Removed.
-        * pcre/pcre_refcount.c: Removed.
-        * pcre/pcre_study.c: Removed.
-        * pcre/pcre_try_flipped.c: Removed.
-        * pcre/pcre_ucp_findchar.c: Removed.
-        * pcre/pcre_version.c: Removed.
-
-2007-10-16  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-
-        Removed KJS_VERBOSE because it was getting in the way of readability, 
-        and the messages didn't seem very helpful.
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::callAsFunction):
-        (KJS::FunctionImp::passInParameters):
-        * kjs/lookup.h:
-        (KJS::lookupPut):
-        * kjs/object.cpp:
-        (KJS::JSObject::put):
-        * kjs/value.h:
-
-2007-10-16  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Removed the Parameter class because it was a redundant wrapper around 
-        Identifier.
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::passInParameters):
-        (KJS::FunctionImp::getParameterName):
-        * kjs/nodes.cpp:
-        (FunctionBodyNode::addParam):
-        * kjs/nodes.h:
-        (KJS::FunctionBodyNode::):
-
-2007-10-16  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Global replace of assert with ASSERT.
-
-2007-10-16  Adam Roben  <aroben@apple.com>
-
-        Make testkjs not delay-load WebKit
-
-        Soon, delay-loading WebKit will be impossible (because we will be
-        using __declspec(thread) for thread-local storage). This change
-        prepares testkjs for the future.
-
-        Reviewed by Sam.
-
-        * JavaScriptCore.vcproj/JavaScriptCore.sln: Removed WebKitInitializer,
-        added FindSafari.
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj: Don't link against
-        WebKitInitializer, don't delay-load WebKit.
-        * kjs/testkjs.cpp: Don't use WebKitInitializer.
-
-2007-10-16  Adam Roben  <aroben@apple.com>
-
-        Updated testkjs for the rename of WebKit_debug.dll to WebKit.dll for the Debug configuration
-
-        Reviewed by Kevin McCullough.
-
-        * JavaScriptCore.vcproj/debug.vsprops: Added WebKitDLLConfigSuffix.
-        * JavaScriptCore.vcproj/debug_internal.vsprops: Ditto.
-        * JavaScriptCore.vcproj/release.vsprops: Ditto.
-        * JavaScriptCore.vcproj/testkjs/testkjs.vcproj: Use
-        WebKitDLLConfigSuffix when referring to WebKit.dll, and fixed a typo
-        in the name of icuuc36[_debug].dll.
-
-2007-10-16  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Re-structured variable and function declaration code.
-        
-        Command-line JS iBench shows no regression.
-        
-        Here are the changes:
-
-        1. Function declarations are now processed at the same time as var 
-        declarations -- namely, immediately upon entry to an execution context. 
-        This does not match Firefox, which waits to process a function
-        declaration until the declaration's containing block executes, but it 
-        does match IE and the ECMA spec. (10.1.3 states that var and function 
-        declarations should be processed at the same time -- namely, "On 
-        entering an execution context." 12.2 states that "A Block does not 
-        define a new execution scope.")
-
-        2. Declaration processing proceeds iteratively now, rather than 
-        recursively, storing the nodes is finds in stacks. This will later 
-        facilitate an optimization to hold on to the gathered declaration nodes, 
-        rather than re-fetching them in every function call. 
-        [ http://bugs.webkit.org/show_bug.cgi?id=14868 ]
-
-        Modified these tests because they expected the incorrect Mozilla 
-        behavior described above:
-
-        * tests/mozilla/ecma_3/Function/scope-001.js:
-        * tests/mozilla/js1_5/Scope/regress-184107.js:
-
-2007-10-16  Darin Adler  <darin@apple.com>
-
-        - try to fix the GTK build
-
-        * kjs/ustring.cpp: Include ASCIICType.h, not ASCIICtype.h.
-
-2007-10-16  Darin Adler  <darin@apple.com>
-
-        - try to fix the Windows build
-
-        * kjs/date_object.cpp: (KJS::parseDate): A couple instances of isspace were
-        in here. Not sure why it wasn't failing elsewhere. Changed to isASCIISpace.
-
-2007-10-16  Darin Adler  <darin@apple.com>
-
-        - try to fix the GTK build
-
-        * kjs/ustring.cpp: Include ASCIICType.h.
-
-2007-10-16  Darin Adler  <darin@apple.com>
-
-        Reviewed by Maciej and Geoff (and looked over by Eric).
-
-        - http://bugs.webkit.org/show_bug.cgi?id=15519
-          eliminate use of <ctype.h> for processing ASCII
-
-        * wtf/ASCIICType.h: Added.
-        * wtf/DisallowCType.h: Added.
-
-        * kjs/config.h: Include DisallowCType.h.
-
-        * kjs/date_object.cpp:
-        (KJS::skipSpacesAndComments):
-        (KJS::findMonth):
-        (KJS::parseDate):
-        * kjs/function.cpp:
-        (KJS::decode):
-        * kjs/ustring.cpp:
-        (KJS::UString::toDouble):
-        Use ASCIICType.h functions instead of ctype.h ones.
-
-2007-10-14  Maciej Stachowiak  <mjs@apple.com>
-
-        Reviewed by Darin.
-
-        - fixes for "New JavaScript benchmark"
-        http://bugs.webkit.org/show_bug.cgi?id=15515
-        
-        * kjs/testkjs.cpp:
-        (TestFunctionImp::callAsFunction): Implement "load" for compatibility
-        with SpiderMonkey.
-        (TestFunctionImp::): ditto
-        (doIt): ditto
-        (kjsmain): Drop useless --> from output.
-
-2007-10-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Removed unnecessary #include.
-
-        * API/JSObjectRef.cpp:
-
-2007-10-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Double-reverse build fix. My tree was out of date.
-
-        * kjs/nodes.cpp:
-        (NumberNode::evaluate):
-
-2007-10-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Build fix.
-
-        * kjs/nodes.cpp:
-        (NumberNode::evaluate):
-
-2007-10-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Removed surprising self-named "hack" that made nested functions 
-        available as named properties of their containing functions, and placed
-        containing function objects in the scope chains of nested functions.
-        
-        There were a few reasons to remove this "hack:"
-
-        1. It contradicted FF, IE, and the ECMA spec.
-
-        2. It incurred a performance penalty, since merely parsing a function 
-        required parsing its body for nested functions (and so on).
-
-        3. SVN history contains no explanation for why it was added. It was just
-        legacy code in a large merge a long, long time ago.
-
-        [ Patch broken off from http://bugs.webkit.org/show_bug.cgi?id=14868 ]
-
-        * kjs/nodes.cpp:
-        (FuncDeclNode::processFuncDecl):
-
-2007-10-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Removed the concept of AnonymousCode. It was unused, and it doesn't
-        exist in the ECMA spec.
-        
-        [ Patch broken off from http://bugs.webkit.org/show_bug.cgi?id=14868 ]
-
-        * kjs/Context.cpp:
-        (KJS::Context::Context):
-        * kjs/function.h:
-        * kjs/nodes.cpp:
-        (ReturnNode::execute):
-
-2007-10-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Darin Adler.
-        
-        Made function parameters DontDelete. This matches FF and the vague
-        description in ECMA 10.1.3. It's also required in order to make
-        symbol table based lookup of function parameters valid. (If the 
-        parameters aren't DontDelete, you can't guarantee that you'll find
-        them later in the symbol table.)
-
-        [ Patch broken off from http://bugs.webkit.org/show_bug.cgi?id=14868 ]
-
-        * kjs/function.cpp:
-        (KJS::FunctionImp::passInParameters):
-
-2007-10-15  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Some Vector optimizations. These are especially important when using
-        Vector as a stack for implementing recursive algorithms iteratively.
-        
-        [ Broken off from http://bugs.webkit.org/show_bug.cgi?id=14868 ]
-
-        1. Added shrink(), which is a version of resize() that you can call
-        to save a branch / improve code generation and inlining when you know 
-        that the vector is not getting bigger.
-        
-        2. Changed subclassing relationship in VectorBuffer to remove a call to
-        fastFree() in the destructor for the inlineCapacity != 0 template
-        specialization. This brings inline Vectors one step closer to true
-        stack-allocated arrays.
-        
-        Also changed abort() to CRASH(), since the latter works better.
-
-        * wtf/Vector.h:
-        (WTF::VectorBufferBase::allocateBuffer):
-        (WTF::VectorBufferBase::deallocateBuffer):
-        (WTF::VectorBufferBase::VectorBufferBase):
-        (WTF::VectorBufferBase::~VectorBufferBase):
-        (WTF::):
-        (WTF::VectorBuffer::VectorBuffer):
-        (WTF::VectorBuffer::~VectorBuffer):
-        (WTF::VectorBuffer::deallocateBuffer):
-        (WTF::VectorBuffer::releaseBuffer):
-        (WTF::Vector::clear):
-        (WTF::Vector::removeLast):
-        (WTF::::operator):
-        (WTF::::fill):
-        (WTF::::shrink):
-
-2007-10-12  Geoffrey Garen  <ggaren@apple.com>
-
-        Reviewed by Maciej Stachowiak.
-        
-        Fixed http://bugs.webkit.org/show_bug.cgi?id=15490
-        Iteration statements sometimes incorrectly evaluate to the empty value 
-        (KDE r670547). 
-        
-        [ Broken off from http://bugs.webkit.org/show_bug.cgi?id=14868 ]
-        
-        This patch is a merge of KDE r670547, with substantial modification 
-        for performance.
-        
-        It fixes do-while statements to evaluate to a value. (They used
-        to evaluate to the empty value in all cases.) 
-
-        It also fixes SourceElementsNode to maintain the value of abnormal 
-        completions like "break" and "continue."
-        
-        It also re-works the main execution loop in SourceElementsNode so that
-        it (1) makes a little more sense and (2) avoids unnecessary work. This 
-        is a .28% speedup on command-line JS iBench.
-
-        * kjs/nodes.cpp:
-        (DoWhileNode::execute):
-        (SourceElementsNode::execute):
-
-2007-10-15  Simon Hausmann  <hausmann@kde.org>
-
-        Reviewed by Lars.
-
-        Fix compilation with gcc 4.3 by including 'limits' due to the use of std::numeric_limits.
-
-        * wtf/HashTraits.h:
-
-2007-10-5  Kevin Ollivier  <kevino@theolliviers.com>
-        Reviewed by Adam.
-        
-        Add support for MSVC7, and fix cases where PLATFORM(WIN) should
-        be PLATFORM(WIN_OS) for other ports building on Windows.
-        * kjs/DateMath.cpp:
-        (KJS::getDSTOffsetSimple):
-        * kjs/JSImmediate.h:
-        * wtf/Assertions.cpp:
-        * wtf/Assertions.h:
-        * wtf/Platform.h:
-        * wtf/StringExtras.h:
-        (snprintf):
-        (vsnprintf):
-
-2007-10-14  Cameron Zwarich  <cwzwarich@uwaterloo.ca>
-
-        Reviewed by Darin.
-
-        Adds NegateNode optimization from KJS. The relevant revision in KDE
-        is 666736.
-
-        * kjs/grammar.y:
-        * kjs/nodes.cpp:
-        (NumberNode::evaluate):
-        * kjs/nodes.h:
-        (KJS::Node::):
-        (KJS::NumberNode::):
-        * kjs/nodes2string.cpp:
-        (NumberNode::streamTo):
-
-2007-10-14  Jason Foreman  <jason@threeve.org>
-
-        Reviewed by Maciej.
-
-        Fix http://bugs.webkit.org/show_bug.cgi?id=15145
-        
-        Ensure that if adjusting n to minimize the difference of n*intPow10(e-p+1) to x,
-        that the property n < intPow10(p) is maintained.
-
-        * kjs/number_object.cpp:
-        (NumberProtoFunc::callAsFunction):
-
-== Rolled over to ChangeLog-2007-10-14 ==
index 4b3368293c590853254be435e771f7e8b8a8da77..9eaccab4b5bd59f5c74be13c8dc93c2848172e5b 100644 (file)
@@ -40,6 +40,7 @@ all : \
     chartables.c \
     DatePrototype.lut.h \
     Grammar.cpp \
+    JSONObject.lut.h \
     Lexer.lut.h \
     MathObject.lut.h \
     NumberConstructor.lut.h \
index 3d90470ddebe1074ea66043746013f82f8a3fb0f..d376b78899901fd9789c3726078706dfa7de0c01 100644 (file)
@@ -1,4 +1,5 @@
 javascriptcore_cppflags += \
+       -I$(srcdir)/JavaScriptCore \
        -I$(srcdir)/JavaScriptCore/API \
        -I$(srcdir)/JavaScriptCore/ForwardingHeaders \
        -I$(srcdir)/JavaScriptCore/interpreter \
@@ -13,6 +14,7 @@ javascriptcore_cppflags += \
        -I$(srcdir)/JavaScriptCore/jit \
        -I$(srcdir)/JavaScriptCore/assembler \
        -I$(srcdir)/JavaScriptCore/wtf/unicode \
+       -I$(srcdir)/JavaScriptCore/yarr \
        -I$(top_builddir)/JavaScriptCore/pcre \
        -I$(top_builddir)/JavaScriptCore/parser \
        -I$(top_builddir)/JavaScriptCore/runtime
@@ -33,6 +35,7 @@ javascriptcore_built_nosources += \
        DerivedSources/Lexer.lut.h \
        JavaScriptCore/runtime/ArrayPrototype.lut.h \
        JavaScriptCore/runtime/DatePrototype.lut.h \
+       JavaScriptCore/runtime/JSONObject.lut.h \
        JavaScriptCore/runtime/MathObject.lut.h \
        JavaScriptCore/runtime/NumberConstructor.lut.h \
        JavaScriptCore/runtime/RegExpConstructor.lut.h \
@@ -75,13 +78,17 @@ javascriptcore_sources += \
        JavaScriptCore/JavaScriptCorePrefix.h \
        JavaScriptCore/jit/ExecutableAllocator.h \
        JavaScriptCore/jit/JIT.cpp \
+       JavaScriptCore/jit/JITOpcodes.cpp \
        JavaScriptCore/jit/JITCall.cpp \
+       JavaScriptCore/jit/JITCode.h \
        JavaScriptCore/jit/JITPropertyAccess.cpp \
        JavaScriptCore/jit/JITArithmetic.cpp \
        JavaScriptCore/jit/ExecutableAllocator.cpp \
-       JavaScriptCore/jit/ExecutableAllocatorPosix.cpp \
        JavaScriptCore/jit/JIT.h \
        JavaScriptCore/jit/JITInlineMethods.h \
+       JavaScriptCore/jit/JITStubs.cpp \
+       JavaScriptCore/jit/JITStubs.h \
+       JavaScriptCore/jit/JITStubCall.h \
        JavaScriptCore/bytecode/StructureStubInfo.cpp \
        JavaScriptCore/bytecode/StructureStubInfo.h \
        JavaScriptCore/bytecode/CodeBlock.cpp \
@@ -101,7 +108,6 @@ javascriptcore_sources += \
        JavaScriptCore/bytecompiler/RegisterID.h \
        JavaScriptCore/bytecode/SamplingTool.cpp \
        JavaScriptCore/bytecode/SamplingTool.h \
-       JavaScriptCore/bytecompiler/SegmentedVector.h \
        JavaScriptCore/config.h \
        JavaScriptCore/debugger/DebuggerActivation.cpp \
        JavaScriptCore/debugger/DebuggerActivation.h \
@@ -130,8 +136,13 @@ javascriptcore_sources += \
        JavaScriptCore/icu/unicode/utypes.h \
        JavaScriptCore/icu/unicode/uversion.h \
        JavaScriptCore/assembler/X86Assembler.h \
+       JavaScriptCore/assembler/AbstractMacroAssembler.h \
        JavaScriptCore/assembler/AssemblerBuffer.h \
        JavaScriptCore/assembler/MacroAssembler.h \
+       JavaScriptCore/assembler/MacroAssemblerCodeRef.h \
+       JavaScriptCore/assembler/MacroAssemblerX86.h \
+       JavaScriptCore/assembler/MacroAssemblerX86_64.h \
+       JavaScriptCore/assembler/MacroAssemblerX86Common.h \
        JavaScriptCore/os-win32/stdbool.h \
        JavaScriptCore/os-win32/stdint.h \
        JavaScriptCore/pcre/pcre.h \
@@ -155,8 +166,12 @@ javascriptcore_sources += \
        JavaScriptCore/profiler/Profiler.h \
        JavaScriptCore/profiler/TreeProfile.cpp \
        JavaScriptCore/profiler/TreeProfile.h \
+       JavaScriptCore/interpreter/CachedCall.h \
        JavaScriptCore/interpreter/CallFrame.cpp \
        JavaScriptCore/interpreter/CallFrame.h \
+       JavaScriptCore/interpreter/CallFrameClosure.h \
+       JavaScriptCore/runtime/TimeoutChecker.cpp \
+       JavaScriptCore/runtime/TimeoutChecker.h \
        JavaScriptCore/runtime/InitializeThreading.cpp \
        JavaScriptCore/runtime/InitializeThreading.h \
        JavaScriptCore/runtime/JSActivation.cpp \
@@ -167,8 +182,12 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/JSGlobalData.h \
        JavaScriptCore/runtime/JSNotAnObject.cpp \
        JavaScriptCore/runtime/JSNotAnObject.h \
+       JavaScriptCore/runtime/JSONObject.cpp \
+       JavaScriptCore/runtime/JSONObject.h \
        JavaScriptCore/runtime/JSPropertyNameIterator.cpp \
        JavaScriptCore/runtime/JSPropertyNameIterator.h \
+       JavaScriptCore/runtime/LiteralParser.cpp \
+       JavaScriptCore/runtime/LiteralParser.h \
        JavaScriptCore/runtime/SmallStrings.cpp \
        JavaScriptCore/runtime/SmallStrings.h \
        JavaScriptCore/runtime/Structure.cpp \
@@ -177,19 +196,13 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/StructureChain.h \
        JavaScriptCore/runtime/StructureTransitionTable.h \
        JavaScriptCore/runtime/TypeInfo.h \
-       JavaScriptCore/wrec/CharacterClass.cpp \
        JavaScriptCore/wrec/CharacterClass.h \
-       JavaScriptCore/wrec/CharacterClassConstructor.cpp \
        JavaScriptCore/wrec/CharacterClassConstructor.h \
        JavaScriptCore/wrec/Escapes.h \
        JavaScriptCore/wrec/Quantifier.h \
-       JavaScriptCore/wrec/WREC.cpp \
        JavaScriptCore/wrec/WREC.h \
-       JavaScriptCore/wrec/WRECFunctors.cpp \
        JavaScriptCore/wrec/WRECFunctors.h \
-       JavaScriptCore/wrec/WRECGenerator.cpp \
        JavaScriptCore/wrec/WRECGenerator.h \
-       JavaScriptCore/wrec/WRECParser.cpp \
        JavaScriptCore/wrec/WRECParser.h \
        JavaScriptCore/wtf/ASCIICType.h \
        JavaScriptCore/wtf/AVLTree.h \
@@ -198,8 +211,12 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/Assertions.h \
        JavaScriptCore/wtf/ByteArray.cpp \
        JavaScriptCore/wtf/ByteArray.h \
+       JavaScriptCore/wtf/CrossThreadRefCounted.h \
+       JavaScriptCore/wtf/OwnFastMallocPtr.h \
        JavaScriptCore/wtf/CurrentTime.cpp \
        JavaScriptCore/wtf/CurrentTime.h \
+       JavaScriptCore/wtf/DateMath.cpp \
+       JavaScriptCore/wtf/DateMath.h \
        JavaScriptCore/wtf/Deque.h \
        JavaScriptCore/wtf/DisallowCType.h \
        JavaScriptCore/wtf/Forward.h \
@@ -225,6 +242,8 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/NotFound.h \
        JavaScriptCore/wtf/OwnArrayPtr.h \
        JavaScriptCore/wtf/OwnPtr.h \
+       JavaScriptCore/wtf/OwnPtrCommon.h \
+       JavaScriptCore/wtf/PassOwnPtr.h \
        JavaScriptCore/wtf/PassRefPtr.h \
        JavaScriptCore/wtf/Platform.h \
        JavaScriptCore/wtf/PtrAndFlags.h \
@@ -237,6 +256,7 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/RefPtr.h \
        JavaScriptCore/wtf/RefPtrHashMap.h \
        JavaScriptCore/wtf/RetainPtr.h \
+       JavaScriptCore/wtf/SegmentedVector.h \
        JavaScriptCore/wtf/StdLibExtras.h \
        JavaScriptCore/wtf/StringExtras.h \
        JavaScriptCore/wtf/TCPackedCache.h \
@@ -245,19 +265,58 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/ThreadSpecific.h \
        JavaScriptCore/wtf/Threading.h \
        JavaScriptCore/wtf/Threading.cpp \
-       JavaScriptCore/wtf/ThreadingGtk.cpp \
        JavaScriptCore/wtf/ThreadingPthreads.cpp \
+       JavaScriptCore/wtf/TypeTraits.cpp \
+       JavaScriptCore/wtf/TypeTraits.h \
        JavaScriptCore/wtf/UnusedParam.h \
        JavaScriptCore/wtf/Vector.h \
        JavaScriptCore/wtf/VectorTraits.h \
        JavaScriptCore/wtf/gtk/MainThreadGtk.cpp \
+       JavaScriptCore/wtf/gtk/ThreadingGtk.cpp \
        JavaScriptCore/wtf/unicode/Collator.h \
        JavaScriptCore/wtf/unicode/CollatorDefault.cpp \
        JavaScriptCore/wtf/unicode/UTF8.cpp \
        JavaScriptCore/wtf/unicode/UTF8.h \
-       JavaScriptCore/wtf/unicode/Unicode.h \
+       JavaScriptCore/wtf/unicode/Unicode.h
+
+if TARGET_WIN32
+javascriptcore_sources += \
+       JavaScriptCore/wtf/ThreadSpecificWin.cpp \
+       JavaScriptCore/jit/ExecutableAllocatorWin.cpp
+else
+javascriptcore_sources += \
+       JavaScriptCore/jit/ExecutableAllocatorPosix.cpp
+endif
+
+# ----
+# icu unicode backend
+# ----
+if USE_ICU_UNICODE
+javascriptcore_sources += \
        JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp \
        JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h
+endif # USE_ICU_UNICODE
+
+# ----
+# glib unicode backend
+# ----
+if USE_GLIB_UNICODE
+javascriptcore_sources += \
+       JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h \
+       JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp \
+       JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h
+endif
+
+javascriptcore_sources += \
+       JavaScriptCore/wtf/VMTags.h \
+       JavaScriptCore/yarr/RegexCompiler.cpp \
+       JavaScriptCore/yarr/RegexCompiler.h \
+       JavaScriptCore/yarr/RegexInterpreter.cpp \
+       JavaScriptCore/yarr/RegexInterpreter.h \
+       JavaScriptCore/yarr/RegexJIT.cpp \
+       JavaScriptCore/yarr/RegexJIT.h \
+       JavaScriptCore/yarr/RegexParser.h \
+       JavaScriptCore/yarr/RegexPattern.h
 
 # Debug build
 if ENABLE_DEBUG
@@ -275,11 +334,14 @@ javascriptcore_sources += \
        JavaScriptCore/debugger/Debugger.h \
        JavaScriptCore/parser/Lexer.cpp \
        JavaScriptCore/parser/Lexer.h \
+       JavaScriptCore/parser/NodeConstructors.h \
        JavaScriptCore/parser/NodeInfo.h \
        JavaScriptCore/parser/Nodes.cpp \
        JavaScriptCore/parser/Nodes.h \
        JavaScriptCore/parser/Parser.cpp \
        JavaScriptCore/parser/Parser.h \
+       JavaScriptCore/parser/ParserArena.cpp \
+       JavaScriptCore/parser/ParserArena.h \
        JavaScriptCore/parser/ResultType.h \
        JavaScriptCore/parser/SourceCode.h \
        JavaScriptCore/parser/SourceProvider.h \
@@ -311,10 +373,10 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/ConstructData.h \
        JavaScriptCore/runtime/DateConstructor.cpp \
        JavaScriptCore/runtime/DateConstructor.h \
+       JavaScriptCore/runtime/DateConversion.cpp \
+       JavaScriptCore/runtime/DateConversion.h \
        JavaScriptCore/runtime/DateInstance.cpp \
        JavaScriptCore/runtime/DateInstance.h \
-       JavaScriptCore/runtime/DateMath.cpp \
-       JavaScriptCore/runtime/DateMath.h \
        JavaScriptCore/runtime/DatePrototype.cpp \
        JavaScriptCore/runtime/DatePrototype.h \
        JavaScriptCore/runtime/Error.cpp \
@@ -375,6 +437,7 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/NativeErrorConstructor.h \
        JavaScriptCore/runtime/NativeErrorPrototype.cpp \
        JavaScriptCore/runtime/NativeErrorPrototype.h \
+       JavaScriptCore/runtime/NativeFunctionWrapper.h \
        JavaScriptCore/runtime/NumberConstructor.cpp \
        JavaScriptCore/runtime/NumberConstructor.h \
        JavaScriptCore/runtime/NumberObject.cpp \
@@ -419,6 +482,7 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/Tracing.h \
        JavaScriptCore/runtime/UString.cpp \
        JavaScriptCore/runtime/UString.h \
+       JavaScriptCore/wtf/FastAllocBase.h \
        JavaScriptCore/wtf/FastMalloc.cpp \
        JavaScriptCore/wtf/FastMalloc.h \
        JavaScriptCore/wtf/MallocZoneSupport.h \
@@ -433,7 +497,9 @@ javascriptcore_built_nosources += \
        DerivedSources/Grammar.h
 
 javascriptcore_sources += \
-       JavaScriptCore/AllInOneFile.cpp
+       JavaScriptCore/AllInOneFile.cpp \
+       JavaScriptCore/parser/ParserArena.cpp \
+       JavaScriptCore/parser/ParserArena.h
 endif # END ENABLE_DEBUG
 
 DerivedSources/Grammar.h: DerivedSources/Grammar.cpp;
@@ -478,7 +544,6 @@ Programs_minidom_CPPFLAGS = \
 Programs_minidom_CFLAGS = \
        -ansi \
        -fno-strict-aliasing \
-       -O2 \
        $(global_cflags) \
        $(GLOBALDEPS_CFLAGS)
 
@@ -487,6 +552,10 @@ Programs_minidom_LDADD = \
         -lm \
         -lstdc++
 
+Programs_minidom_LDFLAGS = \
+       -no-install \
+       -no-fast-install
+
 # jsc
 Programs_jsc_SOURCES = \
        JavaScriptCore/jsc.cpp
@@ -497,7 +566,6 @@ Programs_jsc_CPPFLAGS = \
 
 Programs_jsc_CXXFLAGS = \
        -fno-strict-aliasing \
-       -O2 \
        $(global_cxxflags) \
        $(global_cflags) \
        $(GLOBALDEPS_CFLAGS) \
@@ -525,6 +593,7 @@ javascriptcore_dist += \
 CLEANFILES += \
        JavaScriptCore/runtime/ArrayPrototype.lut.h \
        JavaScriptCore/runtime/DatePrototype.lut.h \
+       JavaScriptCore/runtime/JSONObject.lut.h \
        JavaScriptCore/runtime/MathObject.lut.h \
        JavaScriptCore/runtime/NumberConstructor.lut.h \
        JavaScriptCore/runtime/RegExpConstructor.lut.h \
index 5e1bb78c767c002524135368f6b2eee2be6caf73..6d9af9bb629b3dce6a4d5fe119d99d5ac77ea574 100644 (file)
@@ -96,79 +96,77 @@ __ZN3JSC10Identifier24checkSameIdentifierTableEPNS_9ExecStateEPNS_7UString3RepE
 __ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
 __ZN3JSC10Identifier5equalEPKNS_7UString3RepEPKc
 __ZN3JSC10JSFunction4infoE
+__ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringE
-__ZN3JSC11JSByteArray15createStructureENS_10JSValuePtrE
+__ZN3JSC11JSByteArray15createStructureENS_7JSValueE
 __ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
-__ZN3JSC11JSImmediate12nonInlineNaNEv
-__ZN3JSC11JSImmediate8toObjectENS_10JSValuePtrEPNS_9ExecStateE
-__ZN3JSC11JSImmediate8toStringENS_10JSValuePtrE
-__ZN3JSC11JSImmediate9prototypeENS_10JSValuePtrEPNS_9ExecStateE
-__ZN3JSC11ProfileNode4sortEPFbRKN3WTF6RefPtrIS0_EES5_E
+__ZN3JSC11ParserArena5resetEv
 __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
 __ZN3JSC12DateInstance4infoE
 __ZN3JSC12JSGlobalData10ClientDataD2Ev
 __ZN3JSC12JSGlobalData12createLeakedEv
 __ZN3JSC12JSGlobalData14sharedInstanceEv
-__ZN3JSC12JSGlobalData6createEv
+__ZN3JSC12JSGlobalData6createEb
 __ZN3JSC12JSGlobalDataD1Ev
-__ZN3JSC12SamplingTool13notifyOfScopeEPNS_9ScopeNodeE
 __ZN3JSC12SamplingTool4dumpEPNS_9ExecStateE
-__ZN3JSC12SamplingTool4stopEv
-__ZN3JSC12SamplingTool5startEj
+__ZN3JSC12SamplingTool5setupEv
 __ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
 __ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC12StringObject14toThisJSStringEPNS_9ExecStateE
 __ZN3JSC12StringObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
 __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC12StringObject4infoE
 __ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringE
 __ZN3JSC12jsNumberCellEPNS_9ExecStateEd
+__ZN3JSC12nonInlineNaNEv
+__ZN3JSC13SamplingFlags4stopEv
+__ZN3JSC13SamplingFlags5startEv
+__ZN3JSC13SamplingFlags7s_flagsE
 __ZN3JSC13StatementNode6setLocEii
 __ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE
 __ZN3JSC14JSGlobalObject10globalExecEv
 __ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
 __ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
-__ZN3JSC14JSGlobalObject14setTimeoutTimeEj
-__ZN3JSC14JSGlobalObject16stopTimeoutCheckEv
-__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrEj
-__ZN3JSC14JSGlobalObject17startTimeoutCheckEv
-__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
+__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE  
 __ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
 __ZN3JSC14JSGlobalObject4markEv
 __ZN3JSC14JSGlobalObjectD2Ev
 __ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
+__ZN3JSC14SamplingThread4stopEv
+__ZN3JSC14SamplingThread5startEj
+__ZN3JSC14TimeoutChecker5resetEv
 __ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
 __ZN3JSC15JSWrapperObject4markEv
 __ZN3JSC15toInt32SlowCaseEdRb
 __ZN3JSC16FunctionBodyNode13finishParsingEPNS_10IdentifierEm
 __ZN3JSC16FunctionBodyNode14copyParametersEv
-__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm0EEERKNS_10SourceCodeEji
+__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_IPNS_12FuncDeclNodeELm0EEERKNS_10SourceCodeEji
 __ZN3JSC16InternalFunction4infoE
 __ZN3JSC16InternalFunction4nameEPNS_12JSGlobalDataE
 __ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF10PassRefPtrINS_9StructureEEERKNS_10IdentifierE
 __ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZN3JSC16ParserRefCounted3refEv
-__ZN3JSC16ParserRefCounted5derefEv
 __ZN3JSC16toUInt32SlowCaseEdRb
 __ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb
 __ZN3JSC17PropertyNameArray3addEPNS_7UString3RepE
-__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectESA_RKNS_7ArgListEE
-__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectES6_RKNS_7ArgListEE
+__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
+__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectES6_RKNS_7ArgListEE
 __ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
 __ZN3JSC18DebuggerActivationC1EPNS_8JSObjectE
 __ZN3JSC19constructEmptyArrayEPNS_9ExecStateE
 __ZN3JSC19initializeThreadingEv
+__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
 __ZN3JSC20constructEmptyObjectEPNS_9ExecStateE
-__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC23AbstractSamplingCounter4dumpEv
+__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_10JSValuePtrEPNS_14JSGlobalObjectE
+__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE
 __ZN3JSC4Heap11objectCountEv
-__ZN3JSC4Heap14allocateNumberEm
 __ZN3JSC4Heap14primaryHeapEndEv
 __ZN3JSC4Heap15recordExtraCostEm
 __ZN3JSC4Heap16primaryHeapBeginEv
@@ -177,14 +175,14 @@ __ZN3JSC4Heap20protectedObjectCountEv
 __ZN3JSC4Heap24setGCProtectNeedsLockingEv
 __ZN3JSC4Heap25protectedObjectTypeCountsEv
 __ZN3JSC4Heap26protectedGlobalObjectCountEv
-__ZN3JSC4Heap4heapENS_10JSValuePtrE
+__ZN3JSC4Heap4heapENS_7JSValueE  
 __ZN3JSC4Heap6isBusyEv
 __ZN3JSC4Heap7collectEv
 __ZN3JSC4Heap7destroyEv
-__ZN3JSC4Heap7protectENS_10JSValuePtrE
+__ZN3JSC4Heap7protectENS_7JSValueE
 __ZN3JSC4Heap8allocateEm
-__ZN3JSC4Heap9unprotectENS_10JSValuePtrE
-__ZN3JSC4callEPNS_9ExecStateENS_10JSValuePtrENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
+__ZN3JSC4Heap9unprotectENS_7JSValueE
+__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
 __ZN3JSC5equalEPKNS_7UString3RepES3_
 __ZN3JSC6JSCell11getCallDataERNS_8CallDataE
 __ZN3JSC6JSCell11getJSNumberEv
@@ -194,8 +192,8 @@ __ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
 __ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE
 __ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC6JSCell3putEPNS_9ExecStateEjNS_10JSValuePtrE
+__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC6JSCell3putEPNS_9ExecStateEjNS_7JSValueE  
 __ZN3JSC6JSCell9getObjectEv
 __ZN3JSC6JSCellnwEmPNS_9ExecStateE
 __ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE
@@ -206,7 +204,6 @@ __ZN3JSC6JSLock6unlockEb
 __ZN3JSC6JSLock9lockCountEv
 __ZN3JSC6JSLockC1EPNS_9ExecStateE
 __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
-__ZN3JSC7ArgList10slowAppendENS_10JSValuePtrE
 __ZN3JSC7CStringD1Ev
 __ZN3JSC7CStringaSERKS0_
 __ZN3JSC7JSArray4infoE
@@ -214,11 +211,17 @@ __ZN3JSC7Profile10restoreAllEv
 __ZN3JSC7Profile5focusEPKNS_11ProfileNodeE
 __ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE
 __ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE
+__ZN3JSC7UString3Rep11computeHashEPKci
 __ZN3JSC7UString3Rep11computeHashEPKti
+__ZN3JSC7UString3Rep12sharedBufferEv
+__ZN3JSC7UString3Rep14createFromUTF8EPKc
 __ZN3JSC7UString3Rep14nullBaseStringE
+__ZN3JSC7UString3Rep6createEPtiN3WTF10PassRefPtrINS3_21CrossThreadRefCountedINS3_16OwnFastMallocPtrItEEEEEE
 __ZN3JSC7UString3Rep7destroyEv
+__ZN3JSC7UString4fromEd
 __ZN3JSC7UString4fromEi
 __ZN3JSC7UString4fromEj
+__ZN3JSC7UString4fromEl
 __ZN3JSC7UString6appendEPKc
 __ZN3JSC7UString6appendERKS0_
 __ZN3JSC7UStringC1EPKc
@@ -228,7 +231,7 @@ __ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
 __ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
 __ZN3JSC8DebuggerC2Ev
 __ZN3JSC8DebuggerD2Ev
-__ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateENS_10JSValuePtrES3_
+__ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateENS_7JSValueES3_
 __ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
 __ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
 __ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
@@ -239,35 +242,38 @@ __ZN3JSC8JSObject15unwrappedObjectEv
 __ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
 __ZN3JSC8JSObject17createInheritorIDEv
 __ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
-__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrEj
-__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateEjNS_10JSValuePtrEj
+__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
+__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEjbRNS_15PutPropertySlotE
+__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateEjNS_7JSValueEj
 __ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_10JSValuePtrE
-__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_10JSValuePtrE
+__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
+__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_7JSValueE  
 __ZN3JSC8JSObject23allocatePropertyStorageEmm
-__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_10JSValuePtrE
+__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE  
 __ZN3JSC8JSObject4markEv
 __ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC8Profiler8profilerEv
-__ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_10JSValuePtrE
+__ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_7JSValueE
 __ZN3JSC8jsStringEPNS_12JSGlobalDataERKNS_7UStringE
 __ZN3JSC9CodeBlockD1Ev
 __ZN3JSC9CodeBlockD2Ev
+__ZN3JSC9Structure13hasTransitionEPNS_7UString3RepEj
 __ZN3JSC9Structure17stopIgnoringLeaksEv
 __ZN3JSC9Structure18startIgnoringLeaksEv
-__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjRm
+__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
 __ZN3JSC9Structure22materializePropertyMapEv
-__ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_10JSValuePtrE
-__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEj
-__ZN3JSC9Structure3getERKNS_10IdentifierERj
-__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjRm
-__ZN3JSC9StructureC1ENS_10JSValuePtrERKNS_8TypeInfoE
+__ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_7JSValueE
+__ZN3JSC9Structure27despecifyDictionaryFunctionERKNS_10IdentifierE
+__ZN3JSC9Structure27despecifyFunctionTransitionEPS0_RKNS_10IdentifierE
+__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEjPNS_6JSCellE
+__ZN3JSC9Structure3getEPKNS_7UString3RepERjRPNS_6JSCellE
+__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
+__ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoE
 __ZN3JSC9StructureD1Ev
-__ZN3JSC9constructEPNS_9ExecStateENS_10JSValuePtrENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
+__ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
 __ZN3JSCeqERKNS_7UStringEPKc
-__ZN3JSCeqERKNS_7UStringES2_
 __ZN3JSCgtERKNS_7UStringES2_
 __ZN3JSCltERKNS_7UStringES2_
 __ZN3WTF10fastCallocEmm
@@ -284,6 +290,7 @@ __ZN3WTF13tryFastCallocEmm
 __ZN3WTF15ThreadCondition4waitERNS_5MutexE
 __ZN3WTF15ThreadCondition6signalEv
 __ZN3WTF15ThreadCondition9broadcastEv
+__ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd
 __ZN3WTF15ThreadConditionC1Ev
 __ZN3WTF15ThreadConditionD1Ev
 __ZN3WTF16callOnMainThreadEPFvPvES0_
@@ -300,6 +307,7 @@ __ZN3WTF23waitForThreadCompletionEjPPv
 __ZN3WTF27releaseFastMallocFreeMemoryEv
 __ZN3WTF28setMainThreadCallbacksPausedEb
 __ZN3WTF36lockAtomicallyInitializedStaticMutexEv
+__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
 __ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
 __ZN3WTF5Mutex4lockEv
 __ZN3WTF5Mutex6unlockEv
@@ -313,31 +321,34 @@ __ZN3WTF8CollatorC1EPKc
 __ZN3WTF8CollatorD1Ev
 __ZN3WTF8fastFreeEPv
 __ZN3WTF9ByteArray6createEm
-__ZNK3JSC10JSValuePtr9toIntegerEPNS_9ExecStateE
 __ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
-__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_10JSValuePtrE
+__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE  
 __ZNK3JSC12DateInstance7getTimeERdRi
 __ZNK3JSC12StringObject12toThisStringEPNS_9ExecStateE
 __ZNK3JSC12StringObject8toStringEPNS_9ExecStateE
 __ZNK3JSC14JSGlobalObject14isDynamicScopeEv
+__ZNK3JSC16FunctionBodyNode14isHostFunctionEv
 __ZNK3JSC16InternalFunction9classInfoEv
 __ZNK3JSC16JSVariableObject16isVariableObjectEv
 __ZNK3JSC16JSVariableObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
 __ZNK3JSC17DebuggerCallFrame10thisObjectEv
 __ZNK3JSC17DebuggerCallFrame12functionNameEv
+__ZNK3JSC17DebuggerCallFrame22calculatedFunctionNameEv
 __ZNK3JSC17DebuggerCallFrame4typeEv
-__ZNK3JSC17DebuggerCallFrame8evaluateERKNS_7UStringERNS_10JSValuePtrE
+__ZNK3JSC17DebuggerCallFrame8evaluateERKNS_7UStringERNS_7JSValueE
 __ZNK3JSC4Heap10statisticsEv
 __ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE
 __ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
 __ZNK3JSC6JSCell14isGetterSetterEv
-__ZNK3JSC6JSCell17getTruncatedInt32ERi
-__ZNK3JSC6JSCell18getTruncatedUInt32ERj
 __ZNK3JSC6JSCell9classInfoEv
 __ZNK3JSC6JSCell9getStringERNS_7UStringE
 __ZNK3JSC6JSCell9getStringEv
 __ZNK3JSC6JSCell9getUInt32ERj
 __ZNK3JSC7ArgList8getSliceEiRS0_
+__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
+__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
+__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
+__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE
 __ZNK3JSC7UString10UTF8StringEb
 __ZNK3JSC7UString14toStrictUInt32EPb
 __ZNK3JSC7UString5asciiEv
@@ -363,6 +374,7 @@ __ZTVN3JSC14JSGlobalObjectE
 __ZTVN3JSC15JSWrapperObjectE
 __ZTVN3JSC16InternalFunctionE
 __ZTVN3JSC16JSVariableObjectE
+__ZTVN3JSC17JSAPIValueWrapperE
 __ZTVN3JSC8JSObjectE
 __ZTVN3JSC8JSStringE
 _jscore_fastmalloc_introspection
diff --git a/JavaScriptCore.gypi b/JavaScriptCore.gypi
new file mode 100644 (file)
index 0000000..2d69c7d
--- /dev/null
@@ -0,0 +1,452 @@
+{
+    'variables': {
+        'javascriptcore_files': [
+            'AllInOneFile.cpp',
+            'API/APICast.h',
+            'API/JavaScript.h',
+            'API/JavaScriptCore.h',
+            'API/JSBase.cpp',
+            'API/JSBase.h',
+            'API/JSBasePrivate.h',
+            'API/JSCallbackConstructor.cpp',
+            'API/JSCallbackConstructor.h',
+            'API/JSCallbackFunction.cpp',
+            'API/JSCallbackFunction.h',
+            'API/JSCallbackObject.cpp',
+            'API/JSCallbackObject.h',
+            'API/JSCallbackObjectFunctions.h',
+            'API/JSClassRef.cpp',
+            'API/JSClassRef.h',
+            'API/JSContextRef.cpp',
+            'API/JSContextRef.h',
+            'API/JSObjectRef.cpp',
+            'API/JSObjectRef.h',
+            'API/JSProfilerPrivate.cpp',
+            'API/JSProfilerPrivate.h',
+            'API/JSRetainPtr.h',
+            'API/JSStringRef.cpp',
+            'API/JSStringRef.h',
+            'API/JSStringRefBSTR.cpp',
+            'API/JSStringRefBSTR.h',
+            'API/JSStringRefCF.cpp',
+            'API/JSStringRefCF.h',
+            'API/JSValueRef.cpp',
+            'API/JSValueRef.h',
+            'API/OpaqueJSString.cpp',
+            'API/OpaqueJSString.h',
+            'API/tests/JSNode.h',
+            'API/tests/JSNodeList.h',
+            'API/tests/Node.h',
+            'API/tests/NodeList.h',
+            'API/WebKitAvailability.h',
+            'assembler/AbstractMacroAssembler.h',
+            'assembler/ARMv7Assembler.h',
+            'assembler/AssemblerBuffer.h',
+            'assembler/CodeLocation.h',
+            'assembler/MacroAssembler.h',
+            'assembler/MacroAssemblerARMv7.h',
+            'assembler/MacroAssemblerCodeRef.h',
+            'assembler/MacroAssemblerX86.h',
+            'assembler/MacroAssemblerX86_64.h',
+            'assembler/MacroAssemblerX86Common.h',
+            'assembler/X86Assembler.h',
+            'bytecode/CodeBlock.cpp',
+            'bytecode/CodeBlock.h',
+            'bytecode/EvalCodeCache.h',
+            'bytecode/Instruction.h',
+            'bytecode/JumpTable.cpp',
+            'bytecode/JumpTable.h',
+            'bytecode/Opcode.cpp',
+            'bytecode/Opcode.h',
+            'bytecode/SamplingTool.cpp',
+            'bytecode/SamplingTool.h',
+            'bytecode/StructureStubInfo.cpp',
+            'bytecode/StructureStubInfo.h',
+            'bytecompiler/BytecodeGenerator.cpp',
+            'bytecompiler/BytecodeGenerator.h',
+            'bytecompiler/Label.h',
+            'bytecompiler/LabelScope.h',
+            'bytecompiler/RegisterID.h',
+            'config.h',
+            'debugger/Debugger.cpp',
+            'debugger/Debugger.h',
+            'debugger/DebuggerActivation.cpp',
+            'debugger/DebuggerActivation.h',
+            'debugger/DebuggerCallFrame.cpp',
+            'debugger/DebuggerCallFrame.h',
+            'icu/unicode/parseerr.h',
+            'icu/unicode/platform.h',
+            'icu/unicode/putil.h',
+            'icu/unicode/uchar.h',
+            'icu/unicode/ucnv.h',
+            'icu/unicode/ucnv_err.h',
+            'icu/unicode/ucol.h',
+            'icu/unicode/uconfig.h',
+            'icu/unicode/uenum.h',
+            'icu/unicode/uiter.h',
+            'icu/unicode/uloc.h',
+            'icu/unicode/umachine.h',
+            'icu/unicode/unorm.h',
+            'icu/unicode/urename.h',
+            'icu/unicode/uset.h',
+            'icu/unicode/ustring.h',
+            'icu/unicode/utf.h',
+            'icu/unicode/utf16.h',
+            'icu/unicode/utf8.h',
+            'icu/unicode/utf_old.h',
+            'icu/unicode/utypes.h',
+            'icu/unicode/uversion.h',
+            'interpreter/CachedCall.h',
+            'interpreter/CallFrame.cpp',
+            'interpreter/CallFrame.h',
+            'interpreter/CallFrameClosure.h',
+            'interpreter/Interpreter.cpp',
+            'interpreter/Interpreter.h',
+            'interpreter/Register.h',
+            'interpreter/RegisterFile.cpp',
+            'interpreter/RegisterFile.h',
+            'JavaScriptCorePrefix.h',
+            'jit/ExecutableAllocator.cpp',
+            'jit/ExecutableAllocator.h',
+            'jit/ExecutableAllocatorFixedVMPool.cpp',
+            'jit/ExecutableAllocatorPosix.cpp',
+            'jit/ExecutableAllocatorWin.cpp',
+            'jit/JIT.cpp',
+            'jit/JIT.h',
+            'jit/JITArithmetic.cpp',
+            'jit/JITCall.cpp',
+            'jit/JITCode.h',
+            'jit/JITInlineMethods.h',
+            'jit/JITOpcodes.cpp',
+            'jit/JITPropertyAccess.cpp',
+            'jit/JITStubCall.h',
+            'jit/JITStubs.cpp',
+            'jit/JITStubs.h',
+            'jsc.cpp',
+            'os-win32/stdbool.h',
+            'os-win32/stdint.h',
+            'parser/Lexer.cpp',
+            'parser/Lexer.h',
+            'parser/NodeConstructors.h',
+            'parser/NodeInfo.h',
+            'parser/Nodes.cpp',
+            'parser/Nodes.h',
+            'parser/Parser.cpp',
+            'parser/Parser.h',
+            'parser/ParserArena.cpp',
+            'parser/ParserArena.h',
+            'parser/ResultType.h',
+            'parser/SourceCode.h',
+            'parser/SourceProvider.h',
+            'pcre/pcre.h',
+            'pcre/pcre_compile.cpp',
+            'pcre/pcre_exec.cpp',
+            'pcre/pcre_internal.h',
+            'pcre/pcre_tables.cpp',
+            'pcre/pcre_ucp_searchfuncs.cpp',
+            'pcre/pcre_xclass.cpp',
+            'pcre/ucpinternal.h',
+            'pcre/ucptable.cpp',
+            'profiler/CallIdentifier.h',
+            'profiler/HeavyProfile.cpp',
+            'profiler/HeavyProfile.h',
+            'profiler/Profile.cpp',
+            'profiler/Profile.h',
+            'profiler/ProfileGenerator.cpp',
+            'profiler/ProfileGenerator.h',
+            'profiler/ProfileNode.cpp',
+            'profiler/ProfileNode.h',
+            'profiler/Profiler.cpp',
+            'profiler/Profiler.h',
+            'profiler/ProfilerServer.h',
+            'profiler/TreeProfile.cpp',
+            'profiler/TreeProfile.h',
+            'runtime/ArgList.cpp',
+            'runtime/ArgList.h',
+            'runtime/Arguments.cpp',
+            'runtime/Arguments.h',
+            'runtime/ArrayConstructor.cpp',
+            'runtime/ArrayConstructor.h',
+            'runtime/ArrayPrototype.cpp',
+            'runtime/ArrayPrototype.h',
+            'runtime/BatchedTransitionOptimizer.h',
+            'runtime/BooleanConstructor.cpp',
+            'runtime/BooleanConstructor.h',
+            'runtime/BooleanObject.cpp',
+            'runtime/BooleanObject.h',
+            'runtime/BooleanPrototype.cpp',
+            'runtime/BooleanPrototype.h',
+            'runtime/CallData.cpp',
+            'runtime/CallData.h',
+            'runtime/ClassInfo.h',
+            'runtime/Collector.cpp',
+            'runtime/Collector.h',
+            'runtime/CollectorHeapIterator.h',
+            'runtime/CommonIdentifiers.cpp',
+            'runtime/CommonIdentifiers.h',
+            'runtime/Completion.cpp',
+            'runtime/Completion.h',
+            'runtime/ConstructData.cpp',
+            'runtime/ConstructData.h',
+            'runtime/DateConstructor.cpp',
+            'runtime/DateConstructor.h',
+            'runtime/DateConversion.cpp',
+            'runtime/DateConversion.h',
+            'runtime/DateInstance.cpp',
+            'runtime/DateInstance.h',
+            'runtime/DatePrototype.cpp',
+            'runtime/DatePrototype.h',
+            'runtime/Error.cpp',
+            'runtime/Error.h',
+            'runtime/ErrorConstructor.cpp',
+            'runtime/ErrorConstructor.h',
+            'runtime/ErrorInstance.cpp',
+            'runtime/ErrorInstance.h',
+            'runtime/ErrorPrototype.cpp',
+            'runtime/ErrorPrototype.h',
+            'runtime/ExceptionHelpers.cpp',
+            'runtime/ExceptionHelpers.h',
+            'runtime/FunctionConstructor.cpp',
+            'runtime/FunctionConstructor.h',
+            'runtime/FunctionPrototype.cpp',
+            'runtime/FunctionPrototype.h',
+            'runtime/GetterSetter.cpp',
+            'runtime/GetterSetter.h',
+            'runtime/GlobalEvalFunction.cpp',
+            'runtime/GlobalEvalFunction.h',
+            'runtime/Identifier.cpp',
+            'runtime/Identifier.h',
+            'runtime/InitializeThreading.cpp',
+            'runtime/InitializeThreading.h',
+            'runtime/InternalFunction.cpp',
+            'runtime/InternalFunction.h',
+            'runtime/JSActivation.cpp',
+            'runtime/JSActivation.h',
+            'runtime/JSArray.cpp',
+            'runtime/JSArray.h',
+            'runtime/JSByteArray.cpp',
+            'runtime/JSByteArray.h',
+            'runtime/JSCell.cpp',
+            'runtime/JSCell.h',
+            'runtime/JSFunction.cpp',
+            'runtime/JSFunction.h',
+            'runtime/JSGlobalData.cpp',
+            'runtime/JSGlobalData.h',
+            'runtime/JSGlobalObject.cpp',
+            'runtime/JSGlobalObject.h',
+            'runtime/JSGlobalObjectFunctions.cpp',
+            'runtime/JSGlobalObjectFunctions.h',
+            'runtime/JSImmediate.cpp',
+            'runtime/JSImmediate.h',
+            'runtime/JSLock.cpp',
+            'runtime/JSLock.h',
+            'runtime/JSNotAnObject.cpp',
+            'runtime/JSNotAnObject.h',
+            'runtime/JSNumberCell.cpp',
+            'runtime/JSNumberCell.h',
+            'runtime/JSObject.cpp',
+            'runtime/JSObject.h',
+            'runtime/JSONObject.cpp',
+            'runtime/JSONObject.h',
+            'runtime/JSPropertyNameIterator.cpp',
+            'runtime/JSPropertyNameIterator.h',
+            'runtime/JSStaticScopeObject.cpp',
+            'runtime/JSStaticScopeObject.h',
+            'runtime/JSString.cpp',
+            'runtime/JSString.h',
+            'runtime/JSType.h',
+            'runtime/JSValue.cpp',
+            'runtime/JSValue.h',
+            'runtime/JSVariableObject.cpp',
+            'runtime/JSVariableObject.h',
+            'runtime/JSWrapperObject.cpp',
+            'runtime/JSWrapperObject.h',
+            'runtime/LiteralParser.cpp',
+            'runtime/LiteralParser.h',
+            'runtime/Lookup.cpp',
+            'runtime/Lookup.h',
+            'runtime/MathObject.cpp',
+            'runtime/MathObject.h',
+            'runtime/NativeErrorConstructor.cpp',
+            'runtime/NativeErrorConstructor.h',
+            'runtime/NativeErrorPrototype.cpp',
+            'runtime/NativeErrorPrototype.h',
+            'runtime/NativeFunctionWrapper.h',
+            'runtime/NumberConstructor.cpp',
+            'runtime/NumberConstructor.h',
+            'runtime/NumberObject.cpp',
+            'runtime/NumberObject.h',
+            'runtime/NumberPrototype.cpp',
+            'runtime/NumberPrototype.h',
+            'runtime/ObjectConstructor.cpp',
+            'runtime/ObjectConstructor.h',
+            'runtime/ObjectPrototype.cpp',
+            'runtime/ObjectPrototype.h',
+            'runtime/Operations.cpp',
+            'runtime/Operations.h',
+            'runtime/PropertyMapHashTable.h',
+            'runtime/PropertyNameArray.cpp',
+            'runtime/PropertyNameArray.h',
+            'runtime/PropertySlot.cpp',
+            'runtime/PropertySlot.h',
+            'runtime/Protect.h',
+            'runtime/PrototypeFunction.cpp',
+            'runtime/PrototypeFunction.h',
+            'runtime/PutPropertySlot.h',
+            'runtime/RegExp.cpp',
+            'runtime/RegExp.h',
+            'runtime/RegExpConstructor.cpp',
+            'runtime/RegExpConstructor.h',
+            'runtime/RegExpMatchesArray.h',
+            'runtime/RegExpObject.cpp',
+            'runtime/RegExpObject.h',
+            'runtime/RegExpPrototype.cpp',
+            'runtime/RegExpPrototype.h',
+            'runtime/ScopeChain.cpp',
+            'runtime/ScopeChain.h',
+            'runtime/ScopeChainMark.h',
+            'runtime/SmallStrings.cpp',
+            'runtime/SmallStrings.h',
+            'runtime/StringConstructor.cpp',
+            'runtime/StringConstructor.h',
+            'runtime/StringObject.cpp',
+            'runtime/StringObject.h',
+            'runtime/StringObjectThatMasqueradesAsUndefined.h',
+            'runtime/StringPrototype.cpp',
+            'runtime/StringPrototype.h',
+            'runtime/Structure.cpp',
+            'runtime/Structure.h',
+            'runtime/StructureChain.cpp',
+            'runtime/StructureChain.h',
+            'runtime/StructureTransitionTable.h',
+            'runtime/SymbolTable.h',
+            'runtime/TimeoutChecker.cpp',
+            'runtime/TimeoutChecker.h',
+            'runtime/Tracing.h',
+            'runtime/TypeInfo.h',
+            'runtime/UString.cpp',
+            'runtime/UString.h',
+            'wrec/CharacterClass.cpp',
+            'wrec/CharacterClass.h',
+            'wrec/CharacterClassConstructor.cpp',
+            'wrec/CharacterClassConstructor.h',
+            'wrec/Escapes.h',
+            'wrec/Quantifier.h',
+            'wrec/WREC.cpp',
+            'wrec/WREC.h',
+            'wrec/WRECFunctors.cpp',
+            'wrec/WRECFunctors.h',
+            'wrec/WRECGenerator.cpp',
+            'wrec/WRECGenerator.h',
+            'wrec/WRECParser.cpp',
+            'wrec/WRECParser.h',
+            'wtf/AlwaysInline.h',
+            'wtf/ASCIICType.h',
+            'wtf/Assertions.cpp',
+            'wtf/Assertions.h',
+            'wtf/AVLTree.h',
+            'wtf/ByteArray.cpp',
+            'wtf/ByteArray.h',
+            'wtf/chromium/ChromiumThreading.h',
+            'wtf/chromium/MainThreadChromium.cpp',
+            'wtf/CrossThreadRefCounted.h',
+            'wtf/CurrentTime.cpp',
+            'wtf/CurrentTime.h',
+            'wtf/DateMath.cpp',
+            'wtf/DateMath.h',
+            'wtf/Deque.h',
+            'wtf/DisallowCType.h',
+            'wtf/dtoa.cpp',
+            'wtf/dtoa.h',
+            'wtf/FastAllocBase.h',
+            'wtf/FastMalloc.cpp',
+            'wtf/FastMalloc.h',
+            'wtf/Forward.h',
+            'wtf/GetPtr.h',
+            'wtf/GOwnPtr.cpp',
+            'wtf/GOwnPtr.h',
+            'wtf/gtk/MainThreadGtk.cpp',
+            'wtf/gtk/ThreadingGtk.cpp',
+            'wtf/HashCountedSet.h',
+            'wtf/HashFunctions.h',
+            'wtf/HashIterators.h',
+            'wtf/HashMap.h',
+            'wtf/HashSet.h',
+            'wtf/HashTable.cpp',
+            'wtf/HashTable.h',
+            'wtf/HashTraits.h',
+            'wtf/ListHashSet.h',
+            'wtf/ListRefPtr.h',
+            'wtf/Locker.h',
+            'wtf/MainThread.cpp',
+            'wtf/MainThread.h',
+            'wtf/MallocZoneSupport.h',
+            'wtf/MathExtras.h',
+            'wtf/MessageQueue.h',
+            'wtf/Noncopyable.h',
+            'wtf/NotFound.h',
+            'wtf/OwnArrayPtr.h',
+            'wtf/OwnFastMallocPtr.h',
+            'wtf/OwnPtr.h',
+            'wtf/OwnPtrCommon.h',
+            'wtf/OwnPtrWin.cpp',
+            'wtf/PassOwnPtr.h',
+            'wtf/PassRefPtr.h',
+            'wtf/Platform.h',
+            'wtf/PtrAndFlags.h',
+            'wtf/qt/MainThreadQt.cpp',
+            'wtf/qt/ThreadingQt.cpp',
+            'wtf/RandomNumber.cpp',
+            'wtf/RandomNumber.h',
+            'wtf/RandomNumberSeed.h',
+            'wtf/RefCounted.h',
+            'wtf/RefCountedLeakCounter.cpp',
+            'wtf/RefCountedLeakCounter.h',
+            'wtf/RefPtr.h',
+            'wtf/RefPtrHashMap.h',
+            'wtf/RetainPtr.h',
+            'wtf/SegmentedVector.h',
+            'wtf/StdLibExtras.h',
+            'wtf/StringExtras.h',
+            'wtf/TCPackedCache.h',
+            'wtf/TCPageMap.h',
+            'wtf/TCSpinLock.h',
+            'wtf/TCSystemAlloc.cpp',
+            'wtf/TCSystemAlloc.h',
+            'wtf/Threading.cpp',
+            'wtf/Threading.h',
+            'wtf/ThreadingNone.cpp',
+            'wtf/ThreadingPthreads.cpp',
+            'wtf/ThreadingWin.cpp',
+            'wtf/ThreadSpecific.h',
+            'wtf/ThreadSpecificWin.cpp',
+            'wtf/TypeTraits.cpp',
+            'wtf/TypeTraits.h',
+            'wtf/unicode/Collator.h',
+            'wtf/unicode/CollatorDefault.cpp',
+            'wtf/unicode/glib/UnicodeGLib.cpp',
+            'wtf/unicode/glib/UnicodeGLib.h',
+            'wtf/unicode/glib/UnicodeMacrosFromICU.h',
+            'wtf/unicode/icu/CollatorICU.cpp',
+            'wtf/unicode/icu/UnicodeIcu.h',
+            'wtf/unicode/qt4/UnicodeQt4.h',
+            'wtf/unicode/Unicode.h',
+            'wtf/unicode/UTF8.cpp',
+            'wtf/unicode/UTF8.h',
+            'wtf/UnusedParam.h',
+            'wtf/Vector.h',
+            'wtf/VectorTraits.h',
+            'wtf/VMTags.h',
+            'wtf/win/MainThreadWin.cpp',
+            'wtf/wx/MainThreadWx.cpp',
+            'yarr/RegexCompiler.cpp',
+            'yarr/RegexCompiler.h',
+            'yarr/RegexInterpreter.cpp',
+            'yarr/RegexInterpreter.h',
+            'yarr/RegexJIT.cpp',
+            'yarr/RegexJIT.h',
+            'yarr/RegexParser.h',
+            'yarr/RegexPattern.h',
+        ]
+    }
+}
index 7be22ae4303613294829b9ffab6fea2ee63a560e..4cff982bcfbad61da96c0fcc320d0a9d9dff294f 100644 (file)
@@ -1,10 +1,10 @@
-__ZN3JSC19initializeThreadingEv
-dyld_stub_binding_helper
-__ZN3JSCL23initializeThreadingOnceEv
-__ZN3WTF19initializeThreadingEv
+// JavaScriptCore order file generated on Fri Feb 19 17:16:12 -0800 2010 by Andrew Turley (aturley@apple.com)
+// Scenario included SpringBoard launch/unlock with passcode, launching all apps, MobileSafari page loads,
+// keyboard usage and general app interaction.
 __ZN3WTF10fastMallocEm
 __ZN3WTF10fastMallocILb1EEEPvm
 __ZN3WTF20TCMalloc_ThreadCache10InitModuleEv
+ stub helpers
 __ZN3WTFL15InitSizeClassesEv
 __Z20TCMalloc_SystemAllocmPmm
 __ZN3WTF20TCMalloc_ThreadCache22CreateCacheIfNecessaryEv
@@ -13,23 +13,23 @@ __ZN3WTF25TCMalloc_Central_FreeList18FetchFromSpansSafeEv
 __ZN3WTF17TCMalloc_PageHeap10AllocLargeEm
 __ZN3WTF17TCMalloc_PageHeap8GrowHeapEm
 __ZN3WTFL13MetaDataAllocEm
-__Z22TCMalloc_SystemReleasePvm
+__ZN3WTF17TCMalloc_PageHeap6DeleteEPNS_4SpanE
+__ZN3WTF16fastZeroedMallocEm
+__ZN3WTF8fastFreeEPv
+__ZN3WTF12isMainThreadEv
 __ZN3WTFL25identifierByPthreadHandleERKP17_opaque_pthread_t
 __ZN3WTFL35establishIdentifierForPthreadHandleERP17_opaque_pthread_t
 __ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSA_IS3_EEEESB_E6rehashEi
-__ZN3WTF16fastZeroedMallocEm
-__ZN3WTF8fastFreeEPv
-__ZN3WTF22initializeMainNSThreadEv
+__ZN3JSC19initializeThreadingEv
+__ZN3JSCL23initializeThreadingOnceEv
+__ZN3WTF19initializeThreadingEv
 __ZN3WTF20initializeMainThreadEv
 __ZN3WTF5MutexC1Ev
+__ZN3WTF28initializeMainThreadPlatformEv
 __ZN3JSC17initializeUStringEv
-__ZN3JSC12initDateMathEv
+__ZN3WTF15initializeDatesEv
 __ZN3WTF11currentTimeEv
 __ZN3WTF14FastMallocZone4sizeEP14_malloc_zone_tPKv
-__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv
-__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_
-__ZN3WTF25TCMalloc_Central_FreeList11InsertRangeEPvS1_i
-__ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv
 __ZN3WTF36lockAtomicallyInitializedStaticMutexEv
 __ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
 __ZN3JSC8DebuggerC2Ev
@@ -39,91 +39,101 @@ __ZN3WTF6strtodEPKcPPc
 __ZN3JSC6JSLock12DropAllLocksC1Eb
 __ZN3JSCL17createJSLockCountEv
 __ZN3JSC6JSLock12DropAllLocksD1Ev
+__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv
+__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_
+__ZN3WTF25TCMalloc_Central_FreeList11InsertRangeEPvS1_i
+__ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv
+__ZN3WTF5MutexD1Ev
 __ZN3WTF15ThreadConditionC1Ev
 __ZN3WTF12createThreadEPFPvS0_ES0_PKc
 __ZN3WTF20createThreadInternalEPFPvS0_ES0_PKc
-__ZN3WTF15ThreadCondition4waitERNS_5MutexE
 __ZN3WTFL16threadEntryPointEPv
-__ZN3WTF5MutexD1Ev
+__ZN3WTF21setThreadNameInternalEPKc
 __ZN3WTF13currentThreadEv
 __ZN3WTF15ThreadCondition9broadcastEv
 __ZN3WTF15ThreadCondition6signalEv
 __ZN3WTF16callOnMainThreadEPFvPvES0_
-__ZN3WTF6VectorINS_19FunctionWithContextELm0EE14expandCapacityEm
+__ZN3WTF5DequeINS_19FunctionWithContextEE14expandCapacityEv
 __ZN3WTF37scheduleDispatchFunctionsOnMainThreadEv
-__ZN3WTF12mainNSThreadEv
 -[WTFMainThreadCaller call]
 __ZN3WTF31dispatchFunctionsFromMainThreadEv
 __ZN3WTF11fastReallocEPvm
 __ZN3WTF11fastReallocILb1EEEPvS1_m
+__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
+__ZL30calculateCompiledPatternLengthPKti24JSRegExpIgnoreCaseOptionR11CompileDataR9ErrorCode
+__ZL11checkEscapePPKtS0_P9ErrorCodeib
+__ZL13compileBranchiPiPPhPPKtS3_P9ErrorCodeS_S_R11CompileData
+__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
+__ZL5matchPKtPKhiR9MatchData
 __ZN3WTF25TCMalloc_Central_FreeList11ShrinkCacheEib
 __ZN3JSC7UStringC1EPKti
 __ZN3JSC7UStringC2EPKti
 __ZN3JSC12JSGlobalData12createLeakedEv
-__ZN3JSC12JSGlobalDataC2Eb
-__ZN3JSC11InterpreterC1Ev
-__ZN3JSC11InterpreterC2Ev
-__ZN3JSC11Interpreter14privateExecuteENS0_13ExecutionFlagEPNS_12RegisterFileEPNS_9ExecStateEPNS_10JSValuePtrE
-__ZN3WTF7HashMapIPvN3JSC8OpcodeIDENS_7PtrHashIS1_EENS_10HashTraitsIS1_EENS6_IS3_EEE3addERKS1_RKS3_
-__ZN3WTF9HashTableIPvSt4pairIS1_N3JSC8OpcodeIDEENS_18PairFirstExtractorIS5_EENS_7PtrHashIS1_EENS_14PairHashTraitsINS_10HashTraitsIS1_EENSB_IS4_EEEESC_E6expandEv
-__ZN3JSC9StructureC1ENS_10JSValuePtrERKNS_8TypeInfoE
+__ZN3JSC9Structure18startIgnoringLeaksEv
+__ZN3JSC7VPtrSetC2Ev
+__ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoE
 __ZN3JSC7JSArrayC1EN3WTF10PassRefPtrINS_9StructureEEE
 __ZN3JSC7JSArrayD1Ev
 __ZN3JSC7JSArrayD2Ev
 __ZN3WTF10RefCountedIN3JSC9StructureEE5derefEv
 __ZN3JSC9StructureD1Ev
 __ZN3JSC9StructureD2Ev
-__ZN3JSC11JSByteArray15createStructureENS_10JSValuePtrE
+__ZN3JSC11JSByteArray15createStructureENS_7JSValueE
 __ZN3JSC11JSByteArrayD1Ev
 __ZN3JSC8JSStringD1Ev
-__ZN3WTF6RefPtrIN3JSC7UString3RepEED1Ev
 __ZN3JSC10JSFunctionD1Ev
-__ZN3JSC8JSObjectD2Ev
+__ZN3JSC12JSGlobalDataC2EbRKNS_7VPtrSetE
 __ZN3JSC21createIdentifierTableEv
 __ZN3JSC17CommonIdentifiersC1EPNS_12JSGlobalDataE
 __ZN3JSC17CommonIdentifiersC2EPNS_12JSGlobalDataE
 __ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKc
 __ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addIPKcNS1_17CStringTranslatorEEESt4pairINS_24HashTableIteratorAdapterINS_9HashTableIS4_S4_NS_17IdentityExtractorIS4_EES6_S8_S8_EES4_EEbERKT_
 __ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7StrHashIS4_EENS_10HashTraitsIS4_EESA_E6rehashEi
-__ZN3WTF7HashMapIPKcNS_6RefPtrIN3JSC7UString3RepEEENS_7PtrHashIS2_EENS_10HashTraitsIS2_EENSA_IS7_EEE3addERKS2_RKS7_
 __ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC7UString3RepEEEENS_18PairFirstExtractorIS9_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSF_IS8_EEEESG_E6rehashEi
 __ZN3JSC12SmallStringsC1Ev
 __ZN3JSC5LexerC1EPNS_12JSGlobalDataE
 __ZN3JSC5LexerC2EPNS_12JSGlobalDataE
+__ZN3JSC11InterpreterC1Ev
+__ZN3JSC11InterpreterC2Ev
+__ZN3JSC11Interpreter14privateExecuteENS0_13ExecutionFlagEPNS_12RegisterFileEPNS_9ExecStateEPNS_7JSValueE
+__ZN3WTF9HashTableIPKvSt4pairIS2_N3JSC8OpcodeIDEENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS5_EEEESD_E6expandEv
+__ZN3JSC14TimeoutCheckerC1Ev
 __ZN3JSC4HeapC1EPNS_12JSGlobalDataE
 __ZN3JSC27startProfilerServerIfNeededEv
 +[ProfilerServer sharedProfileServer]
 -[ProfilerServer init]
-__ZN3JSC11Interpreter10initializeEPNS_12JSGlobalDataE
+__ZN3JSC9Structure17stopIgnoringLeaksEv
 __ZN3JSC4Heap8allocateEm
 __ZN3JSCL13allocateBlockILNS_8HeapTypeE0EEEPNS_14CollectorBlockEv
+__ZN3JSC4Heap4heapENS_7JSValueE
+__ZN3JSC4Heap7protectENS_7JSValueE
+__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi
 __ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
 __ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
-__ZN3JSC14JSGlobalObject5resetENS_10JSValuePtrE
+__ZN3JSC14JSGlobalObject5resetENS_7JSValueE
 __ZN3JSC4Heap12heapAllocateILNS_8HeapTypeE0EEEPvm
-__ZN3JSC17FunctionPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
 __ZN3JSC8jsStringEPNS_12JSGlobalDataERKNS_7UStringE
 __ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
 __ZN3JSC7UStringC1EPKc
 __ZN3JSCL9createRepEPKc
-__ZN3JSC8JSObject9putDirectERKNS_10IdentifierENS_10JSValuePtrEjbRNS_15PutPropertySlotE
-__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjRm
-__ZN3JSC9Structure3getERKNS_10IdentifierERj
-__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjRm
-__ZN3JSC9Structure3putERKNS_10IdentifierEj
-__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEj
-__ZN3JSC17FunctionPrototype21addFunctionPropertiesEPNS_9ExecStateEPNS_9StructureE
-__ZN3JSC17PrototypeFunctionC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectESA_RKNS_7ArgListEE
+__ZN3JSC8JSObject17putDirectInternalERKNS_10IdentifierENS_7JSValueEjbRNS_15PutPropertySlotEPNS_6JSCellE
+__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
+__ZN3JSC9Structure3getEPKNS_7UString3RepERjRPNS_6JSCellE
+__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
+__ZN3JSC9Structure3putERKNS_10IdentifierEjPNS_6JSCellE
+__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEjPNS_6JSCellE
+__ZN3JSC17FunctionPrototype21addFunctionPropertiesEPNS_9ExecStateEPNS_9StructureEPPNS_17PrototypeFunctionES7_
+__ZN3JSC17PrototypeFunctionC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
 __ZN3JSC8JSObject34putDirectFunctionWithoutTransitionEPNS_9ExecStateEPNS_16InternalFunctionEj
 __ZN3JSC15ObjectPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
 __ZN3JSC9Structure26rehashPropertyMapHashTableEj
 __ZN3JSC15StringPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
 __ZN3JSC16BooleanPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
 __ZN3JSC15NumberPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC12jsNumberCellEPNS_9ExecStateEd
 __ZN3JSCL13allocateBlockILNS_8HeapTypeE1EEEPNS_14CollectorBlockEv
 __ZN3JSC15RegExpPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
 __ZN3JSC14ErrorPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
+__ZN3WTF6RefPtrIN3JSC7UString3RepEED1Ev
 __ZN3JSC20NativeErrorPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringES9_
 __ZN3JSC17ObjectConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_15ObjectPrototypeE
 __ZN3JSC19FunctionConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_17FunctionPrototypeE
@@ -142,118 +152,141 @@ __ZN3JSC16ErrorConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPN
 __ZNK3JSC13ErrorInstance9classInfoEv
 __ZN3JSC22NativeErrorConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_20NativeErrorPrototypeE
 __ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPNS_7UString3RepE
+__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addERKS4_
 __ZN3JSC10MathObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
 __ZN3JSC12SmallStrings24singleCharacterStringRepEh
+__ZN3JSC7JSValueC1EPNS_9ExecStateEd
 __ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS2_16SymbolTableEntryENS2_17IdentifierRepHashENS_10HashTraitsIS5_EENS2_26SymbolTableIndexHashTraitsEE3addEPS4_RKS6_
 __ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_16SymbolTableEntryEENS_18PairFirstExtractorIS8_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS5_EENS2_26SymbolTableIndexHashTraitsEEESE_E6expandEv
-__ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_10JSValuePtrE
+__ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_7JSValueE
 __ZN3JSC9Structure17copyPropertyTableEv
-__ZN3JSC14JSGlobalObject14setTimeoutTimeEj
 __ZN3JSC14JSGlobalObject10globalExecEv
 __ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
-__ZN3JSC4Heap4heapENS_10JSValuePtrE
-__ZN3JSC4Heap7protectENS_10JSValuePtrE
-__ZN3WTF7HashMapIPN3JSC6JSCellEjNS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS6_IjEEE3addERKS3_RKj
-__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi
+__ZN3JSC4Heap9unprotectENS_7JSValueE
 __ZN3JSC6JSCellnwEmPNS_9ExecStateE
 __ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPNS_7UString3RepE
 __ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
-__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC14JSGlobalObject17startTimeoutCheckEv
-__ZN3JSC11Interpreter17resetTimeoutCheckEv
-__ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_10JSValuePtrE
+__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC7UString3Rep12sharedBufferEv
+__ZN3JSC14TimeoutChecker5resetEv
+__ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_7JSValueE
 __ZN3JSC6JSLock4lockEb
 __ZN3JSC6Parser5parseINS_11ProgramNodeEEEN3WTF10PassRefPtrIT_EEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
 __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
 __ZN3JSC7UStringaSEPKc
 __Z10jscyyparsePv
 __ZN3JSC5Lexer3lexEPvS1_
-__ZN3WTF6VectorItLm0EE6appendItEEvRKT_
-__ZN3WTF6VectorItLm0EE15reserveCapacityEm
 __ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKti
 __ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addINS1_11UCharBufferENS1_21UCharBufferTranslatorEEESt4pairINS_24HashTableIteratorAdapterINS_9HashTableIS4_S4_NS_17IdentityExtractorIS4_EES6_S8_S8_EES4_EEbERKT_
-__ZN3WTF7HashSetIPN3JSC16ParserRefCountedENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
-__ZN3WTF9HashTableIPN3JSC16ParserRefCountedES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3JSC16ParserRefCountedC2EPNS_12JSGlobalDataE
-__ZN3JSC16ParserRefCounted3refEv
-__ZL14makeAssignNodePvPN3JSC14ExpressionNodeENS0_8OperatorES2_bbiii
-__ZNK3JSC11ResolveNode10isLocationEv
-__ZNK3JSC11ResolveNode13isResolveNodeEv
-__ZN3JSC14SourceElements6appendEN3WTF10PassRefPtrINS_13StatementNodeEEE
+__ZN3WTF15SegmentedVectorIN3JSC10IdentifierELm64EE6appendIS2_EEvRKT_
+__ZN3JSC5Lexer10sourceCodeEiii
+__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeE
+__ZN3JSC20ParserArenaDeletablenwEmPNS_12JSGlobalDataE
+__ZN3WTF6VectorIPN3JSC20ParserArenaDeletableELm0EE14expandCapacityEm
+__ZN3WTF6VectorIPN3JSC12FuncDeclNodeELm0EE14expandCapacityEm
+__ZN3JSC14SourceElements6appendEPNS_13StatementNodeE
 __ZNK3JSC13StatementNode16isEmptyStatementEv
-__Z21mergeDeclarationListsIPN3JSC20ParserRefCountedDataIN3WTF6VectorINS2_6RefPtrINS0_12FuncDeclNodeEEELm0EEEEEET_SA_SA_
+__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm
+__ZN3JSC5Lexer10scanRegExpEv
+__ZN3WTF6VectorItLm0EE14expandCapacityEmPKt
+__ZN3JSC7UStringC2ERKN3WTF6VectorItLm0EEE
 __ZL20makeFunctionCallNodePvN3JSC8NodeInfoIPNS0_14ExpressionNodeEEENS1_IPNS0_13ArgumentsNodeEEEiii
 __ZNK3JSC15DotAccessorNode10isLocationEv
 __ZNK3JSC14ExpressionNode13isResolveNodeEv
 __ZNK3JSC14ExpressionNode21isBracketAccessorNodeEv
-__ZN3WTF7HashMapIPN3JSC16ParserRefCountedEjNS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS6_IjEEE3addERKS3_RKj
-__ZN3WTF9HashTableIPN3JSC16ParserRefCountedESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi
-__ZN3JSC6Parser16didFinishParsingEPNS_14SourceElementsEPNS_20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEEEPNS3_INS5_INS4_6RefPtrINS_12FuncDeclNodeEEELm0EEEEEjii
+__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14shrinkCapacityEm
+__ZN3JSC5Lexer7record8Ei
+__ZL14makeAssignNodePvPN3JSC14ExpressionNodeENS0_8OperatorES2_bbiii
+__ZN3JSC7UString3Rep7destroyEv
+__ZNK3JSC11ResolveNode10isLocationEv
+__ZNK3JSC11ResolveNode13isResolveNodeEv
+__ZL26appendToVarDeclarationListPvRPN3JSC15ParserArenaDataIN3WTF6VectorISt4pairINS0_10IdentifierEjELm0EEEEERKS5_j
+__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EE14expandCapacityEm
+__ZNK3JSC14ExpressionNode10isLocationEv
 __ZN3JSC5Lexer5clearEv
-__ZN3JSC16ParserRefCounted16deleteNewObjectsEPNS_12JSGlobalDataE
-__ZN3JSC11ResolveNodeD0Ev
-__ZN3JSC15DotAccessorNodeD0Ev
-__ZN3JSC12NodeReleaser15releaseAllNodesEPNS_16ParserRefCountedE
-__ZN3JSC15DotAccessorNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC12NodeReleaser7releaseINS_14ExpressionNodeEEEvRN3WTF6RefPtrIT_EE
-__ZN3JSC12NodeReleaser5adoptEN3WTF10PassRefPtrINS_16ParserRefCountedEEE
-__ZN3JSC16ParserRefCounted9hasOneRefEv
-__ZN3JSC16ParserRefCounted5derefEv
-__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS9_INS8_6RefPtrINS_12FuncDeclNodeEEELm0EEEji
-__ZN3WTF6VectorINS_6RefPtrIN3JSC13StatementNodeEEELm0EE14shrinkCapacityEm
-__ZN3JSC14SourceElementsD0Ev
+__ZN3JSC10Identifier6removeEPNS_7UString3RepE
+__ZN3WTF6VectorIN3JSC10IdentifierELm64EE14shrinkCapacityEm
+__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS9_IPNS_12FuncDeclNodeELm0EEEji
+__ZN3JSC11ParserArena10removeLastEv
+__ZN3JSC11ParserArena5resetEv
 __ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
-__ZN3JSC11Interpreter7executeEPNS_11ProgramNodeEPNS_9ExecStateEPNS_14ScopeChainNodeEPNS_8JSObjectEPNS_10JSValuePtrE
+__ZN3JSC11Interpreter7executeEPNS_11ProgramNodeEPNS_9ExecStateEPNS_14ScopeChainNodeEPNS_8JSObjectEPNS_7JSValueE
 __ZN3JSC11ProgramNode16generateBytecodeEPNS_14ScopeChainNodeE
 __ZN3JSC9CodeBlockC2EPNS_9ScopeNodeENS_8CodeTypeEN3WTF10PassRefPtrINS_14SourceProviderEEEj
-__ZN3WTF7HashSetIPN3JSC16ProgramCodeBlockENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
 __ZN3WTF9HashTableIPN3JSC16ProgramCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
 __ZN3JSC17BytecodeGeneratorC2EPNS_11ProgramNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISE_EENS_26SymbolTableIndexHashTraitsEEEPNS_16ProgramCodeBlockE
-__ZN3WTF6VectorIN3JSC11InstructionELm0EE15reserveCapacityEm
-__ZN3JSC9Structure22toDictionaryTransitionEPS0_
-__ZN3JSC17BytecodeGenerator11newRegisterEv
-__ZN3JSC9Structure24fromDictionaryTransitionEPS0_
+__ZN3WTF6VectorIN3JSC11InstructionELm0EE14expandCapacityEm
+__ZN3JSC9Structure31toCacheableDictionaryTransitionEPS0_
+__ZN3JSC9Structure22toDictionaryTransitionEPS0_NS0_14DictionaryKindE
+__ZN3JSC8JSObject12removeDirectERKNS_10IdentifierE
+__ZN3JSC9Structure24removePropertyTransitionEPS0_RKNS_10IdentifierERm
+__ZN3JSC9Structure6removeERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_12FuncDeclNodeE
+__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv
+__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EE14expandCapacityEm
+__ZN3JSC9Structure31removePropertyWithoutTransitionERKNS_10IdentifierE
+__ZNK3JSC7UString14toStrictUInt32EPb
+__ZN3JSC9Structure26flattenDictionaryStructureEPNS_8JSObjectE
+__ZN3JSCL30comparePropertyMapEntryIndicesEPKvS1_
 __ZN3JSC17BytecodeGenerator8generateEv
 __ZN3JSC11ProgramNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator13emitDebugHookENS_11DebugHookIDEii
-__ZN3JSC17BytecodeGenerator11addConstantENS_10JSValuePtrE
-__ZN3WTF7HashMapIPN3JSC23JSValueEncodedAsPointerEjNS_7PtrHashIS3_EENS1_17BytecodeGenerator17JSValueHashTraitsENS_10HashTraitsIjEEE3addERKS3_RKj
-__ZN3WTF9HashTableIPN3JSC23JSValueEncodedAsPointerESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS1_17BytecodeGenerator17JSValueHashTraitsENS_10HashTraitsIjEEEESC_E6rehashEi
+__ZN3JSC17BytecodeGenerator12newTemporaryEv
+__ZN3JSC17BytecodeGenerator11newRegisterEv
+__ZN3JSC17BytecodeGenerator16addConstantValueENS_7JSValueE
+__ZN3WTF9HashTableIPvSt4pairIS1_jENS_18PairFirstExtractorIS3_EENS_7PtrHashIS1_EENS_14PairHashTraitsIN3JSC24EncodedJSValueHashTraitsENS_10HashTraitsIjEEEESA_E6expandEv
 __ZN3WTF6VectorIN3JSC8RegisterELm0EE14expandCapacityEm
 __ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_
-__ZNK3JSC13StatementNode6isLoopEv
 __ZN3JSC17BytecodeGenerator8emitNodeEPNS_10RegisterIDEPNS_4NodeE
 __ZN3WTF6VectorIN3JSC8LineInfoELm0EE14expandCapacityEm
-__ZN3JSC17ExprStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17AssignResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator11registerForERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator18findScopedPropertyERKNS_10IdentifierERiRmbRPNS_8JSObjectE
-__ZN3JSC17BytecodeGenerator15emitResolveBaseEPNS_10RegisterIDERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator11addConstantERKNS_10IdentifierE
-__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEEiNS2_17IdentifierRepHashENS_10HashTraitsIS5_EENS2_17BytecodeGenerator28IdentifierMapIndexHashTraitsEE3addEPS4_RKi
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_iENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS5_EENS2_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESD_E6rehashEi
-__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm
+__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8newLabelEv
+__ZN3JSC13LogicalOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14ExpressionNode6isNullEv
+__ZNK3JSC14ExpressionNode6isPureERNS_17BytecodeGeneratorE
 __ZN3JSC15DotAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC11ResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11registerForERKNS_10IdentifierE
 __ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEm
-__ZN3JSC17BytecodeGenerator12newTemporaryEv
-__ZN3JSC17BytecodeGenerator11emitResolveEPNS_10RegisterIDERKNS_10IdentifierE
-__ZN3WTF6VectorIjLm0EE14expandCapacityEm
 __ZN3JSC17BytecodeGenerator11emitGetByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator11emitPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_
-__ZN3JSC10StringNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3WTF7HashMapIPN3JSC7UString3RepEPNS1_8JSStringENS1_17IdentifierRepHashENS_10HashTraitsIS4_EENS8_IS6_EEE3addERKS4_RKS6_
-__ZN3WTF9HashTableIPN3JSC7UString3RepESt4pairIS4_PNS1_8JSStringEENS_18PairFirstExtractorIS8_EENS1_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS4_EENSD_IS7_EEEESE_E6rehashEi
+__ZN3WTF6VectorIjLm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator11addConstantERKNS_10IdentifierE
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_iENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS5_EENS2_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESD_E6rehashEi
+__ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE
+__ZN3JSC17BytecodeGenerator15emitJumpIfFalseEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC11UnaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC19FunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3WTF6VectorIN3JSC11InstructionELm0EE6appendIiEEvRKT_
 __ZN3JSC17BytecodeGenerator8emitCallENS_8OpcodeIDEPNS_10RegisterIDES3_S3_PNS_13ArgumentsNodeEjjj
 __ZN3JSC16ArgumentListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator10emitOpcodeENS_8OpcodeIDE
+__ZN3JSC10RegExpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
+__ZN3JSC17BytecodeGenerator13emitNewRegExpEPNS_10RegisterIDEPNS_6RegExpE
+__ZN3JSC17BytecodeGenerator9emitLabelEPNS_5LabelE
+__ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17ExprStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11emitResolveEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator18findScopedPropertyERKNS_10IdentifierERiRmbRPNS_8JSObjectE
+__ZN3JSC13AssignDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE
+__ZN3JSC17BytecodeGenerator11emitPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC17AssignResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator15emitResolveBaseEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3JSC16VarStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitJumpIfTrueEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC17ObjectLiteralNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC10StringNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3WTF9HashTableIPN3JSC7UString3RepESt4pairIS4_PNS1_8JSStringEENS_18PairFirstExtractorIS8_EENS1_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS4_EENSD_IS7_EEEESE_E6expandEv
 __ZN3JSC12JSGlobalData22numericCompareFunctionEPNS_9ExecStateE
 __ZNK3JSC21UStringSourceProvider6lengthEv
 __ZNK3JSC21UStringSourceProvider4dataEv
-__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeE
 __ZN3JSC19extractFunctionBodyEPNS_11ProgramNodeE
 __ZNK3JSC17ExprStatementNode15isExprStatementEv
 __ZNK3JSC12FuncExprNode14isFuncExprNodeEv
@@ -266,541 +299,777 @@ __ZN3JSC9CodeBlockC1EPNS_9ScopeNodeENS_8CodeTypeEN3WTF10PassRefPtrINS_14SourcePr
 __ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISE_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE
 __ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierE
 __ZN3JSC16FunctionBodyNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC10ReturnNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC7SubNode8opcodeIDEv
 __ZNK3JSC11ResolveNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE
 __ZN3JSC17BytecodeGenerator10emitReturnEPNS_10RegisterIDE
 __ZNK3JSC9BlockNode7isBlockEv
 __ZNK3JSC10ReturnNode12isReturnNodeEv
 __ZN3JSC9CodeBlock11shrinkToFitEv
 __ZN3WTF6VectorIN3JSC11InstructionELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorIjLm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIN3JSC10IdentifierELm0EE14shrinkCapacityEm
-__ZN3JSC9BlockNodeD0Ev
-__ZN3JSC9BlockNode12releaseNodesERNS_12NodeReleaserE
-__ZN3WTF6VectorINS_6RefPtrIN3JSC16ParserRefCountedEEELm0EE15reserveCapacityEm
-__ZN3JSC10ReturnNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC12BinaryOpNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC16ParserRefCounted12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC10ReturnNodeD0Ev
+__ZN3JSC11ParserArenaD1Ev
+__ZN3JSC11ResolveNodeD0Ev
 __ZN3JSC7SubNodeD0Ev
-__ZN3JSC12BinaryOpNodeD2Ev
-__ZN3JSC17BytecodeGeneratorD2Ev
+__ZN3JSC14ExpressionNodeD2Ev
+__ZN3JSC10ReturnNodeD0Ev
+__ZN3JSC14SourceElementsD0Ev
+__ZN3JSC9BlockNodeD0Ev
 __ZN3WTF6VectorIN3JSC11InstructionELm0EEaSERKS3_
+__ZThn12_N3JSC11ProgramNodeD0Ev
 __ZN3JSC11ProgramNodeD0Ev
-__ZN3JSC9ScopeNodeD2Ev
-__ZN3JSC9ScopeNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC13ParameterNodeD0Ev
 __ZN3JSC17ExprStatementNodeD0Ev
+__ZThn12_N3JSC12FuncExprNodeD0Ev
 __ZN3JSC12FuncExprNodeD0Ev
-__ZN3JSC12FuncExprNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC12NodeReleaser21adoptFunctionBodyNodeERN3WTF6RefPtrINS_16FunctionBodyNodeEEE
-__ZN3JSC13ParameterNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13ParameterNodeD0Ev
+__ZThn12_N3JSC16FunctionBodyNodeD0Ev
 __ZN3JSC16FunctionBodyNodeD0Ev
-__ZN3JSC7UString3Rep7destroyEv
-__ZN3JSC10Identifier6removeEPNS_7UString3RepE
 __ZN3JSC9CodeBlockD1Ev
 __ZN3JSC9CodeBlockD2Ev
 __ZN3JSC21UStringSourceProviderD0Ev
-__ZN3JSC17AssignResolveNodeD0Ev
-__ZN3JSC17AssignResolveNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC10StringNodeD0Ev
-__ZN3JSC19FunctionCallDotNodeD0Ev
-__ZN3JSC19FunctionCallDotNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13ArgumentsNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC16ArgumentListNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13ArgumentsNodeD0Ev
-__ZN3JSC16ArgumentListNodeD0Ev
-__ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12RegisterFileE
-__ZN3JSC11Interpreter11resolveBaseEPNS_9ExecStateEPNS_11InstructionE
-__ZN3JSC11Interpreter13resolveGlobalEPNS_9ExecStateEPNS_11InstructionERNS_10JSValuePtrE
-__ZN3JSC11Interpreter15tryCacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockEPNS_11InstructionENS_10JSValuePtrERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC11Interpreter15tryCachePutByIDEPNS_9ExecStateEPNS_9CodeBlockEPNS_11InstructionENS_10JSValuePtrERKNS_15PutPropertySlotE
-__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC17PrototypeFunctionC2EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectES6_RKNS_7ArgListEE
-__ZN3JSC17PrototypeFunction11getCallDataERNS_8CallDataE
-__ZNK3JSC8JSString8toStringEPNS_9ExecStateE
-__ZNK3JSC9CodeBlock15derefStructuresEPNS_11InstructionE
-__ZN3JSC14JSGlobalObject16stopTimeoutCheckEv
-__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EE15reserveCapacityEm
-__ZN3JSC20ParserRefCountedDataIN3WTF6VectorINS1_6RefPtrINS_12FuncDeclNodeEEELm0EEEED0Ev
-__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EEaSERKS5_
-__ZN3JSC8JSObject12removeDirectERKNS_10IdentifierE
-__ZN3JSC9Structure31removePropertyWithoutTransitionERKNS_10IdentifierE
-__ZN3JSC9Structure6removeERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_12FuncDeclNodeE
-__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv
-__ZN3JSC13AssignDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC10StringNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC20GetByIdExceptionInfoELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorINS_6RefPtrIN3JSC6RegExpEEELm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14shrinkCapacityEm
+__ZN3JSC15ParserArenaDataIN3WTF6VectorIPNS_12FuncDeclNodeELm0EEEED0Ev
+__ZN3JSC15DotAccessorNodeD0Ev
+__ZN3JSC12NotEqualNodeD0Ev
+__ZN3JSC10RegExpNodeD0Ev
+__ZN3JSC16ArgumentListNodeD0Ev
+__ZN3JSC13ArgumentsNodeD0Ev
+__ZN3JSC19FunctionCallDotNodeD0Ev
+__ZN3JSC14LogicalNotNodeD0Ev
+__ZN3JSC13LogicalOpNodeD0Ev
+__ZN3JSC6IfNodeD0Ev
 __ZN3JSC13AssignDotNodeD0Ev
-__ZN3JSC13AssignDotNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC12FuncDeclNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZN3JSC12FuncDeclNodeD0Ev
-__ZN3JSC12FuncDeclNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC4Heap9unprotectENS_10JSValuePtrE
-__ZN3JSC5Lexer7record8Ei
-__ZL26appendToVarDeclarationListPvRPN3JSC20ParserRefCountedDataIN3WTF6VectorISt4pairINS0_10IdentifierEjELm0EEEEERKS5_j
-__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EE14expandCapacityEmPKS4_
-__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EE15reserveCapacityEm
-__ZL20makeVarStatementNodePvPN3JSC14ExpressionNodeE
-__ZN3JSC20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEED0Ev
-__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EEaSERKS5_
-__ZNK3JSC7UString14toStrictUInt32EPb
-__ZN3JSC16VarStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17AssignResolveNodeD0Ev
+__ZN3JSC17ObjectLiteralNodeD0Ev
+__ZN3JSC15ParserArenaDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEED0Ev
 __ZN3JSC16VarStatementNodeD0Ev
-__ZN3JSC16VarStatementNode12releaseNodesERNS_12NodeReleaserE
-__ZL12makeMultNodePvPN3JSC14ExpressionNodeES2_b
-__ZNK3JSC10NumberNode8isNumberEv
-__ZL11makeAddNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC21FunctionCallValueNodeD0Ev
+__ZN3JSC10StringNodeD0Ev
+__ZN3WTF14deleteOwnedPtrIN3JSC17BytecodeGeneratorEEEvPT_
+__ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12RegisterFileE
+__ZN3JSC12FuncDeclNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZN3JSC11Interpreter15tryCacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockEPNS_11InstructionENS_7JSValueERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC7JSValue13equalSlowCaseEPNS_9ExecStateES0_S0_
+__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC12FuncExprNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZN3JSC9Structure13hasTransitionEPNS_7UString3RepEj
+__ZN3JSC11Interpreter15tryCachePutByIDEPNS_9ExecStateEPNS_9CodeBlockEPNS_11InstructionENS_7JSValueERKNS_15PutPropertySlotE
+__ZN3JSC11Interpreter13resolveGlobalEPNS_9ExecStateEPNS_11InstructionERNS_7JSValueE
+__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
+__ZN3JSC10JSFunction11getCallDataERNS_8CallDataE
+__ZL17combineCommaNodesPvPN3JSC14ExpressionNodeES2_
+__ZL15makePostfixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
+__ZNK3JSC18EmptyStatementNode16isEmptyStatementEv
+__ZNK3JSC16JSVariableObject16isVariableObjectEv
+__ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_7JSValueE
+__ZN3JSC7ForNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13newLabelScopeENS_10LabelScope4TypeEPKNS_10IdentifierE
 __ZN3JSC10NumberNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEd
-__ZN3WTF7HashMapIdN3JSC10JSValuePtrENS_9FloatHashIdEENS_10HashTraitsIdEENS5_IS2_EEE3addERKdRKS2_
-__ZN3WTF9HashTableIdSt4pairIdN3JSC10JSValuePtrEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsIdEENSA_IS3_EEEESB_E6rehashEi
-__ZN3JSC11NewExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13emitConstructEPNS_10RegisterIDES2_PNS_13ArgumentsNodeEjjj
-__ZN3WTF6VectorIN3JSC20GetByIdExceptionInfoELm0EE14expandCapacityEm
-__ZNK3JSC7AddNode8opcodeIDEv
-__ZNK3JSC14ExpressionNode6isPureERNS_17BytecodeGeneratorE
-__ZNK3JSC8MultNode8opcodeIDEv
-__ZNK3JSC10NumberNode6isPureERNS_17BytecodeGeneratorE
+__ZN3WTF9HashTableIdSt4pairIdN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsIdEENSA_IS3_EEEESB_E6expandEv
+__ZN3JSC17BytecodeGenerator8emitJumpEPNS_5LabelE
+__ZN3JSC15ConditionalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZL14compileBracketiPiPPhPPKtS3_P9ErrorCodeiS_S_R11CompileData
+__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
+__ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi
+__ZN3JSC18PostfixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC19BracketAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12emitGetByValEPNS_10RegisterIDES2_S2_
+__ZN3JSC16PropertyListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC10NumberNodeD0Ev
-__ZN3JSC11NewExprNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11NewExprNodeD0Ev
-__ZN3JSC7AddNodeD0Ev
-__ZN3JSC8MultNodeD0Ev
-__ZN3JSC15DateConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL28constructWithDateConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC13constructDateEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC13DatePrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL20dateProtoFuncGetTimeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC19BracketAccessorNodeD0Ev
+__ZN3JSC18PostfixResolveNodeD0Ev
+__ZN3JSC15ConditionalNodeD0Ev
+__ZN3JSC9BreakNodeD0Ev
+__ZN3JSC18EmptyStatementNodeD0Ev
+__ZN3JSC7ForNodeD0Ev
+__ZN3JSC12PropertyNodeD0Ev
+__ZN3JSC16PropertyListNodeD0Ev
+__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC17PrototypeFunction11getCallDataERNS_8CallDataE
+__ZNK3JSC8JSString8toStringEPNS_9ExecStateE
+__ZN3JSC7UString4fromEj
+__ZN3JSC7UString3Rep6createEPtiN3WTF10PassRefPtrINS3_21CrossThreadRefCountedINS3_16OwnFastMallocPtrItEEEEEE
+__ZNK3JSC8JSString9toBooleanEPNS_9ExecStateE
+__ZN3JSC12RegExpObjectC1EN3WTF10PassRefPtrINS_9StructureEEENS2_INS_6RegExpEEE
+__ZN3JSC12RegExpObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL19regExpProtoFuncTestEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZNK3JSC6JSCell8isObjectEPKNS_9ClassInfoE
-__ZNK3JSC12DateInstance9classInfoEv
-__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC12JSNumberCell8toNumberEPNS_9ExecStateE
+__ZNK3JSC12RegExpObject9classInfoEv
+__ZN3JSC12RegExpObject5matchEPNS_9ExecStateERKNS_7ArgListE
+__ZNK3JSC7JSValue8toStringEPNS_9ExecStateE
+__ZN3JSC17RegExpConstructor12performMatchEPNS_6RegExpERKNS_7UStringEiRiS6_PPi
+__ZN3JSC6RegExp5matchERKNS_7UStringEiPN3WTF6VectorIiLm32EEE
+__ZN3JSC17RegExpConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar1EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC11jsSubstringEPNS_12JSGlobalDataERKNS_7UStringEjj
+__ZN3JSC20constructEmptyObjectEPNS_9ExecStateE
+__ZN3WTF7HashMapISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjES1_IPNS3_9StructureES9_ENS3_28StructureTransitionTableHashENS3_34StructureTransitionTableHashTraitsENS_10HashTraitsISA_EEE3addERKS7_RKSA_
+__ZN3WTF9HashTableISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjES1_IS7_S1_IPNS3_9StructureES9_EENS_18PairFirstExtractorISB_EENS3_28StructureTransitionTableHashENS_14PairHashTraitsINS3_34StructureTransitionTableHashTraitsENS_10HashTraitsISA_EEEESG_E6rehashEi
+__ZN3WTF7HashSetINS_6RefPtrIN3JSC7UString3RepEEENS2_17IdentifierRepHashENS_10HashTraitsIS5_EEE3addERKS5_
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEES5_NS_17IdentityExtractorIS5_EENS2_17IdentifierRepHashENS_10HashTraitsIS5_EESA_E6rehashEi
 __ZN3JSC11BooleanNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC13StatementNode12isReturnNodeEv
 __ZN3JSC11BooleanNodeD0Ev
-__ZN3JSC4Heap7collectEv
-__ZN3JSC4Heap30markStackObjectsConservativelyEv
-__ZN3JSC4Heap31markCurrentThreadConservativelyEv
-__ZN3JSC4Heap39markCurrentThreadConservativelyInternalEv
-__ZN3JSC4Heap18markConservativelyEPvS1_
-__ZN3JSC4Heap20markProtectedObjectsEv
-__ZN3JSC8JSObject4markEv
-__ZN3JSC6JSCell4markEv
-__ZN3JSC14JSGlobalObject4markEv
-__ZN3JSC7JSArray4markEv
-__ZN3JSC15JSWrapperObject4markEv
-__ZN3JSC18GlobalEvalFunction4markEv
-__ZN3JSC12SmallStrings4markEv
-__ZN3JSC4Heap5sweepILNS_8HeapTypeE0EEEmv
-__ZN3JSC14JSGlobalObjectD2Ev
-__ZN3JSC17FunctionPrototypeD1Ev
-__ZN3JSC17PrototypeFunctionD1Ev
-__ZN3JSC15ObjectPrototypeD1Ev
-__ZN3JSC14ArrayPrototypeD1Ev
-__ZN3JSC15StringPrototypeD1Ev
-__ZN3JSC16BooleanPrototypeD1Ev
-__ZN3JSC15NumberPrototypeD1Ev
-__ZN3JSC13DatePrototypeD1Ev
-__ZN3JSC12DateInstanceD2Ev
-__ZN3JSC15RegExpPrototypeD1Ev
-__ZN3JSC14ErrorPrototypeD1Ev
-__ZN3JSC20NativeErrorPrototypeD1Ev
-__ZN3JSC17ObjectConstructorD1Ev
-__ZN3JSC19FunctionConstructorD1Ev
-__ZN3JSC16ArrayConstructorD1Ev
-__ZN3JSC17StringConstructorD1Ev
-__ZN3JSC18BooleanConstructorD1Ev
-__ZN3JSC17NumberConstructorD1Ev
-__ZN3JSC15DateConstructorD1Ev
-__ZN3JSC17RegExpConstructorD1Ev
-__ZN3JSC16ErrorConstructorD1Ev
-__ZN3JSC22NativeErrorConstructorD1Ev
-__ZN3JSC10MathObjectD1Ev
-__ZN3JSC18GlobalEvalFunctionD1Ev
-__ZN3JSC12DateInstanceD1Ev
-__ZN3JSC4Heap5sweepILNS_8HeapTypeE1EEEmv
-__ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator8newLabelEv
-__ZN3JSC17BytecodeGenerator15emitJumpIfFalseEPNS_10RegisterIDEPNS_5LabelE
-__ZN3JSC17BytecodeGenerator9emitLabelEPNS_5LabelE
-__ZN3JSC6IfNodeD0Ev
-__ZN3JSC6IfNode12releaseNodesERNS_12NodeReleaserE
-__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
-__ZN3JSC10JSFunction4markEv
-__ZN3JSC16FunctionBodyNode4markEv
-__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator19emitResolveFunctionEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZNK3JSC12NotEqualNode8opcodeIDEv
-__ZNK3JSC14ExpressionNode6isNullEv
-__ZN3JSC13LogicalOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC8LessNode8opcodeIDEv
-__ZN3JSC23FunctionCallResolveNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC23FunctionCallResolveNodeD0Ev
-__ZN3JSC12NotEqualNodeD0Ev
-__ZN3JSC13LogicalOpNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13LogicalOpNodeD0Ev
-__ZN3JSC8LessNodeD0Ev
-__ZN3JSC11Interpreter18resolveBaseAndFuncEPNS_9ExecStateEPNS_11InstructionERNS_10JSValuePtrE
-__ZN3JSC18globalFuncParseIntEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11JSImmediate12nonInlineNaNEv
+__ZN3JSC10IfElseNodeD0Ev
+__ZN3JSC12JSActivationC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_16FunctionBodyNodeEEE
+__ZN3JSC12JSActivationC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_16FunctionBodyNodeEEE
+__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
 __ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC15StringPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL22stringProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZNK3JSC8JSString12toThisStringEPNS_9ExecStateE
-__ZNK3JSC7UString4findERKS0_i
-__ZN3JSC10JSFunction11getCallDataERNS_8CallDataE
-__ZNK3JSC16JSVariableObject16isVariableObjectEv
-__ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_10JSValuePtrE
-__ZNK3JSC13StatementNode12isReturnNodeEv
-__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
-__ZN3JSC9EqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14emitEqualityOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_
-__ZNK3JSC13StatementNode7isBlockEv
-__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
-__ZN3JSC9EqualNodeD0Ev
-__ZN3JSC11concatenateEPNS_7UString3RepES2_
-__ZNK3JSC9CodeBlock13refStructuresEPNS_11InstructionE
-__ZN3JSC9CodeBlock4markEv
-__ZNK3JSC12JSNumberCell8toStringEPNS_9ExecStateE
-__ZN3JSC7UString4fromEd
-__ZN3WTF4dtoaEdiPiS0_PPc
-__ZN3WTFL3d2bEdPiS0_
-__ZN3JSC19BracketAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitGetByValEPNS_10RegisterIDES2_S2_
-__ZN3JSC19BracketAccessorNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC19BracketAccessorNodeD0Ev
-__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC10JSFunction16getConstructDataERNS_13ConstructDataE
-__ZL15makePostfixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
+__ZNK3JSC6JSCell9classInfoEv
+__Z12jsRegExpFreeP8JSRegExp
+__ZL11makeAddNodePvPN3JSC14ExpressionNodeES2_b
 __ZNK3JSC19BracketAccessorNode10isLocationEv
 __ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv
-__ZNK3JSC7ForNode6isLoopEv
-__ZN3JSC7ForNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13newLabelScopeENS_10LabelScope4TypeEPKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator8emitJumpEPNS_5LabelE
+__ZL14makePrefixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
+__ZN3JSC9ThrowNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9EqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC10NumberNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
+__ZN3JSC17BytecodeGenerator14emitEqualityOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_
+__ZNK3JSC14ExpressionNode5isAddEv
+__ZNK3JSC12JSActivation14isDynamicScopeEv
+__ZN3JSC15StrictEqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC11BooleanNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC7AddNode5isAddEv
+__ZN3JSC12BinaryOpNode10emitStrcatERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_PNS_21ReadModifyResolveNodeE
+__ZNK3JSC10StringNode8isStringEv
+__ZNK3JSC14ExpressionNode8isStringEv
+__ZN3JSC17BytecodeGenerator10emitStrcatEPNS_10RegisterIDES2_i
 __ZN3JSC17AssignBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC8ThisNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator12emitPutByValEPNS_10RegisterIDES2_S2_
-__ZN3JSC18PostfixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14emitJumpIfTrueEPNS_10RegisterIDEPNS_5LabelE
-__ZN3JSC7ForNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC7ForNodeD0Ev
-__ZN3JSC18PostfixResolveNodeD0Ev
+__ZNK3JSC10StringNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC17TypeOfResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE
+__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9ThrowNodeD0Ev
+__ZN3JSC9EqualNodeD0Ev
+__ZN3JSC7AddNodeD0Ev
+__ZN3JSC15StrictEqualNodeD0Ev
+__ZN3JSC23FunctionCallResolveNodeD0Ev
 __ZN3JSC17AssignBracketNodeD0Ev
-__ZN3JSC17AssignBracketNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC8ThisNodeD0Ev
-__ZN3JSC8JSObject17createInheritorIDEv
-__ZN3JSC10JSFunction15argumentsGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZNK3JSC11Interpreter17retrieveArgumentsEPNS_9ExecStateEPNS_10JSFunctionE
+__ZN3JSC17TypeOfResolveNodeD0Ev
+__ZN3JSC9ArrayNodeD0Ev
+__ZN3JSC13PrefixDotNodeD0Ev
+__ZN3JSCL22stringProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7UString4findERKS0_i
+__ZN3JSC11concatenateEPNS_7UString3RepES2_
 __ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_10JSValuePtrE
-__ZN3JSCL21dateProtoFuncGetMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC12DateInstance21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
-__ZN3JSC21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
-__ZN3JSCL12getDSTOffsetEdd
+__ZN3JSC17BytecodeGenerator16emitPutScopedVarEmiPNS_10RegisterIDENS_7JSValueE
+__ZNK3JSC7UString8toUInt32EPbb
+__ZNK3JSC7UString8toDoubleEbb
 __ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL20dateProtoFuncGetDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11concatenateEPNS_7UString3RepEi
-__ZN3JSC21ReadModifyResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC21ReadModifyResolveNodeD0Ev
-__ZN3JSC21ReadModifyResolveNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC10LessEqNode8opcodeIDEv
-__ZN3JSC10IfElseNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC10IfElseNodeD0Ev
-__ZN3JSC10LessEqNodeD0Ev
-__ZN3JSCL21dateProtoFuncGetHoursEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL23dateProtoFuncGetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC8JSString11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZN3JSC7UString3Rep15reserveCapacityEi
+__ZN3WTF11fastReallocILb0EEEPvS1_m
+__ZN3JSC7UString6appendERKS0_
+__ZN3JSC16jsIsFunctionTypeENS_7JSValueE
+__ZNK3JSC9CodeBlock13refStructuresEPNS_11InstructionE
+__ZN3JSC14StructureChainC1EPNS_9StructureE
+__ZN3JSC14StructureChainC2EPNS_9StructureE
+__ZNK3JSC14StructureChain11isCacheableEv
+__ZNK3JSC9CodeBlock15derefStructuresEPNS_11InstructionE
+__ZN3JSC6RegExpD1Ev
+__ZThn12_N3JSC12FuncDeclNodeD0Ev
+__ZN3JSC12FuncDeclNodeD0Ev
+__ZNK3JSC10NumberNode8isNumberEv
+__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEm
 __ZN3JSC19ReverseBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC13GreaterEqNode8opcodeIDEv
-__ZN3JSC13GreaterEqNodeD0Ev
-__ZN3JSC9ArgumentsD1Ev
-__ZN3JSC9ArgumentsD2Ev
 __ZN3JSC8WithNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator13emitPushScopeEPNS_10RegisterIDE
 __ZN3WTF6VectorIN3JSC18ControlFlowContextELm0EE14expandCapacityEm
-__ZNK3JSC11GreaterNode8opcodeIDEv
-__ZN3JSC11UnaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC14LogicalNotNode8opcodeIDEv
-__ZN3JSC8WithNodeD0Ev
-__ZN3JSC8WithNode12releaseNodesERNS_12NodeReleaserE
+__ZL17bracketIsAnchoredPKh
+__ZL32branchFindFirstAssertedCharacterPKhb
+__ZL20branchNeedsLineStartPKhjj
+__ZN3JSC23CallFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator25emitJumpIfNotFunctionCallEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC21ThrowableBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11NewExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13emitConstructEPNS_10RegisterIDES2_PNS_13ArgumentsNodeEjjj
+__ZN3WTF6VectorIN3JSC20GetByIdExceptionInfoELm0EE14expandCapacityEm
 __ZN3JSC11GreaterNodeD0Ev
-__ZN3JSC11UnaryOpNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC14LogicalNotNodeD0Ev
-__ZN3JSC14ExpressionNodeD2Ev
-__ZN3JSC10JSValuePtr13equalSlowCaseEPNS_9ExecStateES0_S0_
-__ZN3JSC11Interpreter7resolveEPNS_9ExecStateEPNS_11InstructionERNS_10JSValuePtrE
-__ZNK3JSC8NullNode6isNullEv
-__ZN3JSC8NullNodeD0Ev
-__ZN3JSC8NullNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC9ForInNodeC2EPNS_12JSGlobalDataERKNS_10IdentifierEPNS_14ExpressionNodeES7_PNS_13StatementNodeEiii
-__ZNK3JSC9ForInNode6isLoopEv
+__ZN3JSC18NotStrictEqualNodeD0Ev
+__ZN3JSC8WithNodeD0Ev
+__ZN3JSC11ElementNodeD0Ev
+__ZN3JSC23CallFunctionCallDotNodeD0Ev
+__ZN3JSC6InNodeD0Ev
+__ZN3JSC11NewExprNodeD0Ev
+__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE
+__ZN3JSC7JSArrayC2EN3WTF10PassRefPtrINS_9StructureEEEj
+__ZNK3JSC7UString10getCStringERN3WTF6VectorIcLm32EEE
 __ZN3JSC9ForInNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator20emitNextPropertyNameEPNS_10RegisterIDES2_PNS_5LabelE
-__ZN3JSC9ForInNode12releaseNodesERNS_12NodeReleaserE
 __ZN3JSC9ForInNodeD0Ev
 __ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
 __ZN3JSC9Structure26getEnumerablePropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayEPNS_8JSObjectE
 __ZN3JSC9Structure35getEnumerableNamesFromPropertyTableERNS_17PropertyNameArrayE
-__ZNK3JSC6JSCell9classInfoEv
-__ZN3JSC14StructureChainC1EPNS_9StructureE
-__ZN3JSC14StructureChainC2EPNS_9StructureE
 __ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE
-__ZN3JSC16globalFuncEscapeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11JSImmediate8toStringENS_10JSValuePtrE
-__ZN3JSC7UString4fromEi
-__ZN3JSC7UString6appendERKS0_
 __ZN3JSC22JSPropertyNameIterator10invalidateEv
-__ZNK3JSC18EmptyStatementNode16isEmptyStatementEv
-__ZN3JSC18EmptyStatementNodeD0Ev
-__ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC21gregorianDateTimeToMSERKNS_17GregorianDateTimeEdb
-__ZN3JSCL15dateToDayInYearEiii
-__ZN3JSCL21dateProtoFuncSetMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL23setNewValueFromDateArgsEPNS_9ExecStateENS_10JSValuePtrERKNS_7ArgListEib
-__ZN3JSCL20dateProtoFuncSetDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL24dateProtoFuncToGMTStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCplERKNS_7UStringES2_
-__ZN3JSC10formatTimeERKNS_17GregorianDateTimeEb
-__ZN3JSC22JSPropertyNameIteratorD1Ev
-__ZN3JSC8JSObjectD1Ev
-__ZNK3JSC8JSString11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
-__ZN3JSC9parseDateERKNS_7UStringE
-__ZNK3JSC7UString10UTF8StringEb
-__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
+__ZN3JSC9Structure22materializePropertyMapEv
+__ZNK3JSC14ExpressionNode11isCommaNodeEv
+__ZN3JSC8ThisNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9CommaNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8ThisNodeD0Ev
+__ZN3JSC9CommaNodeD0Ev
+__ZN3JSC9WhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9WhileNodeD0Ev
 __ZN3JSC16ArrayConstructor16getConstructDataERNS_13ConstructDataE
 __ZN3JSCL29constructWithArrayConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
 __ZN3JSCL27constructArrayWithSizeQuirkEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC7JSArrayC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7ArgListE
-__ZL14makePrefixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
-__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC9WhileNode6isLoopEv
-__ZN3JSC9WhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3JSC9WhileNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13PrefixDotNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13PrefixDotNodeD0Ev
-__ZN3JSC20EvalFunctionCallNodeD0Ev
-__ZN3JSC20EvalFunctionCallNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC9WhileNodeD0Ev
-__ZN3JSC12JSActivationC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_16FunctionBodyNodeEEE
-__ZN3JSC12JSActivationC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_16FunctionBodyNodeEEE
-__ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZL11makeDivNodePvPN3JSC14ExpressionNodeES2_b
-__ZN3JSC15ConditionalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC7DivNode8opcodeIDEv
-__ZN3JSC15ConditionalNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC15ConditionalNodeD0Ev
-__ZN3JSC7DivNodeD0Ev
-__ZN3JSC7JSArrayC2EN3WTF10PassRefPtrINS_9StructureEEEj
-__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_10JSValuePtrE
-__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC7JSArray3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3WTF7HashMapISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjEPNS3_9StructureENS3_28StructureTransitionTableHashENS3_34StructureTransitionTableHashTraitsENS_10HashTraitsIS9_EEE3addERKS7_RKS9_
-__ZN3WTF9HashTableISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjES1_IS7_PNS3_9StructureEENS_18PairFirstExtractorISA_EENS3_28StructureTransitionTableHashENS_14PairHashTraitsINS3_34StructureTransitionTableHashTraitsENS_10HashTraitsIS9_EEEESF_E6rehashEi
-__ZN3JSC17StringConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL30constructWithStringConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZNK3JSC7JSValue8toUInt32EPNS_9ExecStateE
+__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC17RegExpConstructor3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC8NullNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8NullNodeD0Ev
+__ZN3JSC8LessNodeD0Ev
+__ZN3JSC6JSCell11getCallDataERNS_8CallDataE
+__ZN3JSC10JSFunction3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC7JSArrayC2EN3WTF10PassRefPtrINS_9StructureEEERKNS_7ArgListE
 __ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC11Interpreter22resolveBaseAndPropertyEPNS_9ExecStateEPNS_11InstructionERNS_10JSValuePtrE
-__ZN3JSC9Structure22materializePropertyMapEv
-__ZN3JSC8JSObject23allocatePropertyStorageEmm
-__ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC12StringObject12toThisStringEPNS_9ExecStateE
-__ZN3JSC12JSActivationD1Ev
-__ZN3JSC12JSActivationD2Ev
-__ZN3JSC11Interpreter14uncachePutByIDEPNS_9CodeBlockEPNS_11InstructionE
-__ZN3JSC12StringObjectD1Ev
-__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL18arrayProtoFuncPushEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorIN3JSC10IdentifierELm20EE14expandCapacityEm
+__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC9Structure27despecifyFunctionTransitionEPS0_RKNS_10IdentifierE
+__ZN3JSC11Interpreter7resolveEPNS_9ExecStateEPNS_11InstructionERNS_7JSValueE
+__ZN3JSC11Interpreter14uncacheGetByIDEPNS_9CodeBlockEPNS_11InstructionE
+__ZN3JSC7JSArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC17NumberConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZNK3JSC8JSString12toThisObjectEPNS_9ExecStateE
+__ZN3JSCL22stringProtoFuncReplaceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12StringObject14toThisJSStringEPNS_9ExecStateE
 __ZN3JSC8JSString14toThisJSStringEPNS_9ExecStateE
-__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_10JSValuePtrE
-__ZN3WTF11fastReallocILb0EEEPvS1_m
-__ZN3JSCL24stringProtoFuncSubstringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11jsSubstringEPNS_12JSGlobalDataERKNS_7UStringEjj
-__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC19constructEmptyArrayEPNS_9ExecStateE
-__ZNK3JSC11BooleanNode6isPureERNS_17BytecodeGeneratorE
-__ZNK3JSC7ModNode8opcodeIDEv
-__ZN3JSC7ModNodeD0Ev
-__ZN3JSCL23dateProtoFuncGetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC17BytecodeGenerator16emitPutScopedVarEmiPNS_10RegisterIDENS_10JSValuePtrE
-__ZN3JSC18globalFuncUnescapeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC7UString6appendEt
-__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEiiRNS_10JSValuePtrE
-__ZN3JSC5Lexer10scanRegExpEv
-__ZN3JSC7UStringC2ERKN3WTF6VectorItLm0EEE
-__ZNK3JSC9BitOrNode8opcodeIDEv
-__ZN3JSC9BitOrNodeD0Ev
-__ZNK3JSC8JSString9toBooleanEPNS_9ExecStateE
+__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC7TryNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator9emitCatchEPNS_10RegisterIDEPNS_5LabelES4_
+__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator16emitPushNewScopeEPNS_10RegisterIDERNS_10IdentifierES2_
+__ZN3JSC7TryNodeD0Ev
+__ZNK3JSC9CommaNode11isCommaNodeEv
+__ZN3JSCL21arrayProtoFuncForEachEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11Interpreter20prepareForRepeatCallEPNS_16FunctionBodyNodeEPNS_9ExecStateEPNS_10JSFunctionEiPNS_14ScopeChainNodeEPNS_7JSValueE
+__ZN3JSC11Interpreter7executeERNS_16CallFrameClosureEPNS_7JSValueE
 __ZN3JSC10MathObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL19mathProtoFuncRandomEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3WTF16weakRandomNumberEv
-__ZNK3JSC13UnaryPlusNode8opcodeIDEv
-__ZN3JSC13UnaryPlusNodeD0Ev
-__ZNK3JSC8JSString8toNumberEPNS_9ExecStateE
-__ZNK3JSC7UString8toDoubleEbb
-__ZNK3JSC7UString10getCStringERN3WTF6VectorIcLm32EEE
-__ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL18mathProtoFuncFloorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL18mathProtoFuncRoundEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL13jsAddSlowCaseEPNS_9ExecStateENS_10JSValuePtrES2_
-__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC7UString4fromEj
-__ZN3JSC9CommaNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC9CommaNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC16VarDeclCommaNodeD0Ev
-__ZN3JSC7UStringC2EPtib
-__ZN3JSC11concatenateEPNS_7UString3RepEd
-__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
-__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
-__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEm
-__ZN3JSC17ObjectLiteralNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE
-__ZN3JSC10RegExpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
-__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
-__ZL30calculateCompiledPatternLengthPKti24JSRegExpIgnoreCaseOptionR11CompileDataR9ErrorCode
-__ZL11checkEscapePPKtS0_P9ErrorCodeib
-__ZL13compileBranchiPiPPhPPKtS3_P9ErrorCodeS_S_R11CompileData
-__ZN3JSC17BytecodeGenerator13emitNewRegExpEPNS_10RegisterIDEPNS_6RegExpE
-__ZN3WTF6VectorINS_6RefPtrIN3JSC6RegExpEEELm0EE14expandCapacityEm
-__ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE
-__ZL14compileBracketiPiPPhPPKtS3_P9ErrorCodeiS_S_R11CompileData
-__ZL17bracketIsAnchoredPKh
-__ZL32branchFindFirstAssertedCharacterPKhb
-__ZL20branchNeedsLineStartPKhjj
-__ZN3JSC16PropertyListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17ObjectLiteralNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC17ObjectLiteralNodeD0Ev
-__ZN3JSC10RegExpNodeD0Ev
-__ZN3JSC9ArrayNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC9ArrayNodeD0Ev
-__ZN3JSC16PropertyListNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC12PropertyNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC16PropertyListNodeD0Ev
-__ZN3JSC12PropertyNodeD0Ev
-__ZN3JSC20constructEmptyObjectEPNS_9ExecStateE
-__ZN3JSC12FuncExprNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZN3JSC12RegExpObjectC1EN3WTF10PassRefPtrINS_9StructureEEENS2_INS_6RegExpEEE
-__ZN3JSCL7dateNowEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC17RegExpConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC15constructRegExpEPNS_9ExecStateERKNS_7ArgListE
-__ZNK3JSC14ExpressionNode10isLocationEv
-__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC21FunctionCallValueNodeD0Ev
-__ZN3JSC21FunctionCallValueNode12releaseNodesERNS_12NodeReleaserE
-__ZN3WTF7HashSetINS_6RefPtrIN3JSC7UString3RepEEENS2_17IdentifierRepHashENS_10HashTraitsIS5_EEE3addERKS5_
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEES5_NS_17IdentityExtractorIS5_EENS2_17IdentifierRepHashENS_10HashTraitsIS5_EESA_E6rehashEi
-__ZN3JSC11ElementNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11ElementNodeD0Ev
-__ZNK3JSC12JSActivation14isDynamicScopeEv
-__ZN3JSC4Heap24setGCProtectNeedsLockingEv
-__ZN3WTF15ThreadConditionD1Ev
-__ZN3JSC17PrefixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17PrefixResolveNodeD0Ev
-__ZNK3JSC7UString8toUInt32EPbb
-__ZN3JSC7UString17expandPreCapacityEi
-__ZN3WTF17TCMalloc_PageHeap3NewEm
-__ZN3JSC6JSCell9getObjectEv
-__ZN3JSC4callEPNS_9ExecStateENS_10JSValuePtrENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
-__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
-__ZN3JSC11Interpreter7executeEPNS_16FunctionBodyNodeEPNS_9ExecStateEPNS_10JSFunctionEPNS_8JSObjectERKNS_7ArgListEPNS_14ScopeChainNodeEPNS_10JSValuePtrE
-__ZN3JSCL22stringProtoFuncReplaceEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC6JSCell11getCallDataERNS_8CallDataE
-__ZNK3JSC12RegExpObject9classInfoEv
-__ZN3JSC17RegExpConstructor12performMatchEPNS_6RegExpERKNS_7UStringEiRiS6_PPi
-__ZN3JSC6RegExp5matchERKNS_7UStringEiPN3WTF11OwnArrayPtrIiEE
-__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
+__ZN3JSC11Interpreter13endRepeatCallERNS_16CallFrameClosureE\r
+__ZN3JSC8JSObject23allocatePropertyStorageEmm
+__ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSCL11getPropertyEPNS_9ExecStateEPNS_8JSObjectEj
+__ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC7JSArray9setLengthEj
+__ZN3JSC10JSFunction16getConstructDataERNS_13ConstructDataE
+__ZN3JSC8JSObject17createInheritorIDEv
+__ZN3JSCL25functionProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC10JSFunction9classInfoEv
+__ZN3JSCplERKNS_7UStringES2_
+__ZN3JSC7UString6appendEPKc
+__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC18RegExpMatchesArray17fillArrayInstanceEPNS_9ExecStateE
+__ZN3JSCL19arrayProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE
+__ZN3JSC24ApplyFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14ExpressionNode13isSimpleArrayEv
+__ZN3JSC17BytecodeGenerator26emitJumpIfNotFunctionApplyEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC17BytecodeGenerator15emitCallVarargsEPNS_10RegisterIDES2_S2_S2_jjj
+__ZN3JSC24ApplyFunctionCallDotNodeD0Ev
+__ZNK3JSC7JSArray9classInfoEv
+__ZN3JSC7JSArray15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
 __ZNK3JSC7UString30spliceSubstringsWithSeparatorsEPKNS0_5RangeEiPKS0_i
-__ZL5matchPKtPKhiR9MatchData
-__ZN3JSC9ThrowNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC9ThrowNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC9ThrowNodeD0Ev
-__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callStringConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC17DeleteBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17DeleteBracketNodeD0Ev
-__ZN3JSC17DeleteBracketNode12releaseNodesERNS_12NodeReleaserE
-__ZNK3JSC6JSCell9getUInt32ERj
+__ZN3JSC7UString17expandPreCapacityEi
+__ZN3JSCL19isInvalidParamForInEPNS_9ExecStateEPNS_9CodeBlockEPKNS_11InstructionENS_7JSValueERS7_
+__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC7UString4fromEd
+__ZN3WTF4dtoaEPcdiPiS1_PS0_
+__ZN3JSC12ContinueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14continueTargetERKNS_10IdentifierE
+__ZN3JSC13DeleteDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitDeleteByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3JSC12ContinueNodeD0Ev
+__ZN3JSC13DeleteDotNodeD0Ev
+__ZN3JSC10JSFunction14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC9Structure24removePropertyTransitionEPS0_RKNS_10IdentifierERm
-__ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL18arrayProtoFuncPushEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL18arrayProtoFuncJoinEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZNK3JSC7ArgList8getSliceEiRS0_
+__ZNK3JSC12StringObject12toThisStringEPNS_9ExecStateE
+__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
+__ZNK3JSC8JSObject11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZN3JSCL22arrayProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3WTF7HashSetIPN3JSC8JSObjectENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
 __ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC11Interpreter14uncacheGetByIDEPNS_9CodeBlockEPNS_11InstructionE
-__ZNK3JSC6JSCell17getTruncatedInt32ERi
-__ZN3JSC15toInt32SlowCaseEdRb
-__ZN3JSC10JSFunction3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZNK3JSC7ArgList8getSliceEiRS0_
-__ZN3JSC12RegExpObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL18regExpObjectSourceEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL19regExpProtoFuncExecEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC12RegExpObject5matchEPNS_9ExecStateERKNS_7ArgListE
-__ZNK3JSC12JSNumberCell9toBooleanEPNS_9ExecStateE
-__ZN3JSC28globalFuncDecodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL6decodeEPNS_9ExecStateERKNS_7ArgListEPKcb
-__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE
-__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC18RegExpMatchesArray17fillArrayInstanceEPNS_9ExecStateE
-__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC28globalFuncEncodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC7UString4fromEi
+__ZN3WTF6VectorItLm256EE6appendItEEvPKT_m
+__ZN3JSCL21arrayProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12nonInlineNaNEv
+__ZN3JSC16ErrorConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL29constructWithErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC14constructErrorEPNS_9ExecStateERKNS_7ArgListE
+__ZN3WTF21CrossThreadRefCountedINS_16OwnFastMallocPtrItEEE5derefEv
+__ZN3WTF6VectorINS_6RefPtrIN3JSC10RegisterIDEEELm16EE14expandCapacityEm
+__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
+__ZN3JSC11Interpreter7executeEPNS_16FunctionBodyNodeEPNS_9ExecStateEPNS_10JSFunctionEPNS_8JSObjectERKNS_7ArgListEPNS_14ScopeChainNodeEPNS_7JSValueE
+__ZN3JSC15TypeOfValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15TypeOfValueNodeD0Ev
+__ZN3JSC20jsTypeStringForValueEPNS_9ExecStateENS_7JSValueE
+__ZN3JSC10Identifier5equalEPKNS_7UString3RepEPKc
+__ZN3JSC13UnaryPlusNodeD0Ev
+__ZNK3JSC8JSString8toNumberEPNS_9ExecStateE
+__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3JSC17RegExpConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC15constructRegExpEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC18globalFuncUnescapeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7UString6appendEt
+__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm8EE14expandCapacityEm
+__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC4Heap7collectEv
+__ZN3JSC4Heap30markStackObjectsConservativelyEv
+__ZN3JSC4Heap31markCurrentThreadConservativelyEv
+__ZN3JSC4Heap39markCurrentThreadConservativelyInternalEv
+__ZN3JSC4Heap18markConservativelyEPvS1_
+__ZN3JSC14JSGlobalObject4markEv
+__ZN3JSC8JSObject4markEv
+__ZN3JSC6JSCell4markEv
+__ZN3JSC10JSFunction4markEv
+__ZN3JSC16FunctionBodyNode4markEv
+__ZN3JSC9CodeBlock4markEv
+__ZN3JSC12JSActivation4markEv
+__ZN3JSC9Arguments4markEv
+__ZN3JSC7JSArray4markEv
+__ZN3JSC15JSWrapperObject4markEv
+__ZN3JSC18GlobalEvalFunction4markEv
+__ZN3JSC19JSStaticScopeObject4markEv
+__ZN3JSC4Heap20markProtectedObjectsEv
+__ZN3JSC12SmallStrings4markEv
+__ZN3JSC4Heap5sweepILNS_8HeapTypeE0EEEmv
+__ZN3JSC12RegExpObjectD1Ev
+__ZN3JSC12JSActivationD1Ev
+__ZN3JSC12JSActivationD2Ev
+__ZN3JSC9ArgumentsD1Ev
+__ZN3JSC9ArgumentsD2Ev
+__ZN3JSC18RegExpMatchesArrayD1Ev
+__ZN3JSC8JSObjectD1Ev
+__ZN3JSC22JSPropertyNameIteratorD1Ev
+__ZN3JSC12StringObjectD1Ev
+__ZN3JSC8JSObjectD2Ev
+__ZN3JSC4Heap5sweepILNS_8HeapTypeE1EEEmv
+__ZNK3JSC19JSStaticScopeObject14isDynamicScopeEv
+__ZN3JSC17ReadModifyDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17ReadModifyDotNodeD0Ev
+__ZN3JSC7UString10BaseString20slowIsBufferReadOnlyEv
+__ZN3JSC18BooleanConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL22callBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18arrayProtoFuncJoinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorItLm256EE14expandCapacityEm
+__ZN3JSC19FunctionConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL32constructWithFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
+__ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC10SwitchNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13CaseBlockNode20emitBytecodeForBlockERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_
+__ZN3JSC13CaseBlockNode18tryOptimizedSwitchERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERiS7_
+__ZN3JSCL17processClauseListEPNS_14ClauseListNodeERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERNS_10SwitchKindERbRiSB_
+__ZN3WTF6VectorINS_6RefPtrIN3JSC5LabelEEELm8EE15reserveCapacityEm
+__ZN3JSC17BytecodeGenerator11beginSwitchEPNS_10RegisterIDENS_10SwitchInfo10SwitchTypeE
+__ZN3WTF6VectorIN3JSC10SwitchInfoELm0EE14expandCapacityEm
+__ZN3WTF6VectorIiLm8EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator9endSwitchEjPN3WTF6RefPtrINS_5LabelEEEPPNS_14ExpressionNodeEPS3_ii
+__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14expandCapacityEm
+__ZN3JSC14CaseClauseNodeD0Ev
+__ZN3JSC14ClauseListNodeD0Ev
+__ZN3JSC13CaseBlockNodeD0Ev
+__ZN3JSC10SwitchNodeD0Ev
+__ZN3JSC5equalEPKNS_7UString3RepES3_
+__ZN3JSC28globalFuncEncodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL6encodeEPNS_9ExecStateERKNS_7ArgListEPKc
-__ZN3JSC7UString6appendEPKc
-__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_10JSValuePtrE
-__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEPNS_9ExecStateEj
+__ZNK3JSC7UString10UTF8StringEb
+__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
+__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7UStringC2EPtib
+__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm16EE14expandCapacityEm
+__ZN3JSC7UString13appendNumericEi
+__ZN3JSC11concatenateEPNS_7UString3RepEi
+__ZNK3JSC8NullNode6isNullEv
+__ZN3JSC13GreaterEqNodeD0Ev
+__ZL12makeMultNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC8MultNodeD0Ev
+__ZN3JSCL19mathProtoFuncRandomEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF16weakRandomNumberEv
+__ZN3JSC12jsNumberCellEPNS_9ExecStateEd
+__ZN3JSCL17mathProtoFuncCeilEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7UString3Rep11computeHashEPKti
+__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
+__ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC20EvalFunctionCallNodeD0Ev
+__ZN3JSC11Interpreter22resolveBaseAndPropertyEPNS_9ExecStateEPNS_11InstructionERNS_7JSValueE
+__ZN3JSC15globalFuncIsNaNEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEiiRNS_7JSValueE
+__ZN3JSC13LiteralParser5Lexer3lexERNS1_18LiteralParserTokenE
+__ZN3JSC13LiteralParser5parseENS0_11ParserStateE
+__ZNK3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS1_INS2_8EvalNodeEEENS_7StrHashIS5_EENS_10HashTraitsIS5_EENSA_IS7_EEE3getEPS4_
+__ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS1_INS2_8EvalNodeEEEENS_18PairFirstExtractorIS9_EENS_7StrHashIS5_EENS_14PairHashTraitsINS_10HashTraitsIS5_EENSF_IS8_EEEESG_E6expandEv
+__ZN3JSC9ExecState9thisValueEv
+__ZN3JSC11Interpreter7executeEPNS_8EvalNodeEPNS_9ExecStateEPNS_8JSObjectEiPNS_14ScopeChainNodeEPNS_7JSValueE
+__ZN3JSC8EvalNode16generateBytecodeEPNS_14ScopeChainNodeE
+__ZN3JSC17BytecodeGeneratorC2EPNS_8EvalNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISE_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE
+__ZN3JSC8EvalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11Interpreter11resolveBaseEPNS_9ExecStateEPNS_11InstructionE
+__ZN3JSC10LessEqNodeD0Ev
+__ZN3JSC16globalFuncEscapeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZThn12_N3JSC8EvalNodeD0Ev
+__ZN3JSC8EvalNodeD0Ev
+__ZN3JSC22JSPropertyNameIterator4markEv
+__ZN3JSC21ReadModifyResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC21ReadModifyResolveNodeD0Ev
+__ZN3JSC28globalFuncDecodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL6decodeEPNS_9ExecStateERKNS_7ArgListEPKcb
+__ZNK3JSC12JSNumberCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZN3JSC7UString13appendNumericEd
+__ZN3JSC11concatenateEPNS_7UString3RepEd
+__ZN3JSC14jsIsObjectTypeENS_7JSValueE
+__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
+__ZL11makeDivNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC7DivNodeD0Ev
+__ZN3JSC15DateConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL28constructWithDateConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC13constructDateEPNS_9ExecStateERKNS_7ArgListE
+__ZN3WTF17getCurrentUTCTimeEv
+__ZN3WTF8timeClipEd
+__ZN3JSC13DatePrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12DateInstance9classInfoEv
+__ZNK3JSC12DateInstance21msToGregorianDateTimeEdbRN3WTF17GregorianDateTimeE
+__ZN3WTF21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
+__ZN3WTF12getUTCOffsetEv
+__ZN3WTFL12getDSTOffsetEdd
+__ZN3JSCL21dateProtoFuncGetHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF13tryFastMallocEm
+__ZN3JSC10BitAndNodeD0Ev
+__ZN3JSC18globalFuncParseIntEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL8parseIntERKNS_7UStringEi
+__ZN3JSCL20dateProtoFuncGetTimeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
+__ZN3JSC26createNotAnObjectErrorStubEPNS_9ExecStateEb
+__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_7JSValueEjb
+__ZNK3JSC22JSNotAnObjectErrorStub22isNotAnObjectErrorStubEv
+__ZN3JSC22createNotAnObjectErrorEPNS_9ExecStateEPNS_22JSNotAnObjectErrorStubEjPNS_9CodeBlockE
+__ZN3JSC9CodeBlock37getByIdExceptionInfoForBytecodeOffsetEPNS_9ExecStateEjRNS_8OpcodeIDE
 __ZN3JSC9CodeBlock34reparseForExceptionInfoIfNecessaryEPNS_9ExecStateE
+__ZNK3JSC10ScopeChain10localDepthEv
+__ZNK3JSC12JSActivation9classInfoEv
 __ZN3JSC6Parser7reparseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPS5_
-__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm0EEERKNS_10SourceCodeEji
+__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_IPNS_12FuncDeclNodeELm0EEERKNS_10SourceCodeEji
 __ZN3JSC13StatementNode6setLocEii
 __ZN3JSC16FunctionBodyNode14copyParametersEv
 __ZN3JSC16FunctionBodyNode13finishParsingEPNS_10IdentifierEm
 __ZN3JSC16FunctionBodyNode31bytecodeForExceptionInfoReparseEPNS_14ScopeChainNodeEPNS_9CodeBlockE
 __ZN3JSC9CodeBlock43hasGlobalResolveInstructionAtBytecodeOffsetEj
-__ZN3JSCL22functionProtoFuncApplyEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC9CodeBlock32expressionRangeForBytecodeOffsetEPNS_9ExecStateEjRiS3_S3_
+__ZN3JSCL18createErrorMessageEPNS_9ExecStateEPNS_9CodeBlockEiiiNS_7JSValueENS_7UStringE
+__ZN3JSC5Error6createEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringEilS6_
+__ZN3JSC22NativeErrorConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL35constructWithNativeErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC22NativeErrorConstructor9constructEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
+__ZN3JSC9CodeBlock24handlerForBytecodeOffsetEj
+__ZN3JSC11Interpreter20createExceptionScopeEPNS_9ExecStateEPKNS_11InstructionE
+__ZN3JSC23FunctionCallBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC23FunctionCallBracketNodeD0Ev
+__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24stringProtoFuncSubstringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18mathProtoFuncFloorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL19dateProtoFuncGetDayEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21dateProtoFuncGetMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorIjLm16EE6resizeEm
+__ZN3JSCL24dateProtoFuncToGMTStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10formatTimeERKN3WTF17GregorianDateTimeEb
+__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZNK3JSC12JSNumberCell8toObjectEPNS_9ExecStateE
+__ZN3JSC15constructNumberEPNS_9ExecStateENS_7JSValueE
+__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12JSNumberCell8toStringEPNS_9ExecStateE
+__ZN3JSC14PostfixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC14PostfixDotNodeD0Ev
+__ZN3JSCL19regExpProtoFuncExecEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL20stringProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL22objectProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC14InstanceOfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitInstanceOfEPNS_10RegisterIDES2_S2_S2_
+__ZN3JSC14InstanceOfNodeD0Ev
+__ZN3JSCL27isInvalidParamForInstanceOfEPNS_9ExecStateEPNS_9CodeBlockEPKNS_11InstructionENS_7JSValueERS7_
+__ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateENS_7JSValueES3_
+__ZN3JSCL20arrayProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callStringConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12StringObject8toStringEPNS_9ExecStateE
+__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7UString12replaceRangeEiiRKS0_
+__ZN3JSCL23stringProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC13jsAddSlowCaseEPNS_9ExecStateENS_7JSValueES2_
+__ZNK3JSC12StringObject9classInfoEv
+__ZN3WTFL15dateToDayInYearEiii
+__ZN3JSCL23dateProtoFuncGetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL7dateNowEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC19JSStaticScopeObjectD1Ev
+__ZN3JSC19JSStaticScopeObjectD2Ev
+__ZN3JSC13ErrorInstanceD1Ev
+__ZN3JSC13JSNotAnObjectD1Ev
+__ZN3JSC22JSNotAnObjectErrorStubD1Ev
+__ZN3JSC12NumberObjectD1Ev
+__ZN3JSC12DateInstanceD1Ev
+__ZN3JSC17PrefixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17PrefixResolveNodeD0Ev
+__ZN3JSCL29objectProtoFuncHasOwnPropertyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC17ObjectConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithObjectConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSCL24regExpConstructorDollar2EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar3EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar4EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
+__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEPNS_9ExecStateEj
+__ZN3JSC21ReadModifyBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC7ModNodeD0Ev
+__ZN3JSC21ReadModifyBracketNodeD0Ev
+__ZN3JSC10BitXOrNodeD0Ev
+__ZN3JSCL18mathProtoFuncRoundEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZL17makeLeftShiftNodePvPN3JSC14ExpressionNodeES2_b
+__ZL18makeRightShiftNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC13LeftShiftNodeD0Ev
+__ZN3JSC14RightShiftNodeD0Ev
+__ZN3JSCL25stringProtoFuncCharCodeAtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC15toInt32SlowCaseEdRb
+__ZN3JSC10NegateNodeD0Ev
+__ZN3JSC11DoWhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11DoWhileNodeD0Ev
+__ZN3JSCL16mathProtoFuncMaxEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC17PrefixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17PrefixBracketNodeD0Ev
+__ZN3JSC10JSONObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL22JSONProtoFuncStringifyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11StringifierC2EPNS_9ExecStateENS_7JSValueES3_
+__ZN3JSC11Stringifier9stringifyENS_7JSValueE
+__ZN3JSC11Stringifier22appendStringifiedValueERNS_7UStringENS_7JSValueEPNS_8JSObjectERKNS_27PropertyNameForFunctionCallE
+__ZNK3JSC6JSCell9getStringERNS_7UStringE
+__ZN3JSC11Stringifier6Holder18appendNextPropertyERS0_RNS_7UStringE
+__ZNK3JSC7UString6substrEii
+__ZNK3JSC7UStringixEi
+__ZN3JSC11Stringifier18appendQuotedStringERNS_7UStringERKS1_
+__ZN3JSC7UString6appendEPKti
+__ZN3JSC11StringifierD2Ev
+__ZN3JSCL18JSONProtoFuncParseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC13LiteralParser5Lexer9lexStringILNS0_10ParserModeE0EEENS0_9TokenTypeERNS1_18LiteralParserTokenE
+__ZN3JSC13LiteralParser5Lexer9lexNumberERNS1_18LiteralParserTokenE
+__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateEjNS_7JSValueE
+__ZNK3JSC8JSObject22isNotAnObjectErrorStubEv
+__ZNK3JSC8JSObject19isWatchdogExceptionEv
+__ZN3JSC11Interpreter15unwindCallFrameERPNS_9ExecStateENS_7JSValueERjRPNS_9CodeBlockE
+__ZN3JSC19JSStaticScopeObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE
+__ZN3JSC17PropertyNameArray3addEPNS_7UString3RepE
+__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7PtrHashIS4_EENS_10HashTraitsIS4_EEE3addERKS4_
+__ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7PtrHashIS4_EENS_10HashTraitsIS4_EESA_E6rehashEi
+__ZN3JSC17PrototypeFunctionD1Ev
+__ZN3JSC15ObjectPrototypeD1Ev
+__ZN3JSC17FunctionPrototypeD1Ev
+__ZN3JSC14JSGlobalObjectD2Ev
+__ZN3JSC18GlobalEvalFunctionD1Ev
+__ZN3JSC10JSONObjectD1Ev
+__ZN3JSC10MathObjectD1Ev
+__ZN3JSC22NativeErrorConstructorD1Ev
+__ZN3JSC16ErrorConstructorD1Ev
+__ZN3JSC17RegExpConstructorD1Ev
+__ZN3JSC15DateConstructorD1Ev
+__ZN3JSC17NumberConstructorD1Ev
+__ZN3JSC18BooleanConstructorD1Ev
+__ZN3JSC17StringConstructorD1Ev
+__ZN3JSC16ArrayConstructorD1Ev
+__ZN3JSC19FunctionConstructorD1Ev
+__ZN3JSC17ObjectConstructorD1Ev
+__ZN3JSC20NativeErrorPrototypeD1Ev
+__ZN3JSC14ErrorPrototypeD1Ev
+__ZN3JSC15RegExpPrototypeD1Ev
+__ZN3JSC13DatePrototypeD1Ev
+__ZN3JSC12DateInstanceD2Ev
+__ZN3JSC15NumberPrototypeD1Ev
+__ZN3JSC16BooleanPrototypeD1Ev
+__ZN3JSC15StringPrototypeD1Ev
+__ZN3JSC14ArrayPrototypeD1Ev
+__ZN3JSC17DeleteBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator15emitDeleteByValEPNS_10RegisterIDES2_S2_
+__ZN3JSC17DeleteBracketNodeD0Ev
+__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSObject9classNameEv
+__ZN3JSC17StringConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithStringConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC12RegExpObject11getCallDataERNS_8CallDataE
+__ZN3JSC4Heap15recordExtraCostEm
+__ZN3JSC7JSArray4pushEPNS_9ExecStateENS_7JSValueE
+__ZN3JSCL21dateProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
+__ZN3JSCL20dateProtoFuncGetDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11Interpreter11resolveSkipEPNS_9ExecStateEPNS_11InstructionERNS_7JSValueE
+__ZN3JSC9Structure27despecifyDictionaryFunctionERKNS_10IdentifierE
+__ZN3JSC17DeleteResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17DeleteResolveNodeD0Ev
+__ZN3JSCL21arrayProtoFuncUnShiftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11Interpreter14uncachePutByIDEPNS_9CodeBlockEPNS_11InstructionE
 __ZNK3JSC9Arguments9classInfoEv
-__ZN3JSC9Arguments11fillArgListEPNS_9ExecStateERNS_7ArgListE
-__ZN3JSC7TryNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator9emitCatchEPNS_10RegisterIDEPNS_5LabelES4_
-__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14expandCapacityEm
-__ZN3JSC17BytecodeGenerator16emitPushNewScopeEPNS_10RegisterIDERNS_10IdentifierES2_
-__ZN3JSC7TryNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC7TryNodeD0Ev
-__ZN3JSCL21stringProtoFuncSubstrEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC10JSValuePtr9toIntegerEPNS_9ExecStateE
+__ZN3JSC9Arguments15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
+__ZN3JSC9Arguments3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
+__ZN3WTF6VectorIPN3JSC9StructureELm8EE14expandCapacityEm
+__ZN3JSC12StringObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC9ExecState11stringTableEPS0_
+__ZN3JSCL16mathProtoFuncMinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTFL7multaddERNS_6BigIntEii
+__ZN3WTF6VectorIjLm16EEaSERKS1_
+__ZN3WTFL4multERNS_6BigIntERKS0_
+__ZN3JSC18PostfixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC18PostfixBracketNodeD0Ev
+__ZN3JSCL21arrayProtoFuncReverseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__Z15jsc_pcre_xclassiPKh
+__ZN3JSC8VoidNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8VoidNodeD0Ev
+__ZN3JSC12JSActivation3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZNK3JSC9ArrayNode13isSimpleArrayEv
+__ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18regExpObjectSourceEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC17RegExpConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL20arrayProtoFuncSpliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18arrayProtoFuncSortEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray4sortEPNS_9ExecStateE
+__ZN3JSC7JSArray17compactForSortingEv
+__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3WTF6VectorIN3JSC7UString5RangeELm16EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC7UStringELm16EE14expandCapacityEm
+__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray3popEv
+__ZN3JSCL21functionProtoFuncCallEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12JSActivation14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSCL9dateParseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12RegExpObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSCL24setRegExpObjectLastIndexEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
+__ZN3JSCL28regExpConstructorLeftContextEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL21stringProtoFuncSubstrEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierEjPNS_9CodeBlockE
+__ZN3JSC36constructBooleanFromImmediateBooleanEPNS_9ExecStateENS_7JSValueE
+__ZN3JSCL26stringProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue20toIntegerPreserveNaNEPNS_9ExecStateE
+__ZNK3JSC7UString5rfindERKS0_i
+__ZN3JSC19globalFuncEncodeURIEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC13UnaryPlusNode14stripUnaryPlusEv
+__ZN3JSC8JSString18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
+__ZN3JSC13BooleanObjectD1Ev
+__ZN3WTF17TCMalloc_PageHeap3NewEm
+__ZNK3JSC21UStringSourceProvider8getRangeEii
+__ZN3JSCL23dateProtoFuncGetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
+__ZN3JSCL24dateProtoFuncGetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF21gregorianDateTimeToMSERKNS_17GregorianDateTimeEdb
+__ZN3JSCL27compareByStringPairForQSortEPKvS1_
+__ZN3JSCL29regExpConstructorRightContextEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZNK3JSC12NumberObject9classInfoEv
+__ZN3JSCL19isNonASCIIIdentPartEi
+__ZN3JSC8EvalNode4markEv
+__ZN3WTF7Unicode18UTF8SequenceLengthEc
+__ZN3WTF7Unicode18decodeUTF8SequenceEPKc
+__ZN3JSC18globalFuncIsFiniteEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24booleanProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncToUTCStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
+__ZN3JSC16InternalFunction4nameEPNS_12JSGlobalDataE
+__ZN3JSC16ArrayConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL20callArrayConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21stringProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZNK3JSC8JSString8toObjectEPNS_9ExecStateE
+__ZN3JSC17ObjectConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callObjectConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC13LiteralParser5Lexer9lexStringILNS0_10ParserModeE1EEENS0_9TokenTypeERNS1_18LiteralParserTokenE
+__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE14expandCapacityEmPKS4_
+__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE15reserveCapacityEm
+__ZN3JSCL16mathProtoFuncAbsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL22numberProtoFuncToFixedEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16integerPartNoExpEd
+__ZN3JSCL16mathProtoFuncLogEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncPowEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF13tryFastCallocEmm
+__ZN3JSC7JSArray11sortNumericEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE
+__ZN3JSCL22compareNumbersForQSortEPKvS1_
+__ZN3JSCL22functionProtoFuncApplyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC9Arguments11fillArgListEPNS_9ExecStateERNS_20MarkedArgumentBufferE
+__ZN3JSC7JSArray16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC9ExecState10arrayTableEPS0_
+__ZN3JSCL23regExpProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18regExpObjectGlobalEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL22regExpObjectIgnoreCaseEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL21regExpObjectMultilineEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZNK3JSC12JSNumberCell12toThisObjectEPNS_9ExecStateE
+__ZN3JSCL22numberProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12NumberObject11getJSNumberEv
+__ZNK3JSC7JSValue16synthesizeObjectEPNS_9ExecStateE
+__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSCL22errorProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10JSFunction15argumentsGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZNK3JSC11Interpreter17retrieveArgumentsEPNS_9ExecStateEPNS_10JSFunctionE
+__ZN3JSCL21dateProtoFuncSetMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23setNewValueFromDateArgsEPNS_9ExecStateENS_7JSValueERKNS_7ArgListEib
+__ZN3JSCL20dateProtoFuncSetDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC9BitOrNodeD0Ev
+__ZN3JSC12JSGlobalData6createEb
+__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
+__ZN3JSC7CStringD1Ev
+__ZN3JSCL17mathProtoFuncSqrtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncCosEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncSinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC14BitwiseNotNodeD0Ev
+__ZN3JSC22UnsignedRightShiftNodeD0Ev
+__ZN3JSC16toUInt32SlowCaseEdRb
+__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14expandCapacityEm
+__ZN3WTF6VectorIiLm0EE15reserveCapacityEm
+__ZN3JSC15SimpleJumpTable14offsetForValueEii
+__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
+__ZN3WTF7HashSetIPN3JSC20MarkedArgumentBufferENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3JSC7JSArray4sortEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE
+__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE6insertEi
 __ZN3JSCltERKNS_7UStringES2_
-__ZN3JSC9BreakNodeD0Ev
-__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi
-__ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE
-__ZNK3JSC10ScopeChain10localDepthEv
-__ZNK3JSC12JSActivation9classInfoEv
-__ZN3JSCL30comparePropertyMapEntryIndicesEPKvS1_
-__ZN3WTF6VectorIN3JSC10IdentifierELm20EE15reserveCapacityEm
-__ZN3JSCL19regExpProtoFuncTestEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3WTF12detachThreadEj
-__ZN3WTFL26pthreadHandleForIdentifierEj
-__ZN3WTFL31clearPthreadHandleForIdentifierEj
-__ZN3JSC18RegExpMatchesArrayD1Ev
-__ZN3JSC12RegExpObjectD1Ev
-__Z12jsRegExpFreeP8JSRegExp
-__ZN3JSC6RegExpD1Ev
+__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE7balanceEi
+__ZN3JSC4Heap7destroyEv
+__ZN3JSC12JSGlobalDataD1Ev
+__ZN3JSC12JSGlobalDataD2Ev
+__ZN3JSC12RegisterFileD1Ev
+__ZNK3JSC9HashTable11deleteTableEv
+__ZN3JSC5LexerD1Ev
+__ZN3JSC5LexerD2Ev
+__ZN3WTF20deleteAllPairSecondsIP24OpaqueJSClassContextDataKNS_7HashMapIP13OpaqueJSClassS2_NS_7PtrHashIS5_EENS_10HashTraitsIS5_EENS8_IS2_EEEEEEvRT0_
+__ZN3JSC17CommonIdentifiersD2Ev
+__ZN3JSC21deleteIdentifierTableEPNS_15IdentifierTableE
+__ZN3JSC4HeapD1Ev
+__ZN3JSC12SmallStringsD1Ev
index 05c300cde0e15782fd85eff16df4d55f12f8862f..3ae3ec6dd3bccc2af31e7cca009a3680325321b8 100644 (file)
@@ -1,18 +1,20 @@
-__ZN3WTF19initializeThreadingEv
 __ZN3WTF10fastMallocEm
 __ZN3WTF10fastMallocILb1EEEPvm
 __ZN3WTF20TCMalloc_ThreadCache10InitModuleEv
 __ZN3WTFL15InitSizeClassesEv
 __Z20TCMalloc_SystemAllocmPmm
+__ZN3WTFL13MetaDataAllocEm
 __ZN3WTF20TCMalloc_ThreadCache22CreateCacheIfNecessaryEv
 __ZN3WTF25TCMalloc_Central_FreeList11RemoveRangeEPPvS2_Pi
 __ZN3WTF25TCMalloc_Central_FreeList18FetchFromSpansSafeEv
 __ZN3WTF17TCMalloc_PageHeap10AllocLargeEm
 __ZN3WTF17TCMalloc_PageHeap8GrowHeapEm
-__ZN3WTFL13MetaDataAllocEm
+__ZN3WTF19initializeThreadingEv
 __ZN3WTF20initializeMainThreadEv
 __ZN3WTF5MutexC1Ev
+__ZN3WTF28initializeMainThreadPlatformEv
 __ZN3WTF36lockAtomicallyInitializedStaticMutexEv
+__ZN3WTF8fastFreeEPv
 __ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
 __ZN3JSC19initializeThreadingEv
 __ZN3JSCL23initializeThreadingOnceEv
@@ -22,95 +24,128 @@ __ZN3WTF11currentTimeEv
 __ZN3WTF15ThreadConditionC1Ev
 __ZN3WTF5Mutex4lockEv
 __ZN3WTF5Mutex6unlockEv
-__ZN3WTF8fastFreeEPv
 __ZN3WTF12createThreadEPFPvS0_ES0_PKc
 __ZN3WTF20createThreadInternalEPFPvS0_ES0_PKc
 __ZN3WTFL35establishIdentifierForPthreadHandleERP17_opaque_pthread_t
+__ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTrai
 __ZN3WTFL16threadEntryPointEPv
-__ZN3WTF7HashMapIjP17_opaque_pthread_tNS_7IntHashIjEENS_10HashTraitsIjEENS5_IS2_EEE3addERKjRKS2_
-__ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSA_IS3_EEEESB_E6rehashEi
 __ZN3WTF16fastZeroedMallocEm
+__ZN3WTF21setThreadNameInternalEPKc
 __ZN3WTF5MutexD1Ev
 __ZN3WTF25TCMalloc_Central_FreeList11InsertRangeEPvS1_i
 __ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv
+__ZN3WTF12isMainThreadEv
 __ZN3WTF14FastMallocZone4sizeEP14_malloc_zone_tPKv
 __ZN3WTF13currentThreadEv
 __ZN3WTF16callOnMainThreadEPFvPvES0_
-__ZN3WTF6VectorINS_19FunctionWithContextELm0EE14expandCapacityEm
+__ZN3WTF5DequeINS_19FunctionWithContextEE14expandCapacityEv
 __ZN3WTF37scheduleDispatchFunctionsOnMainThreadEv
 __ZN3WTF15ThreadCondition4waitERNS_5MutexE
 __ZN3JSC8DebuggerC2Ev
 __ZN3WTF6strtodEPKcPPc
 __ZN3WTF15ThreadCondition6signalEv
+__ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd
 __ZN3WTF15ThreadCondition9broadcastEv
+-[WTFMainThreadCaller call]
+__ZN3WTF31dispatchFunctionsFromMainThreadEv
+__ZN3WTF14FastMallocZone9forceLockEP14_malloc_zone_t
+__ZN3WTF11fastReallocEPvm
+__ZN3WTF11fastReallocILb1EEEPvS1_m
+__ZN3JSC7UStringC1EPKti
+__ZN3JSC7UStringC2EPKti
 __ZN3JSC12JSGlobalData12createLeakedEv
-__ZN3JSC12JSGlobalDataC2Eb
-__ZN3JSC11InterpreterC1Ev
-__ZN3JSC11Interpreter14privateExecuteENS0_13ExecutionFlagEPNS_12RegisterFileEPNS_9ExecStateEPNS_10JSValuePtrE
-__ZN3WTF7HashMapIPvN3JSC8OpcodeIDENS_7PtrHashIS1_EENS_10HashTraitsIS1_EENS6_IS3_EEE3addERKS1_RKS3_
-__ZN3WTF9HashTableIPvSt4pairIS1_N3JSC8OpcodeIDEENS_18PairFirstExtractorIS5_EENS_7PtrHashIS1_EENS_14PairHashTraitsINS_10HashTraitsIS1_EENSB_IS4_EEEESC_E6expandEv
-__ZN3JSC9StructureC1ENS_10JSValuePtrERKNS_8TypeInfoE
+__ZN3JSC9Structure18startIgnoringLeaksEv
+__ZN3JSC7VPtrSetC2Ev
+__ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoE
 __ZN3JSC7JSArrayC1EN3WTF10PassRefPtrINS_9StructureEEE
-__ZN3JSC7JSArrayD0Ev
+__ZN3JSC7JSArrayD1Ev
+__ZN3JSC7JSArrayD2Ev
 __ZN3WTF10RefCountedIN3JSC9StructureEE5derefEv
 __ZN3JSC9StructureD1Ev
-__ZN3JSC11JSByteArray15createStructureENS_10JSValuePtrE
+__ZN3JSC9StructureD2Ev
+__ZN3JSC11JSByteArray15createStructureENS_7JSValueE
+__ZN3JSC11JSByteArrayD1Ev
+__ZN3JSC8JSStringD1Ev
+__ZN3JSC10JSFunctionD1Ev
+__ZN3JSC10JSFunctionD2Ev
+__ZN3JSC8JSObjectD2Ev
+__ZN3JSC12JSGlobalDataC2EbRKNS_7VPtrSetE
 __ZN3JSC21createIdentifierTableEv
 __ZN3JSC17CommonIdentifiersC1EPNS_12JSGlobalDataE
+__ZN3JSC17CommonIdentifiersC2EPNS_12JSGlobalDataE
 __ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKc
-__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC7UString3RepEEEENS_18PairFirstExtractorIS9_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSF_IS8_EEEESG_E4findIS2_NS_22IdentityHashTranslatorIS2_S9_SD_EEEENS_17HashTableIteratorIS2_S9_SB_SD_SI_SG_EERKT_
+__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addIPKcNS1_17CStringTranslatorEEESt4pairINS_24HashT
 __ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7StrHashIS4_EENS_10HashTraitsIS4_EESA_E6rehashEi
-__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC7UString3RepEEEENS_18PairFirstExtractorIS9_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSF_IS8_EEEESG_E6expandEv
-__ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7StrHashIS4_EENS_10HashTraitsIS4_EESA_E4findIS4_NS_22IdentityHashTranslatorIS4_S4_S8_EEEENS_17HashTableIteratorIS4_S4_S6_S8_SA_SA_EERKT_
+__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC7UString3RepEEEENS_18PairFirstExtractorIS9_EENS_7PtrHashIS2_EENS_14PairHashTra
+__ZN3WTF6RefPtrIN3JSC7UString3RepEED1Ev
 __ZN3JSC12SmallStringsC1Ev
-__ZN3JSC5LexerC1EPNS_12JSGlobalDataE
-__ZN3JSC4HeapC1EPNS_12JSGlobalDataE
 __ZN3JSC19ExecutableAllocator17intializePageSizeEv
 __ZN3JSC14ExecutablePool11systemAllocEm
-__ZN3JSC27startProfilerServerIfNeededEv
-+[ProfilerServer sharedProfileServer]
--[ProfilerServer init]
-__ZN3JSC11Interpreter10initializeEPNS_12JSGlobalDataE
+__ZN3JSC5LexerC1EPNS_12JSGlobalDataE
+__ZN3JSC5LexerC2EPNS_12JSGlobalDataE
+__ZN3JSC11InterpreterC1Ev
+__ZN3JSC11InterpreterC2Ev
+__ZN3JSC11Interpreter14privateExecuteENS0_13ExecutionFlagEPNS_12RegisterFileEPNS_9ExecStateEPNS_7JSValueE
+__ZN3WTF7HashMapIPvN3JSC8OpcodeIDENS_7PtrHashIS1_EENS_10HashTraitsIS1_EENS6_IS3_EEE3addERKS1_RKS3_
+__ZN3WTF9HashTableIPvSt4pairIS1_N3JSC8OpcodeIDEENS_18PairFirstExtractorIS5_EENS_7PtrHashIS1_EENS_14PairHashTraitsINS_10HashTrai
+__ZN3JSC8JITStubsC1EPNS_12JSGlobalDataE
 __ZN3JSC3JITC1EPNS_12JSGlobalDataEPNS_9CodeBlockE
-__ZN3JSC3JIT35privateCompileCTIMachineTrampolinesEv
+__ZN3JSC3JITC2EPNS_12JSGlobalDataEPNS_9CodeBlockE
+__ZN3JSC3JIT35privateCompileCTIMachineTrampolinesEPN3WTF6RefPtrINS_14ExecutablePoolEEEPNS_12JSGlobalDataEPPvS9_S9_S9_S9_S9_
+__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDE
+__ZN3JSC12X86Assembler3jCCENS0_9ConditionE
+__ZN3JSC23MacroAssemblerX86Common4moveENS_22AbstractMacroAssemblerINS_12X86AssemblerEE6ImmPtrENS_3X8610RegisterIDE
+__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDE
 __ZN3JSC15AssemblerBuffer11ensureSpaceEi
+__ZN3JSC20MacroAssemblerX86_6413branchTestPtrENS_23MacroAssemblerX86Common9ConditionENS_3X8610RegisterIDENS_22AbstractMacroAsse
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDENS_3X8610RegisterIDE
+__ZN3JSC20MacroAssemblerX86_644callEv
 __ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDEi
-__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDE
-__ZN3JSC14MacroAssembler4pokeENS_3X8610RegisterIDEi
 __ZN3JSC3JIT32compileOpCallInitializeCallFrameEv
-__ZN3JSC14MacroAssembler5jnz32ENS_3X8610RegisterIDENS0_5Imm32E
-__ZN3WTF11fastReallocEPvm
-__ZN3WTF11fastReallocILb1EEEPvS1_m
+__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_3X8610RegisterIDEi
+__ZN3JSC20MacroAssemblerX86_6421makeTailRecursiveCallENS_22AbstractMacroAssemblerINS_12X86AssemblerEE4JumpE
+__ZN3JSC14TimeoutCheckerC1Ev
+__ZN3JSC4HeapC1EPNS_12JSGlobalDataE
+__ZN3JSC27startProfilerServerIfNeededEv
++[ProfilerServer sharedProfileServer]
+-[ProfilerServer init]
+__ZN3JSC9Structure17stopIgnoringLeaksEv
 __ZN3JSC4Heap8allocateEm
 __ZN3JSCL13allocateBlockILNS_8HeapTypeE0EEEPNS_14CollectorBlockEv
+__ZN3JSC4Heap4heapENS_7JSValueE
+__ZN3JSC4Heap7protectENS_7JSValueE
+__ZN3WTF7HashMapIPN3JSC6JSCellEjNS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS6_IjEEE3addERKS3_RKj
+__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraits
 __ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
 __ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
-__ZN3JSC14JSGlobalObject5resetENS_10JSValuePtrE
+__ZN3JSC14JSGlobalObject5resetENS_7JSValueE
 __ZN3JSC4Heap12heapAllocateILNS_8HeapTypeE0EEEPvm
-__ZN3JSC17FunctionPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
 __ZN3JSC8jsStringEPNS_12JSGlobalDataERKNS_7UStringE
 __ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
 __ZN3JSC7UStringC1EPKc
 __ZN3JSCL9createRepEPKc
-__ZN3JSC8JSObject9putDirectERKNS_10IdentifierENS_10JSValuePtrEjbRNS_15PutPropertySlotE
+__ZN3JSC8JSObject9putDirectERKNS_10IdentifierENS_7JSValueEjbRNS_15PutPropertySlotE
 __ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjRm
 __ZN3JSC9Structure3getERKNS_10IdentifierERj
 __ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjRm
 __ZN3JSC9Structure3putERKNS_10IdentifierEj
+__ZN3JSC8JSObject26putDirectWithoutTransitionERKNS_10IdentifierENS_7JSValueEj
 __ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEj
-__ZN3JSC17FunctionPrototype21addFunctionPropertiesEPNS_9ExecStateEPNS_9StructureE
-__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectESA_RKNS_7ArgListEE
+__ZN3JSC17FunctionPrototype21addFunctionPropertiesEPNS_9ExecStateEPNS_9StructureEPPNS_10JSFunctionES7_
+__ZN3JSC10JSFunctionC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RK
+__ZN3JSC12JSGlobalData17createNativeThunkEv
+__ZN3JSC16FunctionBodyNode17createNativeThunkEPNS_12JSGlobalDataE
+__ZN3WTF6VectorINS_6RefPtrIN3JSC21ParserArenaRefCountedEEELm0EE15reserveCapacityEm
+__ZN3JSC11ParserArena5resetEv
 __ZN3JSC8JSObject34putDirectFunctionWithoutTransitionEPNS_9ExecStateEPNS_16InternalFunctionEj
 __ZN3JSC15ObjectPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
 __ZN3JSC9Structure26rehashPropertyMapHashTableEj
 __ZN3JSC15StringPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
 __ZN3JSC16BooleanPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
 __ZN3JSC15NumberPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC12jsNumberCellEPNS_9ExecStateEd
-__ZN3JSCL13allocateBlockILNS_8HeapTypeE1EEEPNS_14CollectorBlockEv
 __ZN3JSC15RegExpPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
 __ZN3JSC14ErrorPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
-__ZN3WTF6RefPtrIN3JSC7UString3RepEED1Ev
 __ZN3JSC20NativeErrorPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringES9_
 __ZN3JSC17ObjectConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_15ObjectPrototypeE
 __ZN3JSC19FunctionConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_17FunctionPrototypeE
@@ -132,1507 +167,1799 @@ __ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPNS_7UString3RepE
 __ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addERKS4_
 __ZN3JSC10MathObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
 __ZN3JSC12SmallStrings24singleCharacterStringRepEh
-__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS2_16SymbolTableEntryENS2_17IdentifierRepHashENS_10HashTraitsIS5_EENS2_26SymbolTableIndexHashTraitsEE3addEPS4_RKS6_
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_16SymbolTableEntryEENS_18PairFirstExtractorIS8_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS5_EENS2_26SymbolTableIndexHashTraitsEEESE_E6rehashEi
-__ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_10JSValuePtrE
+__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS2_16SymbolTableEntryENS2_17IdentifierRepHashENS_10HashTraitsIS5_EENS2_26Symbo
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_16SymbolTableEntryEENS_18PairFirstExtractorIS8_EENS2_17Identif
+__ZN3JSC17PrototypeFunctionC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjec
+__ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_7JSValueE
 __ZN3JSC9Structure17copyPropertyTableEv
-__ZN3JSC14JSGlobalObject14setTimeoutTimeEj
 __ZN3JSC14JSGlobalObject10globalExecEv
 __ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
-__ZN3JSC4Heap4heapENS_10JSValuePtrE
-__ZN3JSC4Heap7protectENS_10JSValuePtrE
-__ZN3WTF7HashMapIPN3JSC6JSCellEjNS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS6_IjEEE3addERKS3_RKj
-__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi
+__ZN3JSC4Heap9unprotectENS_7JSValueE
 __ZN3JSC6JSCellnwEmPNS_9ExecStateE
-__ZN3JSC14JSGlobalObject17startTimeoutCheckEv
-__ZN3JSC11Interpreter17resetTimeoutCheckEv
-__ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_10JSValuePtrE
+__ZN3JSC14TimeoutChecker5resetEv
+__ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_7JSValueE
 __ZN3JSC6JSLock4lockEb
 __ZN3JSC6Parser5parseINS_11ProgramNodeEEEN3WTF10PassRefPtrIT_EEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
 __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
 __ZN3JSC7UStringaSEPKc
 __Z10jscyyparsePv
 __ZN3JSC5Lexer3lexEPvS1_
-__ZN3WTF6VectorItLm0EE15reserveCapacityEm
-__ZN3WTF6VectorItLm0EE6appendItEEvRKT_
 __ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKti
-__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addIPKcNS1_17CStringTranslatorEEESt4pairINS_24HashTableIteratorAdapterINS_9HashTableIS4_S4_NS_17IdentityExtractorIS4_EES6_S8_S8_EES4_EEbERKT_
+__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addINS1_11UCharBufferENS1_21UCharBufferTranslatorEE
+__ZN3WTF15SegmentedVectorINS_10IdentifierELm64EE6appendIS1_EEvRKT_
 __ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
-__ZN3WTF7HashSetIPN3JSC16ParserRefCountedENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
-__ZN3WTF9HashTableIPN3JSC16ParserRefCountedES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3JSC16ParserRefCountedC2EPNS_12JSGlobalDataE
-__ZN3JSC16ParserRefCounted3refEv
-__ZL20makeFunctionCallNodePvN3JSC8NodeInfoIPNS0_14ExpressionNodeEEENS1_IPNS0_13ArgumentsNodeEEEiii
-__ZNK3JSC15DotAccessorNode10isLocationEv
-__ZNK3JSC14ExpressionNode13isResolveNodeEv
-__ZNK3JSC14ExpressionNode21isBracketAccessorNodeEv
-__ZN3WTF7HashMapIPN3JSC16ParserRefCountedEjNS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS6_IjEEE3addERKS3_RKj
-__ZN3WTF9HashTableIPN3JSC16ParserRefCountedESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi
-__ZN3JSC14SourceElements6appendEN3WTF10PassRefPtrINS_13StatementNodeEEE
+__ZN3JSC20ParserArenaDeletablenwEmPNS_12JSGlobalDataE
+__ZN3WTF6VectorIPN3JSC20ParserArenaDeletableELm0EE15reserveCapacityEm
+__ZN3JSC5Lexer10sourceCodeEiii
+__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeE
+__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm
+__ZN3WTF6VectorIPN3JSC12FuncDeclNodeELm0EE14expandCapacityEm
+__ZN3JSC14SourceElements6appendEPNS_13StatementNodeE
 __ZNK3JSC13StatementNode16isEmptyStatementEv
-__ZN3JSC6Parser16didFinishParsingEPNS_14SourceElementsEPNS_20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEEEPNS3_INS5_INS4_6RefPtrINS_12FuncDeclNodeEEELm0EEEEEjii
+__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14expandCapacityEm
+__ZL20makeFunctionCallNodePvN3JSC8NodeInfoIPNS0_14ExpressionNodeEEENS1_IPNS0_13ArgumentsNodeEEEiii
+__ZNK3JSC11ResolveNode10isLocationEv
+__ZNK3JSC11ResolveNode13isResolveNodeEv
+__ZN3JSC5Lexer7record8Ei
+__ZN3JSC5Lexer10scanRegExpEv
+__ZN3JSC7UStringC2ERKN3WTF6VectorItLm0EEE
+__ZN3JSC7UString3Rep7destroyEv
 __ZN3JSC5Lexer5clearEv
+__ZN3JSC10Identifier6removeEPNS_7UString3RepE
 __ZN3WTF6VectorIN3JSC10IdentifierELm64EE14shrinkCapacityEm
-__ZN3WTF15deleteAllValuesIPN3JSC16ParserRefCountedEKNS_9HashTableIS3_S3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EESA_EEEEvRT0_
-__ZN3JSC15DotAccessorNodeD1Ev
-__ZN3JSC12NodeReleaser15releaseAllNodesEPNS_16ParserRefCountedE
-__ZN3JSC15DotAccessorNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC12NodeReleaser5adoptEN3WTF10PassRefPtrINS_16ParserRefCountedEEE
-__ZN3JSC16ParserRefCounted9hasOneRefEv
-__ZN3JSC16ParserRefCounted5derefEv
-__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS9_INS8_6RefPtrINS_12FuncDeclNodeEEELm0EEEji
-__ZN3WTF6VectorINS_6RefPtrIN3JSC13StatementNodeEEELm0EE14shrinkCapacityEm
-__ZN3JSC14SourceElementsD1Ev
+__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPN
+__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14shrinkCapacityEm
+__ZN3JSC11ParserArena10removeLastEv
 __ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
-__ZN3JSC11Interpreter7executeEPNS_11ProgramNodeEPNS_9ExecStateEPNS_14ScopeChainNodeEPNS_8JSObjectEPNS_10JSValuePtrE
+__ZN3JSC11Interpreter7executeEPNS_11ProgramNodeEPNS_9ExecStateEPNS_14ScopeChainNodeEPNS_8JSObjectEPNS_7JSValueE
 __ZN3JSC11ProgramNode16generateBytecodeEPNS_14ScopeChainNodeE
-__ZN3JSC9CodeBlockC1EPNS_9ScopeNodeENS_8CodeTypeEN3WTF10PassRefPtrINS_14SourceProviderEEEj
+__ZN3JSC9CodeBlockC2EPNS_9ScopeNodeENS_8CodeTypeEN3WTF10PassRefPtrINS_14SourceProviderEEEj
 __ZN3WTF7HashSetIPN3JSC16ProgramCodeBlockENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
 __ZN3WTF9HashTableIPN3JSC16ProgramCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3JSC17BytecodeGeneratorC2EPNS_11ProgramNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISE_EENS_26SymbolTableIndexHashTraitsEEEPNS_16ProgramCodeBlockE
+__ZN3JSC17BytecodeGeneratorC2EPNS_11ProgramNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEEN
 __ZN3WTF6VectorIN3JSC11InstructionELm0EE14expandCapacityEm
 __ZN3JSC9Structure22toDictionaryTransitionEPS0_
+__ZN3JSC8JSObject12removeDirectERKNS_10IdentifierE
+__ZN3JSC9Structure31removePropertyWithoutTransitionERKNS_10IdentifierE
+__ZN3JSC9Structure6removeERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_12FuncDeclNodeE
+__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv
 __ZN3JSC17BytecodeGenerator11newRegisterEv
 __ZN3JSC9Structure24fromDictionaryTransitionEPS0_
 __ZN3JSC17BytecodeGenerator8generateEv
 __ZN3JSC11ProgramNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator13emitDebugHookENS_11DebugHookIDEii
-__ZN3JSC17BytecodeGenerator11addConstantENS_10JSValuePtrE
-__ZN3WTF9HashTableIPN3JSC23JSValueEncodedAsPointerESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS1_17BytecodeGenerator17JSValueHashTraitsENS_10HashTraitsIjEEEESC_E6expandEv
+__ZN3JSC17BytecodeGenerator11addConstantENS_7JSValueE
+__ZN3WTF9HashTableIPvSt4pairIS1_jENS_18PairFirstExtractorIS3_EENS_7PtrHashIS1_EENS_14PairHashTraitsIN3JSC17JSValueHashTraitsENS
 __ZN3WTF6VectorIN3JSC8RegisterELm0EE14expandCapacityEm
-__ZNK3JSC13StatementNode6isLoopEv
+__ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_
 __ZN3JSC17BytecodeGenerator8emitNodeEPNS_10RegisterIDEPNS_4NodeE
 __ZN3WTF6VectorIN3JSC8LineInfoELm0EE14expandCapacityEm
+__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17ExprStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC19FunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC11ResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator11registerForERKNS_10IdentifierE
-__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEm
-__ZN3JSC17BytecodeGenerator11emitGetByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14expandCapacityEm
-__ZN3JSC17BytecodeGenerator11addConstantERKNS_10IdentifierE
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_iENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS5_EENS2_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESD_E6expandEv
-__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm
 __ZN3JSC17BytecodeGenerator8emitCallENS_8OpcodeIDEPNS_10RegisterIDES3_S3_PNS_13ArgumentsNodeEjjj
+__ZN3JSC16ArgumentListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE
+__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEm
 __ZN3WTF6VectorIN3JSC12CallLinkInfoELm0EE14expandCapacityEm
+__ZN3JSC11ResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC12JSGlobalData22numericCompareFunctionEPNS_9ExecStateE
+__ZNK3JSC21UStringSourceProvider6lengthEv
+__ZNK3JSC21UStringSourceProvider4dataEv
+__ZN3JSC19extractFunctionBodyEPNS_11ProgramNodeE
+__ZNK3JSC17ExprStatementNode15isExprStatementEv
+__ZNK3JSC12FuncExprNode14isFuncExprNodeEv
+__ZN3JSC16FunctionBodyNode16generateBytecodeEPNS_14ScopeChainNodeE
+__ZN3JSC6Parser14reparseInPlaceEPNS_12JSGlobalDataEPNS_16FunctionBodyNodeE
+__ZL11makeSubNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC14ExpressionNode14stripUnaryPlusEv
+__ZNK3JSC14ExpressionNode8isNumberEv
+__ZN3JSC9CodeBlockC1EPNS_9ScopeNodeENS_8CodeTypeEN3WTF10PassRefPtrINS_14SourceProviderEEEj
+__ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3Re
+__ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierE
+__ZN3JSC16FunctionBodyNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC10ReturnNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC11ResolveNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC17BytecodeGenerator12newTemporaryEv
+__ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE
+__ZN3JSC17BytecodeGenerator10emitReturnEPNS_10RegisterIDE
+__ZNK3JSC9BlockNode7isBlockEv
+__ZNK3JSC10ReturnNode12isReturnNodeEv
 __ZN3JSC9CodeBlock11shrinkToFitEv
 __ZN3WTF6VectorIN3JSC11InstructionELm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorIN3JSC17GlobalResolveInfoELm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIPN3JSC12CallLinkInfoELm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIN3JSC10IdentifierELm0EE14shrinkCapacityEm
-__ZN3JSC17ExprStatementNodeD1Ev
-__ZN3JSC19FunctionCallDotNodeD1Ev
-__ZN3JSC19FunctionCallDotNode12releaseNodesERNS_12NodeReleaserE
-__ZN3WTF6VectorINS_6RefPtrIN3JSC16ParserRefCountedEEELm0EE14expandCapacityEm
-__ZN3JSC16ParserRefCounted12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13ArgumentsNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11ResolveNodeD1Ev
-__ZN3JSC13ArgumentsNodeD1Ev
+__ZN3JSC11ParserArenaD1Ev
+__ZN3JSC11ResolveNodeD0Ev
+__ZN3JSC7SubNodeD0Ev
+__ZN3JSC10ReturnNodeD0Ev
+__ZN3JSC14SourceElementsD0Ev
+__ZN3JSC9BlockNodeD0Ev
+__ZN3JSC17BytecodeGeneratorD2Ev
+__ZN3WTF6VectorIN3JSC11InstructionELm0EEaSERKS3_
+__ZThn16_N3JSC11ProgramNodeD0Ev
+__ZN3JSC11ProgramNodeD0Ev
+__ZN3JSC13ParameterNodeD0Ev
+__ZN3JSC17ExprStatementNodeD0Ev
+__ZThn16_N3JSC12FuncExprNodeD0Ev
+__ZN3JSC12FuncExprNodeD0Ev
+__ZThn16_N3JSC16FunctionBodyNodeD0Ev
+__ZN3JSC16FunctionBodyNodeD0Ev
+__ZN3JSC9CodeBlockD1Ev
+__ZN3JSC9CodeBlockD2Ev
+__ZN3JSC21UStringSourceProviderD0Ev
+__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14shrinkCapacityEm
+__ZN3JSC15ParserArenaDataIN3WTF6VectorIPNS_12FuncDeclNodeELm0EEEED0Ev
+__ZN3JSC16ArgumentListNodeD0Ev
+__ZN3JSC13ArgumentsNodeD0Ev
+__ZN3JSC23FunctionCallResolveNodeD0Ev
 __ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12RegisterFileE
 __ZN3JSC3JIT14privateCompileEv
 __ZN3JSC3JIT22privateCompileMainPassEv
-__ZN3JSC3JIT21compileGetByIdHotPathEiiPNS_10IdentifierEj
-__ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEm
-__ZN3JSC3JIT13compileOpCallENS_8OpcodeIDEPNS_11InstructionEj
+__ZN3JSC3JIT13emit_op_enterEPNS_11InstructionE
+__ZN3JSC3JIT16emit_op_new_funcEPNS_11InstructionE
+__ZN3JSC20MacroAssemblerX86_648storePtrENS_22AbstractMacroAssemblerINS_12X86AssemblerEE6ImmPtrENS3_15ImplicitAddressE
+__ZN3JSC11JITStubCall4callEj
 __ZN3WTF6VectorIN3JSC10CallRecordELm0EE14expandCapacityEm
-__ZN3JSC3JIT22privateCompileLinkPassEv
+__ZN3JSC3JIT11emit_op_movEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_new_func_expEPNS_11InstructionE
+__ZN3JSC3JIT12emit_op_callEPNS_11InstructionE
+__ZN3JSC3JIT13compileOpCallENS_8OpcodeIDEPNS_11InstructionEj
+__ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEm
+__ZN3JSC3JIT11emit_op_endEPNS_11InstructionE
+__ZN3JSC11JITStubCall4callEv
+__ZN3WTF6VectorIN3JSC9JumpTableELm0EE14shrinkCapacityEm
 __ZN3JSC3JIT23privateCompileSlowCasesEv
-__ZN3JSC3JIT22compileGetByIdSlowCaseEiiPNS_10IdentifierERPNS_13SlowCaseEntryEj
+__ZN3JSC3JIT16emitSlow_op_callEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSC3JIT21compileOpCallSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryEjNS_8OpcodeIDE
 __ZN3JSC3JIT22compileOpCallSetupArgsEPNS_11InstructionE
-__ZN3JSC12X86Assembler3jneEv
-__ZN3WTF6VectorIN3JSC10CallRecordELm0EE6appendIS2_EEvRKT_
 __ZN3JSC9CodeBlock10setJITCodeERNS_10JITCodeRefE
 __ZN3JSC17BytecodeGenerator18dumpsGeneratedCodeEv
 __ZN3WTF10RefCountedIN3JSC14ExecutablePoolEE5derefEv
-ctiTrampoline
-__ZN3JSC11Interpreter16cti_op_get_by_idEPvz
-__ZNK3JSC10JSValuePtr3getEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC10MathObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_10JSValuePtrES2_PNS_8JSObjectES6_RKNS_7ArgListEE
-__ZN3JSC27ctiPatchCallByReturnAddressEPvS0_
-__ZN3JSC11Interpreter25cti_op_call_NotJSFunctionEPvz
-__ZN3JSC17PrototypeFunction11getCallDataERNS_8CallDataE
-__ZN3JSCL19mathProtoFuncRandomEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3WTF12randomNumberEv
-__ZN3JSC11ProgramNodeD1Ev
-__ZN3WTF9HashTableIPN3JSC16ProgramCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
-__ZN3JSC9CodeBlockD2Ev
-__ZN3JSC17StructureStubInfo5derefEv
-__ZN3JSC9ScopeNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC14JSGlobalObject16stopTimeoutCheckEv
-__ZN3JSC4Heap9unprotectENS_10JSValuePtrE
-__ZNK3JSC12JSNumberCell8toStringEPNS_9ExecStateE
-__ZN3JSC7UString4fromEd
-__ZN3WTF4dtoaEdiPiS0_PPc
-__ZN3WTFL3d2bEdPiS0_
-__ZN3WTFL8pow5multEPNS_6BigintEi
-__ZN3WTFL4multEPNS_6BigintES1_
-__ZN3WTFL6lshiftEPNS_6BigintEi
-__ZN3WTFL6quoremEPNS_6BigintES1_
-__ZN3WTFL4diffEPNS_6BigintES1_
-__ZN3JSC7UString3Rep7destroyEv
--[WTFMainThreadCaller call]
-__ZN3WTF31dispatchFunctionsFromMainThreadEv
-__ZN3JSC4Heap7collectEv
-__ZN3JSC4Heap30markStackObjectsConservativelyEv
-__ZN3JSC4Heap31markCurrentThreadConservativelyEv
-__ZN3JSC4Heap39markCurrentThreadConservativelyInternalEv
-__ZN3JSC4Heap18markConservativelyEPvS1_
-__ZN3JSC4Heap20markProtectedObjectsEv
-__ZN3JSC12SmallStrings4markEv
-__ZN3JSC6JSCell4markEv
-__ZN3JSC4Heap5sweepILNS_8HeapTypeE0EEEmv
-__ZN3JSC14JSGlobalObjectD2Ev
-__ZN3JSC17FunctionPrototypeD0Ev
-__ZN3JSC17PrototypeFunctionD0Ev
-__ZN3JSC16BooleanPrototypeD0Ev
-__ZN3JSC15NumberPrototypeD0Ev
-__ZN3JSC14ErrorPrototypeD0Ev
-__ZN3JSC17ObjectConstructorD0Ev
-__ZN3JSC16ArrayConstructorD0Ev
-__ZN3JSC17StringConstructorD0Ev
-__ZN3JSC18BooleanConstructorD0Ev
-__ZN3JSC17NumberConstructorD0Ev
-__ZN3JSC17RegExpConstructorD0Ev
-__ZN3JSC16ErrorConstructorD0Ev
-__ZN3JSC22NativeErrorConstructorD0Ev
-__ZN3JSC18GlobalEvalFunctionD0Ev
-__ZN3JSC4Heap5sweepILNS_8HeapTypeE1EEEmv
-__ZN3WTF25TCMalloc_Central_FreeList11ShrinkCacheEib
-__ZN3WTF14FastMallocZone9forceLockEP14_malloc_zone_t
-__ZN3WTF14FastMallocZone11forceUnlockEP14_malloc_zone_t
-__ZN3JSC7UStringC1EPKti
-__ZN3JSC5Lexer7record8Ei
-__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeE
-__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EE15reserveCapacityEm
-__ZN3JSC10Identifier6removeEPNS_7UString3RepE
-__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EEaSERKS5_
-__ZN3JSC8JSObject12removeDirectERKNS_10IdentifierE
-__ZN3JSC9Structure31removePropertyWithoutTransitionERKNS_10IdentifierE
-__ZN3JSC9Structure6removeERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_12FuncDeclNodeE
-__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv
-__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14shrinkCapacityEm
-__ZN3JSC3JIT11emitCTICallEPFvPvzE
-__ZN3JSC11Interpreter15cti_op_new_funcEPvz
+_ctiTrampoline
+__ZN3JSC8JITStubs15cti_op_new_funcEPPv
 __ZN3JSC12FuncDeclNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZN3JSC11Interpreter10cti_op_endEPvz
-__ZN3JSC12FuncDeclNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC12NodeReleaser21adoptFunctionBodyNodeERN3WTF6RefPtrINS_16FunctionBodyNodeEEE
-__ZN3JSC8JSObject4markEv
-__ZN3JSC14JSGlobalObject4markEv
-__ZN3JSC7JSArray4markEv
-__ZN3JSC15JSWrapperObject4markEv
-__ZN3JSC18GlobalEvalFunction4markEv
-__ZNK3JSC10NumberNode8isNumberEv
-__ZN3JSC5Lexer10scanRegExpEv
-__ZN3JSC7UStringC2ERKN3WTF6VectorItLm0EEE
-__ZL26appendToVarDeclarationListPvRPN3JSC20ParserRefCountedDataIN3WTF6VectorISt4pairINS0_10IdentifierEjELm0EEEEERKS5_j
-__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EE14expandCapacityEmPKS4_
-__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EE15reserveCapacityEm
-__ZL20makeVarStatementNodePvPN3JSC14ExpressionNodeE
-__ZL14makeAssignNodePvPN3JSC14ExpressionNodeENS0_8OperatorES2_bbiii
-__Z21mergeDeclarationListsIPN3JSC20ParserRefCountedDataIN3WTF6VectorINS2_6RefPtrINS0_12FuncDeclNodeEEELm0EEEEEET_SA_SA_
-__ZN3JSC20ParserRefCountedDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEED1Ev
-__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEm
-__ZNK3JSC18EmptyStatementNode16isEmptyStatementEv
-__ZNK3JSC14ExpressionNode10isLocationEv
-__ZL11makeAddNodePvPN3JSC14ExpressionNodeES2_b
-__ZNK3JSC14ExpressionNode8isNumberEv
-__ZN3JSC16PropertyListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator11emitPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_
-__ZN3JSC11UnaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC13LogicalOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8JITStubs19cti_op_new_func_expEPPv
+__ZN3JSC12FuncExprNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZN3JSC8JITStubs22cti_op_call_JSFunctionEPPv
+__ZN3JSC16FunctionBodyNode15generateJITCodeEPNS_14ScopeChainNodeE
+__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator8newLabelEv
+__ZN3JSC15DotAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11emitResolveEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator18findScopedPropertyERKNS_10IdentifierERiRmbRPNS_8JSObjectE
+__ZNK3JSC16JSVariableObject16isVariableObjectEv
+__ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_7JSValueE
+__ZN3JSC17BytecodeGenerator11emitGetByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator11addConstantERKNS_10IdentifierE
+__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEEiNS2_17IdentifierRepHashENS_10HashTraitsIS5_EENS2_17BytecodeGenerator28Identifi
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_iENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHa
 __ZN3JSC17BytecodeGenerator15emitJumpIfFalseEPNS_10RegisterIDEPNS_5LabelE
-__ZNK3JSC14LogicalNotNode8opcodeIDEv
+__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
+__ZN3JSC17BytecodeGenerator19emitResolveFunctionEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3JSC10StringNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3WTF9HashTableIPN3JSC7UString3RepESt4pairIS4_PNS1_8JSStringEENS_18PairFirstExtractorIS8_EENS1_17IdentifierRepHashENS_14Pair
+__ZN3JSC11BooleanNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8emitJumpEPNS_5LabelE
 __ZN3JSC17BytecodeGenerator9emitLabelEPNS_5LabelE
 __ZN3WTF6VectorIjLm0EE15reserveCapacityEm
-__ZN3JSC19ReverseBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC10NumberNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC17BytecodeGenerator11emitResolveEPNS_10RegisterIDERKNS_10IdentifierE
-__ZN3WTF6VectorIN3JSC17GlobalResolveInfoELm0EE14expandCapacityEm
-__ZNK3JSC11GreaterNode8opcodeIDEv
-__ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE
-__ZN3JSC9EqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC14ExpressionNode6isNullEv
-__ZN3JSC17BytecodeGenerator14emitEqualityOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_
+__ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC13StatementNode12isReturnNodeEv
+__ZN3JSC15DotAccessorNodeD0Ev
+__ZN3JSC10StringNodeD0Ev
+__ZN3JSC11BooleanNodeD0Ev
+__ZN3JSC6IfNodeD0Ev
+__ZN3JSC10IfElseNodeD0Ev
+__ZN3JSC3JIT22emit_op_get_global_varEPNS_11InstructionE
+__ZN3JSC3JIT29emitGetVariableObjectRegisterENS_3X8610RegisterIDEiS2_
+__ZN3JSC3JIT17emit_op_get_by_idEPNS_11InstructionE
+__ZN3JSC3JIT21compileGetByIdHotPathEiiPNS_10IdentifierEj
+__ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEmPKS2_
+__ZN3JSC3JIT14emit_op_jfalseEPNS_11InstructionE
+__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common9ConditionENS_3X8610RegisterIDENS_22AbstractMacroAssembler
+__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common9ConditionENS_3X8610RegisterIDES4_
+__ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEmPKS2_
+__ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEm
+__ZN3JSC3JIT20emit_op_resolve_funcEPNS_11InstructionE
+__ZN3JSC3JIT11emit_op_jmpEPNS_11InstructionE
+__ZN3JSC3JIT11emit_op_retEPNS_11InstructionE
+__ZN3JSC3JIT21emitSlow_op_get_by_idEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT22compileGetByIdSlowCaseEiiPNS_10IdentifierERPNS_13SlowCaseEntryEj
+__ZN3JSC3JIT18emitSlow_op_jfalseEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC23MacroAssemblerX86Common12branchTest32ENS0_9ConditionENS_3X8610RegisterIDENS_22AbstractMacroAssemblerINS_12X86Assemble
+__ZN3JSC8JITStubs23cti_vm_dontLazyLinkCallEPPv
+__ZN3JSC31ctiPatchNearCallByReturnAddressENS_22AbstractMacroAssemblerINS_12X86AssemblerEE22ProcessorReturnAddressEPv
+__ZN3JSC8JITStubs23cti_register_file_checkEPPv
+__ZN3JSC8JITStubs16cti_op_get_by_idEPPv
+__ZNK3JSC7JSValue3getEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC27ctiPatchCallByReturnAddressENS_22AbstractMacroAssemblerINS_12X86AssemblerEE22ProcessorReturnAddressEPv
+__ZN3JSC8JITStubs12cti_op_jtrueEPPv
+__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
+__ZN3JSC8JITStubs19cti_op_resolve_funcEPPv
+__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
+__ZNK3JSC8JSString8toStringEPNS_9ExecStateE
+__ZN3JSC8JITStubs23cti_op_get_by_id_secondEPPv
+__ZN3JSC8JITStubs15tryCacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockEPvNS_7JSValueERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC3JIT26privateCompileGetByIdProtoEPNS_17StructureStubInfoEPNS_9StructureES4_mNS_22AbstractMacroAssemblerINS_12X86Assembl
+__ZN3JSC3JIT22compileGetDirectOffsetEPNS_8JSObjectENS_3X8610RegisterIDES4_m
+__ZN3JSC8JITStubs19cti_vm_lazyLinkCallEPPv
+__ZN3JSC3JIT8linkCallEPNS_10JSFunctionEPNS_9CodeBlockENS_7JITCodeEPNS_12CallLinkInfoEi
+__ZN3JSC8JITStubs10cti_op_endEPPv
+__ZThn16_N3JSC12FuncDeclNodeD0Ev
+__ZN3JSC12FuncDeclNodeD0Ev
+__ZN3WTF25TCMalloc_Central_FreeList11ShrinkCacheEib
+__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC10JSFunction11getCallDataERNS_8CallDataE
+__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
+__ZN3JSC11Interpreter7executeEPNS_16FunctionBodyNodeEPNS_9ExecStateEPNS_10JSFunctionEPNS_8JSObjectERKNS_7ArgListEPNS_14ScopeCha
+__ZNK3JSC15DotAccessorNode10isLocationEv
+__ZNK3JSC14ExpressionNode13isResolveNodeEv
+__ZNK3JSC14ExpressionNode21isBracketAccessorNodeEv
+__ZN3JSC19FunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC19FunctionCallDotNodeD0Ev
+__ZL26appendToVarDeclarationListPvRPN3JSC15ParserArenaDataIN3WTF6VectorISt4pairINS0_10IdentifierEjELm0EEEEERKS5_j
+__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EE14expandCapacityEm
+__ZL14makeAssignNodePvPN3JSC14ExpressionNodeENS0_8OperatorES2_bbiii
+__ZL11makeAddNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC16VarStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17AssignResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11UnaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC10RegExpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
-__ZN3JSC4WREC9Generator13compileRegExpEPNS_12JSGlobalDataERKNS_7UStringEPjPPKcRN3WTF6RefPtrINS_14ExecutablePoolEEEbb
-__ZN3JSC4WREC9Generator13generateEnterEv
-__ZN3JSC4WREC9Generator17generateSaveIndexEv
-__ZN3JSC4WREC6Parser16parseDisjunctionERNS_14MacroAssembler8JumpListE
-__ZN3JSC4WREC6Parser16parseAlternativeERNS_14MacroAssembler8JumpListE
-__ZN3JSC4WREC9Generator32generatePatternCharacterSequenceERNS_14MacroAssembler8JumpListEPim
-__ZN3JSC4WREC9Generator28generatePatternCharacterPairERNS_14MacroAssembler8JumpListEii
-__ZN3WTF6VectorIN3JSC14MacroAssembler4JumpELm16EE6appendIS3_EEvRKT_
-__ZN3JSC12X86Assembler7cmpl_irEiNS_3X8610RegisterIDE
-__ZN3JSC4WREC9Generator24generatePatternCharacterERNS_14MacroAssembler8JumpListEi
-__ZN3JSC4WREC9Generator21generateLoadCharacterERNS_14MacroAssembler8JumpListE
-__ZN3JSC4WREC14CharacterClass7newlineEv
-__ZN3JSC4WREC6Parser29parseCharacterClassQuantifierERNS_14MacroAssembler8JumpListERKNS0_14CharacterClassEb
-__ZN3JSC4WREC6Parser17consumeQuantifierEv
-__ZN3JSC4WREC9Generator24generateGreedyQuantifierERNS_14MacroAssembler8JumpListERNS0_19GenerateAtomFunctorEjj
-__ZN3JSC4WREC29GenerateCharacterClassFunctor12generateAtomEPNS0_9GeneratorERNS_14MacroAssembler8JumpListE
-__ZN3JSC4WREC9Generator22generateCharacterClassERNS_14MacroAssembler8JumpListERKNS0_14CharacterClassEb
-__ZN3JSC4WREC9Generator30generateCharacterClassInvertedERNS_14MacroAssembler8JumpListERKNS0_14CharacterClassE
-__ZN3JSC4WREC29GenerateCharacterClassFunctor9backtrackEPNS0_9GeneratorE
-__ZN3JSC4WREC9Generator18generateBacktrack1Ev
-__ZN3JSC15AssemblerBuffer4growEv
+__ZN3JSC4Yarr15jitCompileRegexEPNS_12JSGlobalDataERNS0_14RegexCodeBlockERKNS_7UStringERjRPKcbb
+__ZN3JSC4Yarr12compileRegexERKNS_7UStringERNS0_12RegexPatternE
+__ZN3JSC4Yarr18PatternDisjunction17addNewAlternativeEv
+__ZN3WTF6VectorIPN3JSC4Yarr18PatternAlternativeELm0EE14expandCapacityEm
+__ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE11parseTokensEv
+__ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEmPKS3_
+__ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEm
+__ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE11parseEscapeILb0ES2_EEbRT0_
+__ZN3JSC4Yarr23RegexPatternConstructor25atomBuiltInCharacterClassENS0_23BuiltInCharacterClassIDEb
+__ZN3JSC4Yarr14wordcharCreateEv
+__ZN3WTF6VectorItLm0EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEmPKS3_
+__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEm
+__ZN3WTF6VectorIPN3JSC4Yarr14CharacterClassELm0EE14expandCapacityEmPKS4_
+__ZN3WTF6VectorIPN3JSC4Yarr14CharacterClassELm0EE14expandCapacityEm
+__ZN3JSC4Yarr14RegexGenerator19generateDisjunctionEPNS0_18PatternDisjunctionE
 __ZN3JSC12X86Assembler7addl_irEiNS_3X8610RegisterIDE
-__ZN3JSC4WREC9Generator21generateReturnSuccessEv
-__ZN3JSC4WREC9Generator22generateIncrementIndexEPNS_14MacroAssembler4JumpE
-__ZN3JSC4WREC9Generator27generateJumpIfNotEndOfInputENS_14MacroAssembler5LabelE
-__ZN3JSC4WREC9Generator21generateReturnFailureEv
+__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_9ConditionENS_3X8610RegisterIDES3_
+__ZN3JSC22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpList6appendENS2_4JumpE
+__ZN3JSC4Yarr14RegexGenerator12generateTermERNS1_19TermGenerationStateE
+__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_9ConditionENS_3X8610RegisterIDENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5I
+__ZN3JSC4Yarr14RegexGenerator19TermGenerationState15jumpToBacktrackENS_22AbstractMacroAssemblerINS_12X86AssemblerEE4JumpEPNS_14
+__ZN3JSC4Yarr14RegexGenerator13readCharacterEiNS_3X8610RegisterIDE
+__ZN3JSC4Yarr14RegexGenerator19matchCharacterClassENS_3X8610RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpLis
+__ZN3JSC4Yarr14RegexGenerator24matchCharacterClassRangeENS_3X8610RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8Ju
+__ZN3JSC22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpList4linkEPS2_
+__ZN3JSC23MacroAssemblerX86Common4jumpEv
+__ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EED1Ev
+__ZN3JSC4Yarr14RegexGenerator28generateCharacterClassGreedyERNS1_19TermGenerationStateE
+__ZN3JSC12X86Assembler7subl_irEiNS_3X8610RegisterIDE
+__ZN3JSC15AssemblerBuffer4growEv
+__ZN3WTF15deleteAllValuesIPN3JSC4Yarr14CharacterClassELm0EEEvRKNS_6VectorIT_XT0_EEE
 __ZN3JSC17BytecodeGenerator13emitNewRegExpEPNS_10RegisterIDEPNS_6RegExpE
-__ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC18NotStrictEqualNode8opcodeIDEv
-__ZNK3JSC14ExpressionNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC4WREC9Generator20generateAssertionBOLERNS_14MacroAssembler8JumpListE
-__ZN3JSC4WREC6Parser13consumeEscapeEb
-__ZN3WTF6VectorIiLm8EE14expandCapacityEm
-__ZN3JSC4WREC6Parser16parseParenthesesERNS_14MacroAssembler8JumpListE
-__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
-__ZL30calculateCompiledPatternLengthPKti24JSRegExpIgnoreCaseOptionR11CompileDataR9ErrorCode
-__ZL11checkEscapePPKtS0_P9ErrorCodeib
-__ZL13compileBranchiPiPPhPPKtS3_P9ErrorCodeS_S_R11CompileData
-__ZN3JSC4WREC14CharacterClass6spacesEv
-__ZN3JSC4WREC6Parser23parseNonCharacterEscapeERNS_14MacroAssembler8JumpListERKNS0_6EscapeE
-__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDE
-__ZN3JSC4WREC9Generator35generateCharacterClassInvertedRangeERNS_14MacroAssembler8JumpListES4_PKNS0_14CharacterRangeEjPjPKtj
-__ZN3JSC4WREC9Generator20terminateAlternativeERNS_14MacroAssembler8JumpListES4_
-__ZN3JSC4WREC6Parser19parseCharacterClassERNS_14MacroAssembler8JumpListE
-__ZN3JSC4WREC14CharacterClass8wordcharEv
-__ZN3JSC4WREC25CharacterClassConstructor6appendERKNS0_14CharacterClassE
-__ZN3JSC4WREC25CharacterClassConstructor5flushEv
-__ZN3JSC4WREC25CharacterClassConstructor9addSortedERN3WTF6VectorItLm0EEEt
-__ZN3WTF6VectorItLm0EE14expandCapacityEm
-__ZN3JSC4WREC25CharacterClassConstructor14addSortedRangeERN3WTF6VectorINS0_14CharacterRangeELm0EEEtt
-__ZN3WTF6VectorIN3JSC4WREC14CharacterRangeELm0EE14expandCapacityEm
-__ZN3JSC4WREC25CharacterClassConstructor3putEt
-__ZN3JSC4WREC9Generator20terminateDisjunctionERNS_14MacroAssembler8JumpListE
-__ZN3JSC11NewExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13emitConstructEPNS_10RegisterIDES2_PNS_13ArgumentsNodeEjjj
-__ZN3WTF6VectorIN3JSC20GetByIdExceptionInfoELm0EE14expandCapacityEm
-__ZN3JSC16VarStatementNodeD1Ev
-__ZN3JSC16VarStatementNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC17AssignResolveNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC17ObjectLiteralNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC16PropertyListNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC12PropertyNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11UnaryOpNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13LogicalOpNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC12BinaryOpNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC17AssignResolveNodeD1Ev
-__ZN3JSC17ObjectLiteralNodeD1Ev
-__ZN3JSC16PropertyListNodeD1Ev
-__ZN3JSC12PropertyNodeD1Ev
-__ZN3JSC14LogicalNotNodeD1Ev
-__ZN3JSC10RegExpNodeD1Ev
-__ZN3JSC13LogicalOpNodeD1Ev
-__ZN3JSC9EqualNodeD1Ev
-__ZN3JSC18NotStrictEqualNodeD1Ev
-__ZN3JSC6IfNodeD1Ev
-__ZN3JSC6IfNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13AssignDotNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC8WithNodeD1Ev
-__ZN3JSC8WithNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC21FunctionCallValueNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC21FunctionCallValueNodeD1Ev
-__ZN3JSC9ArrayNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC9ArrayNodeD1Ev
-__ZN3JSC11ElementNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC10IfElseNodeD1Ev
-__ZN3JSC10IfElseNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC7AddNodeD1Ev
-__ZN3JSC11NewExprNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11NewExprNodeD1Ev
+__ZN3JSC15ConditionalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9EqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14ExpressionNode6isNullEv
+__ZNK3JSC10StringNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC19BracketAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC10NumberNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC10NumberNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEd
+__ZN3JSC17BytecodeGenerator12emitGetByValEPNS_10RegisterIDES2_S2_
+__ZN3JSC17BytecodeGenerator14emitEqualityOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_
+__ZN3JSC19ReverseBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14ExpressionNode5isAddEv
+__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
+__ZN3JSC13AssignDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11emitPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC17AssignResolveNodeD0Ev
+__ZN3JSC15ParserArenaDataIN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEED0Ev
+__ZN3JSC16VarStatementNodeD0Ev
+__ZN3JSC14LogicalNotNodeD0Ev
+__ZN3JSC10RegExpNodeD0Ev
+__ZN3JSC10NumberNodeD0Ev
+__ZN3JSC19BracketAccessorNodeD0Ev
+__ZN3JSC9EqualNodeD0Ev
+__ZN3JSC15ConditionalNodeD0Ev
+__ZN3JSC7AddNodeD0Ev
+__ZN3JSC13GreaterEqNodeD0Ev
+__ZN3JSC13AssignDotNodeD0Ev
+__ZN3JSC3JIT13emit_op_jtrueEPNS_11InstructionE
+__ZN3JSC3JIT18emit_op_new_regexpEPNS_11InstructionE
+__ZN3JSC3JIT18emit_op_get_by_valEPNS_11InstructionE
+__ZN3JSC3JIT10emit_op_eqEPNS_11InstructionE
+__ZN3JSC3JIT11emit_op_addEPNS_11InstructionE
+__ZN3JSC11JITStubCall11addArgumentEjNS_3X8610RegisterIDE
+__ZN3JSC3JIT16emit_op_jnlesseqEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_put_by_idEPNS_11InstructionE
 __ZN3JSC3JIT21compilePutByIdHotPathEiPNS_10IdentifierEij
-__ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEm
-__ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE6appendIS2_EEvRKT_
-__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDES4_ii
-__ZN3JSC3JIT11emitCTICallEPFPNS_23JSValueEncodedAsPointerEPvzE
-__ZN3JSC3JIT17compileOpStrictEqEPNS_11InstructionENS0_21CompileOpStrictEqTypeE
-__ZN3JSC3JIT23compileFastArith_op_addEPNS_11InstructionE
+__ZN3JSC3JIT17emitSlow_op_jtrueEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT22emitSlow_op_get_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT14emitSlow_op_eqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT20emitSlow_op_jnlesseqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC20MacroAssemblerX86_6413branchTestPtrENS_23MacroAssemblerX86Common9ConditionENS_3X8610RegisterIDES4_
+__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_3X8610RegisterIDE
+__ZN3JSC23MacroAssemblerX86Common12branchDoubleENS0_15DoubleConditionENS_3X8613XMMRegisterIDES3_
+__ZN3JSC3JIT21emitSlow_op_put_by_idEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSC3JIT22compilePutByIdSlowCaseEiPNS_10IdentifierEiRPNS_13SlowCaseEntryEj
-__ZN3JSC3JIT27compileOpConstructSetupArgsEPNS_11InstructionE
-__ZN3JSC3JIT11emitCTICallEPFPNS_8JSObjectEPvzE
-__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
-__ZN3JSC11Interpreter17cti_op_new_objectEPvz
-__ZN3JSC20constructEmptyObjectEPNS_9ExecStateE
-__ZN3JSC11Interpreter16cti_op_put_by_idEPvz
-__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC11Interpreter12cti_op_jtrueEPvz
-__ZN3JSC11Interpreter10cti_op_notEPvz
-__ZN3WTF7HashMapISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjEPNS3_9StructureENS3_28StructureTransitionTableHashENS3_34StructureTransitionTableHashTraitsENS_10HashTraitsIS9_EEE3addERKS7_RKS9_
-__ZN3WTF9HashTableISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjES1_IS7_PNS3_9StructureEENS_18PairFirstExtractorISA_EENS3_28StructureTransitionTableHashENS_14PairHashTraitsINS3_34StructureTransitionTableHashTraitsENS_10HashTraitsIS9_EEEESF_E6rehashEi
-__ZN3JSC11Interpreter21cti_op_resolve_globalEPvz
+__ZN3JSC13LogicalOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3WTF6VectorIN3JSC17GlobalResolveInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator14emitJumpIfTrueEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC13LogicalOpNodeD0Ev
+__ZN3JSC3JIT22emit_op_resolve_globalEPNS_11InstructionE
+__ZN3JSC8JITStubs21cti_op_resolve_globalEPPv
+__ZNK3JSC8JSString9toBooleanEPNS_9ExecStateE
 __ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC15StringPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL22stringProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZNK3JSC8JSString12toThisStringEPNS_9ExecStateE
-__ZNK3JSC10JSValuePtr9toIntegerEPNS_9ExecStateE
-__ZN3JSC11JSImmediate12nonInlineNaNEv
-__ZNK3JSC7UString4findERKS0_i
-__ZN3JSC11Interpreter11cti_op_lessEPvz
-__ZN3JSC11Interpreter17cti_op_new_regexpEPvz
-__ZN3JSC12RegExpObjectC1EN3WTF10PassRefPtrINS_9StructureEEENS2_INS_6RegExpEEE
-__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
 __ZNK3JSC6JSCell8isObjectEPKNS_9ClassInfoE
-__ZNK3JSC12RegExpObject9classInfoEv
+__ZNK3JSC6JSCell9classInfoEv
+__ZN3JSC4Yarr23RegexPatternConstructor20atomPatternCharacterEt
+__ZN3JSC4Yarr25CharacterClassConstructor7putCharEt
+__ZN3JSC4Yarr25CharacterClassConstructor9addSortedERN3WTF6VectorItLm0EEEt
+__ZN3JSC4Yarr23RegexPatternConstructor21atomCharacterClassEndEv
+__ZN3JSC4Yarr23RegexPatternConstructor23setupDisjunctionOffsetsEPNS0_18PatternDisjunctionEjj
+__ZN3JSC4Yarr14RegexGenerator25generateParenthesesSingleERNS1_19TermGenerationStateE
+__ZN3JSC4Yarr14RegexGenerator30generateParenthesesDisjunctionERNS0_11PatternTermERNS1_19TermGenerationStateEj
+__ZN3WTF6VectorIN3JSC4Yarr14RegexGenerator26AlternativeBacktrackRecordELm0EE14expandCapacityEm
+__ZN3JSC4Yarr14RegexGenerator19jumpIfCharNotEqualsEti
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDES4_ii
+__ZN3JSC4Yarr14RegexGenerator19TermGenerationState15jumpToBacktrackERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListEP
 __ZN3JSC17RegExpConstructor12performMatchEPNS_6RegExpERKNS_7UStringEiRiS6_PPi
 __ZN3JSC6RegExp5matchERKNS_7UStringEiPN3WTF11OwnArrayPtrIiEE
-__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
-__ZNK3JSC7UString8toUInt32EPbb
-__ZNK3JSC7UString8toDoubleEbb
-__ZN3WTF6VectorIcLm32EE6resizeEm
-__ZN3JSC11Interpreter16cti_op_nstricteqEPvz
-__ZN3JSC10JSValuePtr19strictEqualSlowCaseES0_S0_
-__ZN3JSC11Interpreter19cti_op_new_func_expEPvz
-__ZN3JSC12FuncExprNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZNK3JSC19BracketAccessorNode10isLocationEv
-__ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv
-__ZN3JSC9ForInNodeC2EPNS_12JSGlobalDataERKNS_10IdentifierEPNS_14ExpressionNodeES7_PNS_13StatementNodeEiii
-__ZN3JSC19BracketAccessorNodeD1Ev
-__ZN3JSC19BracketAccessorNode12releaseNodesERNS_12NodeReleaserE
-__ZNK3JSC9ForInNode6isLoopEv
-__ZN3JSC9ForInNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3JSC20EvalFunctionCallNodeD1Ev
-__ZN3JSC20EvalFunctionCallNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC3JIT26compileOpCallEvalSetupArgsEPNS_11InstructionE
-__ZN3JSC11Interpreter24cti_op_resolve_with_baseEPvz
-__ZN3JSC11Interpreter16cti_op_call_evalEPvz
-__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEiiRNS_10JSValuePtrE
-__ZNK3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS1_INS2_8EvalNodeEEENS_7StrHashIS5_EENS_10HashTraitsIS5_EENSA_IS7_EEE3getEPS4_
-__ZN3JSC7UString3Rep11computeHashEPKti
-__ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS1_INS2_8EvalNodeEEEENS_18PairFirstExtractorIS9_EENS_7StrHashIS5_EENS_14PairHashTraitsINS_10HashTraitsIS5_EENSF_IS8_EEEESG_E6rehashEi
-__ZN3JSC9ExecState9thisValueEv
-__ZN3JSC11Interpreter7executeEPNS_8EvalNodeEPNS_9ExecStateEPNS_8JSObjectEiPNS_14ScopeChainNodeEPNS_10JSValuePtrE
-__ZN3JSC8EvalNode16generateBytecodeEPNS_14ScopeChainNodeE
-__ZN3JSC17BytecodeGeneratorC2EPNS_8EvalNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISE_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE
-__ZN3JSC8EvalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC18globalFuncParseIntEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL24dateProtoFuncToGMTStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC10formatTimeERKNS_17GregorianDateTimeEb
-__ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE
-__ZN3JSC9BreakNodeD1Ev
-__ZN3JSC8JSString18getPrimitiveNumberEPNS_9ExecStateERdRNS_10JSValuePtrE
-__ZNK3JSC8JSString8toNumberEPNS_9ExecStateE
-__ZL18makeRightShiftNodePvPN3JSC14ExpressionNodeES2_b
-__ZN3JSC4WREC14CharacterClass6digitsEv
-__ZNK3JSC14RightShiftNode8opcodeIDEv
-__ZN3JSC14RightShiftNodeD1Ev
-__ZN3JSC3JIT26compileFastArith_op_rshiftEjjj
-__ZN3JSC3JIT30compileFastArithSlow_op_rshiftEjjjRPNS_13SlowCaseEntryE
-__ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC21gregorianDateTimeToMSERKNS_17GregorianDateTimeEdb
-__ZN3JSCL15dateToDayInYearEiii
-__ZN3JSC8EvalNode4markEv
-__ZN3JSC19JSStaticScopeObjectD0Ev
-__ZN3JSC18PostfixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC18PostfixBracketNodeD1Ev
-__ZN3JSC18PostfixBracketNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC9ForInNodeC2EPNS_12JSGlobalDataEPNS_14ExpressionNodeES4_PNS_13StatementNodeE
-__ZN3JSC21ReadModifyBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC21ReadModifyBracketNodeD1Ev
-__ZN3JSC21ReadModifyBracketNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSCL20arrayProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC17RegExpConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL30constructWithRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC15constructRegExpEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC8JSObject9classNameEv
-__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL20stringProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC8NullNode6isNullEv
-__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callStringConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC12StringObject8toStringEPNS_9ExecStateE
-__ZN3JSCL23stringProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter28cti_op_get_by_id_string_failEPvz
-__ZN3JSCL19regExpProtoFuncExecEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter16cti_op_is_numberEPvz
-__ZNK3JSC12StringObject9classInfoEv
-__ZN3JSC11Interpreter16cti_op_is_objectEPvz
-__ZN3JSC3JIT30privateCompileGetByIdChainListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureEPNS_14StructureChainEmmPNS_9ExecStateE
-__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC10Identifier5equalEPKNS_7UString3RepEPKc
-__ZNK3JSC6JSCell17getTruncatedInt32ERi
-__ZN3JSC15toInt32SlowCaseEdRb
-__ZNK3JSC12JSNumberCell9toBooleanEPNS_9ExecStateE
-__ZN3JSC9Structure24removePropertyTransitionEPS0_RKNS_10IdentifierERm
-__ZN3JSC11Interpreter10cti_op_subEPvz
-__ZN3JSC28globalFuncEncodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL6encodeEPNS_9ExecStateERKNS_7ArgListEPKc
-__ZNK3JSC7UString10UTF8StringEb
-__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
+__ZN3JSC4Yarr12executeRegexERNS0_14RegexCodeBlockEPKtjjPii
+__ZN3JSC8JITStubs17cti_op_new_regexpEPPv
+__ZN3JSC12RegExpObjectC1EN3WTF10PassRefPtrINS_9StructureEEENS2_INS_6RegExpEEE
+__ZNK3JSC12RegExpObject9classInfoEv
+__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE
+__ZN3JSC8JITStubs17cti_op_get_by_valEPPv
+__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC18RegExpMatchesArray17fillArrayInstanceEPNS_9ExecStateE
+__ZN3JSC11jsSubstringEPNS_12JSGlobalDataERKNS_7UStringEjj
+__ZN3JSC7JSArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC8JITStubs9cti_op_eqEPPv
+__ZN3JSCeqERKNS_7UStringES2_
+__ZN3JSC8JITStubs10cti_op_addEPPv
+__ZN3JSC11concatenateEPNS_7UString3RepES2_
+__ZN3JSCL22stringProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7UString4findERKS0_i
+__ZN3JSC8JITStubs16cti_op_put_by_idEPPv
+__ZNK3JSC7UString8toUInt32EPbb
+__ZNK3JSC7UString8toDoubleEbb
+__ZNK3JSC7UString10getCStringERN3WTF6VectorIcLm32EEE
+__ZN3WTF14FastMallocZone11forceUnlockEP14_malloc_zone_t
+__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
+__ZL30calculateCompiledPatternLengthPKti24JSRegExpIgnoreCaseOptionR11CompileDataR9ErrorCode
+__ZL11checkEscapePPKtS0_P9ErrorCodeib
+__ZL13compileBranchiPiPPhPPKtS3_P9ErrorCodeS_S_R11CompileData
+__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
+__ZL5matchPKtPKhiR9MatchData
+__ZNK3JSC7UString14toStrictUInt32EPb
+__ZN3JSC17ObjectLiteralNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC16PropertyListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC7TryNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator9emitCatchEPNS_10RegisterIDEPNS_5LabelES4_
+__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator16emitPushNewScopeEPNS_10RegisterIDERNS_10IdentifierES2_
+__ZN3WTF6VectorIN3JSC18ControlFlowContextELm0EE14expandCapacityEm
+__ZNK3JSC14ExpressionNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC12PropertyNodeD0Ev
+__ZN3JSC16PropertyListNodeD0Ev
+__ZN3JSC17ObjectLiteralNodeD0Ev
+__ZN3JSC7TryNodeD0Ev
+__ZN3JSC3JIT18emit_op_new_objectEPNS_11InstructionE
+__ZN3JSC3JIT13emit_op_catchEPNS_11InstructionE
+__ZN3JSC3JIT22emit_op_push_new_scopeEPNS_11InstructionE
+__ZN3JSC3JIT15emit_op_resolveEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_pop_scopeEPNS_11InstructionE
+__ZN3JSC8JITStubs17cti_op_new_objectEPPv
+__ZN3JSC20constructEmptyObjectEPNS_9ExecStateE
+__ZN3JSC17StructureStubInfo5derefEv
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEES5_NS_17IdentityExtractorIS5_EENS2_17IdentifierRepHashENS_10HashTraitsIS5_EES
+__ZN3JSC8ThisNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC21ThrowableBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8ThisNodeD0Ev
+__ZN3JSC6InNodeD0Ev
+__ZN3JSC3JIT29emit_op_enter_with_activationEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_convert_thisEPNS_11InstructionE
+__ZN3JSC3JIT27emit_op_tear_off_activationEPNS_11InstructionE
+__ZN3JSC3JIT24emitSlow_op_convert_thisEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC8JITStubs22cti_op_push_activationEPPv
+__ZN3JSC12JSActivationC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_16FunctionBodyNodeEEE
+__ZN3JSC12JSActivationC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_16FunctionBodyNodeEEE
+__ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE11parseEscapeILb1ENS3_28CharacterClassParserDelegateEEEbRT0_
+__ZN3JSC4Yarr12digitsCreateEv
+__ZN3JSC4Yarr25CharacterClassConstructor6appendEPKNS0_14CharacterClassE
+__ZN3JSC4Yarr25CharacterClassConstructor14addSortedRangeERN3WTF6VectorINS0_14CharacterRangeELm0EEEtt
+__ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE28CharacterClassParserDelegate20atomPatternCharacterEt
+__ZN3JSC11GreaterNodeD0Ev
+__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSString14toThisJSStringEPNS_9ExecStateE
+__ZN3JSC7UStringC2EPtib
+__ZN3JSC18globalFuncParseIntEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11JSImmediate12nonInlineNaNEv
+__ZN3JSC8JITStubs11cti_op_lessEPPv
+__ZN3JSC8JITStubs9cti_op_inEPPv
+__ZNK3JSC6JSCell9getUInt32ERj
+__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZL14makePrefixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
+__ZN3JSC7ForNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13newLabelScopeENS_10LabelScope4TypeEPKNS_10IdentifierE
+__ZN3JSC12ContinueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14continueTargetERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi
 __ZN3JSC17PrefixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC10NegateNode8opcodeIDEv
-__ZN3JSC10NegateNodeD1Ev
-__ZN3JSC11Interpreter13cti_op_negateEPvz
-__ZN3JSCL17mathProtoFuncSqrtEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11JSImmediate12toThisObjectENS_10JSValuePtrEPNS_9ExecStateE
-__ZN3JSCL16mathProtoFuncAbsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL18mathProtoFuncRoundEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL16mathProtoFuncCosEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL16mathProtoFuncSinEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter12cti_op_jlessEPvz
-__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
-__ZN3JSC16ArrayConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL20callArrayConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC12JSNumberCell18getPrimitiveNumberEPNS_9ExecStateERdRNS_10JSValuePtrE
-__ZN3JSC11Interpreter10cti_op_modEPvz
-__ZL17makeLeftShiftNodePvPN3JSC14ExpressionNodeES2_b
-__ZNK3JSC13LeftShiftNode8opcodeIDEv
-__ZN3JSC13LeftShiftNodeD1Ev
-__ZN3JSC3JIT26compileFastArith_op_lshiftEjjj
-__ZN3JSC3JIT30compileFastArithSlow_op_lshiftEjjjRPNS_13SlowCaseEntryE
-__ZN3JSCL16mathProtoFuncMaxEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC10BitAndNode8opcodeIDEv
-__ZN3JSC10BitAndNodeD1Ev
-__ZN3JSC3JIT26compileFastArith_op_bitandEjjj
-__ZN3JSC3JIT30compileFastArithSlow_op_bitandEjjjRPNS_13SlowCaseEntryE
-__ZN3JSC11Interpreter13cti_op_bitandEPvz
-__ZNK3JSC14BitwiseNotNode8opcodeIDEv
-__ZN3JSC14BitwiseNotNodeD1Ev
-__ZN3JSC11Interpreter13cti_op_lshiftEPvz
-__ZN3JSC11Interpreter13cti_op_bitnotEPvz
-__ZNK3JSC22UnsignedRightShiftNode8opcodeIDEv
-__ZNK3JSC10BitXOrNode8opcodeIDEv
-__ZN3JSC22UnsignedRightShiftNodeD1Ev
-__ZN3JSC10BitXOrNodeD1Ev
-__ZN3JSCL25stringProtoFuncCharCodeAtEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter14cti_op_urshiftEPvz
-__ZNK3JSC12JSNumberCell18getTruncatedUInt32ERj
-__ZN3JSC16toUInt32SlowCaseEdRb
-__ZN3JSCL17mathProtoFuncCeilEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC6JSCell18getTruncatedUInt32ERj
-__ZN3JSC11Interpreter12cti_op_bitorEPvz
-__ZNK3JSC12JSNumberCell17getTruncatedInt32ERi
-__ZNK3JSC9BitOrNode8opcodeIDEv
-__ZN3JSC9BitOrNodeD1Ev
-__ZN3JSC11Interpreter13cti_op_rshiftEPvz
-__ZN3JSC11Interpreter13cti_op_bitxorEPvz
-__ZN3JSC9parseDateERKNS_7UStringE
-__ZNK3JSC12JSActivation12toThisObjectEPNS_9ExecStateE
-__ZN3JSC11Interpreter19cti_op_resolve_skipEPvz
-__ZN3JSCL24dateProtoFuncGetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC17StringConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL30constructWithStringConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC5equalEPKNS_7UString3RepES3_
-__ZN3JSC10SwitchNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC13CaseBlockNode20emitBytecodeForBlockERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_
-__ZN3JSC13CaseBlockNode18tryOptimizedSwitchERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERiS7_
-__ZN3JSCL17processClauseListEPNS_14ClauseListNodeERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERNS_10SwitchKindERbRiSB_
-__ZNK3JSC10StringNode8isStringEv
-__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm8EE14expandCapacityEm
-__ZN3WTF6VectorINS_6RefPtrIN3JSC5LabelEEELm8EE14expandCapacityEm
-__ZN3JSC17BytecodeGenerator11beginSwitchEPNS_10RegisterIDENS_10SwitchInfo10SwitchTypeE
-__ZN3WTF6VectorIN3JSC10SwitchInfoELm0EE14expandCapacityEm
-__ZN3JSC17BytecodeGenerator9endSwitchEjPN3WTF6RefPtrINS_5LabelEEEPPNS_14ExpressionNodeEPS3_ii
-__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14expandCapacityEm
-__ZN3WTF6VectorIiLm0EE15reserveCapacityEm
-__ZN3JSC10SwitchNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13CaseBlockNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC14ClauseListNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC14CaseClauseNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC10SwitchNodeD1Ev
-__ZN3JSC13CaseBlockNodeD1Ev
-__ZN3JSC14ClauseListNodeD1Ev
-__ZN3JSC14CaseClauseNodeD1Ev
-__ZN3WTF6VectorIN3JSC12SwitchRecordELm0EE14expandCapacityEm
-__ZN3WTF6VectorIPvLm0EE15reserveCapacityEm
-__ZN3JSC11Interpreter18cti_op_switch_charEPvz
-__ZN3JSC8EvalNodeD1Ev
-__ZN3JSCL16mathProtoFuncPowEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3WTF6VectorIcLm0EE14expandCapacityEm
-__ZN3WTF6VectorIN3JSC7UString5RangeELm16EE14expandCapacityEm
-__ZN3WTF6VectorIN3JSC7UStringELm16EE14expandCapacityEm
-__ZN3WTF17TCMalloc_PageHeap3NewEm
-__ZN3JSC7JSArray16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZN3JSC9ExecState10arrayTableEPS0_
-__ZN3JSCL18regExpObjectSourceEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC7ArgList10slowAppendENS_10JSValuePtrE
-__ZN3WTF7HashSetIPN3JSC7ArgListENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
-__ZN3WTF9HashTableIPN3JSC7ArgListES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3WTF6VectorIN3JSC8RegisterELm8EE15reserveCapacityEm
-__ZN3JSC22JSPropertyNameIterator4markEv
-__ZN3JSCL16mathProtoFuncLogEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL29objectProtoFuncHasOwnPropertyEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL18arrayProtoFuncSortEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC7JSArray4sortEPNS_9ExecStateENS_10JSValuePtrENS_8CallTypeERKNS_8CallDataE
-__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE6insertEi
-__ZN3JSCltERKNS_7UStringES2_
-__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE7balanceEi
-__ZN3JSC4WREC9Generator29generateAssertionWordBoundaryERNS_14MacroAssembler8JumpListEb
-__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_3X8610RegisterIDES3_ii
-__ZN3JSCL21stringProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC19globalFuncEncodeURIEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC19globalFuncDecodeURIEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL6decodeEPNS_9ExecStateERKNS_7ArgListEPKcb
-__ZN3WTF7Unicode18UTF8SequenceLengthEc
-__ZN3WTF7Unicode18decodeUTF8SequenceEPKc
-__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZNK3JSC12JSNumberCell8toObjectEPNS_9ExecStateE
-__ZN3JSC15constructNumberEPNS_9ExecStateENS_10JSValuePtrE
-__ZN3JSCL22numberProtoFuncToFixedEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC12JSNumberCell11getJSNumberEv
-__ZN3JSCL16integerPartNoExpEd
-__ZN3JSC11Interpreter27cti_op_get_by_id_proto_failEPvz
-__ZN3WTF6VectorIPN3JSC10RegisterIDELm32EE14expandCapacityEm
-__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC7JSArray3popEv
-__ZNK3JSC11DoWhileNode6isLoopEv
-__ZN3JSC11DoWhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC11DoWhileNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11DoWhileNodeD1Ev
-__ZN3JSC11Interpreter17cti_op_switch_immEPvz
-__ZN3JSCL16mathProtoFuncMinEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC13UnaryPlusNode14stripUnaryPlusEv
-__ZN3JSC13UnaryPlusNodeD1Ev
-__ZN3JSCL21stringProtoFuncSubstrEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC15globalFuncIsNaNEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC17NumberConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callNumberConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter15cti_op_post_incEPvz
-__ZN3JSCL23stringProtoFuncFontsizeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL24dateProtoFuncSetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL23setNewValueFromDateArgsEPNS_9ExecStateENS_10JSValuePtrERKNS_7ArgListEib
-__ZN3JSCL24dateProtoFuncToUTCStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL19stringProtoFuncLinkEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL9dateParseEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter21cti_op_loop_if_lesseqEPvz
-__ZN3JSCL16mathProtoFuncExpEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringE
-__ZN3JSCL21dateProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC4WREC9Generator36generateParenthesesInvertedAssertionERNS_14MacroAssembler8JumpListE
-__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_10JSValuePtrE
-__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEPNS_9ExecStateEj
-__ZN3JSCL23regExpProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL18regExpObjectGlobalEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL22regExpObjectIgnoreCaseEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL21regExpObjectMultilineEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC11Interpreter17cti_op_is_booleanEPvz
-__ZNK3JSC12JSNumberCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
-__ZN3JSC4WREC14CharacterClass9nonspacesEv
-__ZN3JSC4Heap15recordExtraCostEm
-__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE15reserveCapacityEm
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_14OffsetLocationEENS_18PairFirstExtractorIS8_EENS_7StrHashIS5_EENS_14PairHashTraitsINS_10HashTraitsIS5_EENSE_IS7_EEEESF_EC2ERKSI_
-__ZN3JSC11Interpreter20cti_op_switch_stringEPvz
-__ZNK3JSC12JSNumberCell12toThisObjectEPNS_9ExecStateE
-__ZN3JSCL22numberProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC12NumberObject11getJSNumberEv
-__ZNK3JSC13UnaryPlusNode8opcodeIDEv
+__ZN3JSC21ReadModifyResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11NewExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13emitConstructEPNS_10RegisterIDES2_PNS_13ArgumentsNodeEjjj
+__ZN3WTF6VectorIN3JSC20GetByIdExceptionInfoELm0EE14expandCapacityEm
+__ZN3JSC8LessNodeD0Ev
+__ZN3JSC17PrefixResolveNodeD0Ev
+__ZN3JSC12ContinueNodeD0Ev
+__ZN3JSC7ForNodeD0Ev
+__ZN3JSC21ReadModifyResolveNodeD0Ev
+__ZN3JSC11NewExprNodeD0Ev
+__ZN3JSC3JIT11emit_op_notEPNS_11InstructionE
+__ZN3JSC3JIT15emit_op_pre_incEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_loop_if_lessEPNS_11InstructionE
+__ZN3JSC3JIT16emitTimeoutCheckEv
+__ZN3JSC3JIT20compileBinaryArithOpENS_8OpcodeIDEjjjNS_12OperandTypesE
+__ZN3JSC3JIT11emit_op_subEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_constructEPNS_11InstructionE
+__ZN3JSC3JIT24emit_op_construct_verifyEPNS_11InstructionE
+__ZN3JSC3JIT15emitSlow_op_notEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT19emitSlow_op_pre_incEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT24emitSlow_op_loop_if_lessEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT15emitSlow_op_addEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT28compileBinaryArithOpSlowCaseENS_8OpcodeIDERPNS_13SlowCaseEntryEjjjNS_12OperandTypesE
+__ZN3JSC15AssemblerBuffer7putByteEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter11twoByteOp64ENS0_15TwoByteOpcodeIDEiNS_3X8610RegisterIDE
+__ZN3JSC3JIT15emitSlow_op_subEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT21emitSlow_op_constructEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT27compileOpConstructSetupArgsEPNS_11InstructionE
+__ZN3JSC3JIT28emitSlow_op_construct_verifyEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC7UString4fromEj
+__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPNS_7UString3RepE
+__ZN3JSC8JITStubs10cti_op_notEPPv
+__ZN3JSC8JITStubs24cti_op_get_by_id_genericEPPv
+__ZN3JSC7JSArrayC2EN3WTF10PassRefPtrINS_9StructureEEERKNS_7ArgListE
+__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL24stringProtoFuncSubstringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs31cti_op_construct_NotJSConstructEPPv
+__ZN3JSC3JIT33privateCompilePatchGetArrayLengthENS_22AbstractMacroAssemblerINS_12X86AssemblerEE22ProcessorReturnAddressE
+__ZN3JSC8JITStubs27cti_op_get_by_id_proto_listEPPv
+__ZN3JSC3JIT30privateCompileGetByIdProtoListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureES6_mP
+__ZN3JSC3JIT16patchGetByIdSelfEPNS_17StructureStubInfoEPNS_9StructureEmNS_22AbstractMacroAssemblerINS_12X86AssemblerEE22Process
+__ZN3JSC14StructureChainC1EPNS_9StructureE
+__ZN3JSC14StructureChainC2EPNS_9StructureE
+__ZN3JSC3JIT26privateCompileGetByIdChainEPNS_17StructureStubInfoEPNS_9StructureEPNS_14StructureChainEmmNS_22AbstractMacroAssemb
+__ZN3JSC8JITStubs23cti_op_put_by_id_secondEPPv
+__ZN3JSC8JITStubs15tryCachePutByIDEPNS_9ExecStateEPNS_9CodeBlockEPvNS_7JSValueERKNS_15PutPropertySlotE
+__ZN3JSC8JITStubs24cti_op_put_by_id_genericEPPv
+__ZN3JSC8JITStubs26cti_op_tear_off_activationEPPv
+__ZN3JSC8JITStubs21cti_op_ret_scopeChainEPPv
+__ZN3JSC17BytecodeGenerator16emitPutScopedVarEmiPNS_10RegisterIDENS_7JSValueE
+__ZN3JSC3JIT22emit_op_get_scoped_varEPNS_11InstructionE
+__ZN3JSC3JIT22emit_op_put_scoped_varEPNS_11InstructionE
+__ZN3JSC3JIT29emitPutVariableObjectRegisterENS_3X8610RegisterIDES2_i
+__ZN3JSC12X86Assembler7movq_rrENS_3X8610RegisterIDENS1_13XMMRegisterIDE
+__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv
+__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_
+__ZN3JSC15StrictEqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15StrictEqualNodeD0Ev
+__ZN3JSC3JIT16emit_op_stricteqEPNS_11InstructionE
+__ZN3JSC3JIT17compileOpStrictEqEPNS_11InstructionENS0_21CompileOpStrictEqTypeE
+__ZN3JSC3JIT20emitSlow_op_stricteqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC8JITStubs15cti_op_stricteqEPPv
 __ZN3WTF12detachThreadEj
 __ZN3WTFL26pthreadHandleForIdentifierEj
 __ZN3WTFL31clearPthreadHandleForIdentifierEj
-__ZN3WTF15ThreadConditionD1Ev
-__ZN3WTF23waitForThreadCompletionEjPPv
-__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv
-__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_
-__ZN3WTF14FastMallocZone10statisticsEP14_malloc_zone_tP19malloc_statistics_t
-__ZN3JSC4Heap26protectedGlobalObjectCountEv
-__ZNK3JSC11ResolveNode10isLocationEv
-__ZNK3JSC11ResolveNode13isResolveNodeEv
-__ZN3JSC17AssignResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator18findScopedPropertyERKNS_10IdentifierERiRmbRPNS_8JSObjectE
+__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEmPKS4_
+__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE15reserveCapacityEm
+__ZN3JSC8NullNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8NullNodeD0Ev
+__ZN3WTF7HashMapISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjEPNS3_9StructureENS3_28StructureTransitionTableHashENS3_34StructureTra
+__ZN3WTF9HashTableISt4pairINS_6RefPtrIN3JSC7UString3RepEEEjES1_IS7_PNS3_9StructureEENS_18PairFirstExtractorISA_EENS3_28Structur
+__ZN3JSC9Structure22materializePropertyMapEv
+__ZN3JSC15TypeOfValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15TypeOfValueNodeD0Ev
+__ZN3JSC12NotEqualNodeD0Ev
+__ZN3JSC3JIT11emit_op_neqEPNS_11InstructionE
+__ZN3JSC3JIT15emitSlow_op_neqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC8JITStubs13cti_op_typeofEPPv
+__ZN3JSC20jsTypeStringForValueEPNS_9ExecStateENS_7JSValueE
+__ZN3JSC8JITStubs10cti_op_neqEPPv
+__ZN3JSC14ExecutablePool13systemReleaseERKNS0_10AllocationE
+__ZN3WTF6VectorItLm0EE14expandCapacityEmPKt
+__ZNK3JSC10NumberNode8isNumberEv
+__ZNK3JSC14ExpressionNode10isLocationEv
+__ZN3WTF6VectorIPN3JSC10RegisterIDELm32EE14expandCapacityEm
+__ZNK3JSC11BooleanNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC4Yarr13newlineCreateEv
+__ZN3JSC12X86Assembler23X86InstructionFormatter15emitRexIfNeededEiii
+__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_3X8610RegisterIDES3_ii
+__ZN3JSC17TypeOfResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator15emitResolveBaseEPNS_10RegisterIDERKNS_10IdentifierE
-__ZN3JSC15DotAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12newTemporaryEv
-__ZN3JSC10StringNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDERKNS_10IdentifierE
-__ZN3WTF9HashTableIPN3JSC7UString3RepESt4pairIS4_PNS1_8JSStringEENS_18PairFirstExtractorIS8_EENS1_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS4_EENSD_IS7_EEEESE_E6expandEv
-__ZN3JSC16ArgumentListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC10StringNodeD1Ev
-__ZN3JSC16ArgumentListNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC16ArgumentListNodeD1Ev
-__ZN3JSC11Interpreter19cti_op_resolve_baseEPvz
-__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZNK3JSC8JSString8toStringEPNS_9ExecStateE
-__ZN3JSC13AssignDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC10StringNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC13ParameterNode12releaseNodesERNS_12NodeReleaserE
-__ZN3WTF6VectorISt4pairIN3JSC10IdentifierEjELm0EEaSERKS5_
-__ZNK3JSC7UString14toStrictUInt32EPb
-__ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_
-__ZN3JSC16VarStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator20emitLoadGlobalObjectEPNS_10RegisterIDEPNS_8JSObjectE
+__ZN3WTF6VectorIN3JSC7JSValueELm0EE14expandCapacityEm
+__ZNK3JSC7AddNode5isAddEv
+__ZN3JSC12BinaryOpNode10emitStrcatERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_PNS_21ReadModifyResolveNodeE
+__ZNK3JSC10StringNode8isStringEv
+__ZNK3JSC14ExpressionNode8isStringEv
+__ZN3JSC17BytecodeGenerator10emitStrcatEPNS_10RegisterIDES2_i
+__ZN3JSC4Yarr12spacesCreateEv
+__ZN3JSC4Yarr15nonspacesCreateEv
+__ZN3JSC8WithNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13emitPushScopeEPNS_10RegisterIDE
+__ZN3JSC23MacroAssemblerX86Common4moveENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5Imm32ENS_3X8610RegisterIDE
+__ZN3JSC14MacroAssembler4peekENS_3X8610RegisterIDEi
+__ZN3JSC4Yarr14RegexGenerator12atEndOfInputEv
+__ZN3JSC22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpList6linkToENS2_5LabelEPS2_
+__ZN3JSC14MacroAssembler4pokeENS_3X8610RegisterIDEi
+__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE
+__ZN3JSC23CallFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator25emitJumpIfNotFunctionCallEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC4Yarr14RegexGenerator29generateAssertionWordBoundaryERNS1_19TermGenerationStateE
+__ZN3JSC4Yarr14RegexGenerator22matchAssertionWordcharERNS1_19TermGenerationStateERNS_22AbstractMacroAssemblerINS_12X86Assembler
+__ZN3WTF6VectorIPN3JSC4Yarr18PatternDisjunctionELm4EE14expandCapacityEm
+__ZL14compileBracketiPiPPhPPKtS3_P9ErrorCodeiS_S_R11CompileData
+__ZN3JSC9ThrowNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9CommaNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3WTF9HashTableIdSt4pairIdN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsId
+__ZN3JSC17TypeOfResolveNodeD0Ev
+__ZN3JSC18NotStrictEqualNodeD0Ev
+__ZN3JSC8WithNodeD0Ev
+__ZN3JSC21FunctionCallValueNodeD0Ev
+__ZN3JSC9ArrayNodeD0Ev
+__ZN3JSC11ElementNodeD0Ev
+__ZN3JSC23CallFunctionCallDotNodeD0Ev
+__ZN3JSC9ThrowNodeD0Ev
+__ZN3JSC9CommaNodeD0Ev
+__ZN3JSC3JIT23emit_op_unexpected_loadEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_to_primitiveEPNS_11InstructionE
+__ZN3JSC3JIT14emit_op_strcatEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_nstricteqEPNS_11InstructionE
+__ZN3JSC3JIT18emit_op_push_scopeEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_new_arrayEPNS_11InstructionE
+__ZN3JSC3JIT16emit_op_jneq_ptrEPNS_11InstructionE
+__ZN3JSC3JIT13emit_op_throwEPNS_11InstructionE
+__ZN3JSC3JIT14emit_op_jnlessEPNS_11InstructionE
+__ZN3JSC3JIT24emitSlow_op_to_primitiveEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT21emitSlow_op_nstricteqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT18emitSlow_op_jnlessEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZL15makePostfixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
+__ZN3JSC18PostfixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC18PostfixResolveNodeD0Ev
+__ZN3JSC8JITStubs22cti_op_call_arityCheckEPPv
+__ZN3JSC19FunctionConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL32constructWithFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
+__ZN3JSCplERKNS_7UStringES2_
+__ZN3JSC7UString6appendERKS0_
+__ZN3JSC7UString17expandPreCapacityEi
+__ZN3WTF11fastReallocILb0EEEPvS1_m
+__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZL11makeDivNodePvPN3JSC14ExpressionNodeES2_b
 __ZL12makeMultNodePvPN3JSC14ExpressionNodeES2_b
-__ZN3JSC14ExpressionNode14stripUnaryPlusEv
-__ZN3JSC10NumberNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEd
-__ZN3WTF9HashTableIdSt4pairIdN3JSC10JSValuePtrEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsIdEENSA_IS3_EEEESB_E6expandEv
-__ZNK3JSC7AddNode8opcodeIDEv
-__ZNK3JSC8MultNode8opcodeIDEv
-__ZN3JSC10NumberNodeD1Ev
-__ZN3JSC8MultNodeD1Ev
-__ZN3JSC3JIT23compileFastArith_op_mulEPNS_11InstructionE
-__ZN3JSC14MacroAssembler4jz32ENS_3X8610RegisterIDENS0_5Imm32E
-__ZN3JSC12X86Assembler7subl_irEiNS_3X8610RegisterIDE
-__ZN3JSC3JIT20compileBinaryArithOpENS_8OpcodeIDEjjjNS_12OperandTypesE
-__ZN3JSC9CodeBlock19isKnownNotImmediateEi
-__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_3X8610RegisterIDEi
-__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_3X8610RegisterIDEi
-__ZN3JSC12X86Assembler8sarl_i8rEiNS_3X8610RegisterIDE
-__ZN3JSC15AssemblerBuffer7putByteEi
-__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_3X8610RegisterIDE
-__ZN3JSC3JIT42putDoubleResultToJSNumberCellOrJSImmediateENS_3X8613XMMRegisterIDENS1_10RegisterIDEjPNS_12X86Assembler6JmpSrcES2_S3_S3_
-__ZN3JSC3JIT27compileFastArithSlow_op_mulEPNS_11InstructionERPNS_13SlowCaseEntryE
-__ZN3JSC3JIT27compileFastArithSlow_op_addEPNS_11InstructionERPNS_13SlowCaseEntryE
-__ZN3JSC3JIT28compileBinaryArithOpSlowCaseENS_8OpcodeIDERPNS_13SlowCaseEntryEjjjNS_12OperandTypesE
-__ZN3JSC11Interpreter31cti_op_construct_NotJSConstructEPvz
-__ZN3JSC15DateConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL28constructWithDateConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC13constructDateEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC13DatePrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL20dateProtoFuncGetTimeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC12DateInstance9classInfoEv
-__ZN3JSC11Interpreter10cti_op_addEPvz
-__ZN3JSC12jsNumberCellEPNS_12JSGlobalDataEd
-__ZNK3JSC12JSNumberCell8toNumberEPNS_9ExecStateE
-__ZN3JSC11BooleanNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC9BlockNode7isBlockEv
-__ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC9BlockNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC9WhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC7ModNodeD0Ev
+__ZN3JSC7DivNodeD0Ev
+__ZN3JSC8MultNodeD0Ev
+__ZN3JSC9WhileNodeD0Ev
+__ZN3JSC3JIT11emit_op_modEPNS_11InstructionE
+__ZN3JSC3JIT11emit_op_mulEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_loop_if_trueEPNS_11InstructionE
+__ZN3JSC3JIT15emitSlow_op_modEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT15emitSlow_op_mulEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT24emitSlow_op_loop_if_trueEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSCL26stringProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue20toIntegerPreserveNaNEPNS_9ExecStateE
+__ZN3JSC8JITStubs10cti_op_divEPPv
+__ZN3JSC3JIT22emit_op_loop_if_lesseqEPNS_11InstructionE
+__ZN3JSC3JIT26emitSlow_op_loop_if_lesseqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC8JITStubs13cti_op_lesseqEPPv
+__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC19constructEmptyArrayEPNS_9ExecStateE
+__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL18arrayProtoFuncJoinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF7HashSetIPN3JSC8JSObjectENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3WTF6VectorItLm256EE6appendItEEvPKT_m
+__ZN3WTF6VectorItLm256EE14expandCapacityEm
+__ZN3WTF6VectorIPN3JSC12CallLinkInfoELm0EE15reserveCapacityEm
+__ZN3JSC4Heap7collectEv
+__ZN3JSC4Heap30markStackObjectsConservativelyEv
+__ZN3JSC4Heap31markCurrentThreadConservativelyEv
+__ZN3JSC4Heap39markCurrentThreadConservativelyInternalEv
+__ZN3JSC4Heap18markConservativelyEPvS1_
+__ZN3JSC7JSArray4markEv
+__ZN3JSC8JSObject4markEv
 __ZN3JSC10JSFunction4markEv
+__ZN3JSC6JSCell4markEv
+__ZN3JSC14JSGlobalObject4markEv
+__ZN3JSC15JSWrapperObject4markEv
+__ZN3JSC18GlobalEvalFunction4markEv
 __ZN3JSC16FunctionBodyNode4markEv
-__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator19emitResolveFunctionEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZNK3JSC12NotEqualNode8opcodeIDEv
-__ZNK3JSC8LessNode8opcodeIDEv
-__ZN3JSC23FunctionCallResolveNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC23FunctionCallResolveNodeD1Ev
-__ZN3JSC12NotEqualNodeD1Ev
-__ZN3JSC8LessNodeD1Ev
-__ZN3JSC11Interpreter19cti_op_resolve_funcEPvz
-__ZN3JSC11Interpreter22cti_op_call_JSFunctionEPvz
-__ZN3JSC16FunctionBodyNode16generateBytecodeEPNS_14ScopeChainNodeE
-__ZN3JSC6Parser14reparseInPlaceEPNS_12JSGlobalDataEPNS_16FunctionBodyNodeE
-__ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISE_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE
-__ZN3JSC16FunctionBodyNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC16JSVariableObject16isVariableObjectEv
-__ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_10JSValuePtrE
-__ZNK3JSC13StatementNode12isReturnNodeEv
-__ZN3JSC17BytecodeGenerator10emitReturnEPNS_10RegisterIDE
-__ZN3JSC11Interpreter23cti_vm_dontLazyLinkCallEPvz
-__ZN3JSC11Interpreter23cti_register_file_checkEPvz
-__ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierE
-__ZNK3JSC13StatementNode7isBlockEv
-__ZN3JSC10ReturnNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
-__ZN3JSC10ReturnNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC10ReturnNodeD1Ev
-__ZN3JSC11concatenateEPNS_7UString3RepES2_
-__ZN3JSC11Interpreter23cti_op_get_by_id_secondEPvz
-__ZN3JSC11Interpreter18tryCTICacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockEPvNS_10JSValuePtrERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC3JIT26privateCompileGetByIdProtoEPNS_17StructureStubInfoEPNS_9StructureES4_mPvPNS_9ExecStateE
-__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiPv
-__ZNK3JSC11ResolveNode6isPureERNS_17BytecodeGeneratorE
 __ZN3JSC9CodeBlock4markEv
-__ZN3JSC19BracketAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitGetByValEPNS_10RegisterIDES2_S2_
-__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC11Interpreter28cti_op_construct_JSConstructEPvz
+__ZN3JSC4Heap20markProtectedObjectsEv
+__ZN3JSC12SmallStrings4markEv
+__ZN3JSC4Heap5sweepILNS_8HeapTypeE0EEEmv
+__ZN3JSC14JSGlobalObjectD2Ev
+__ZN3JSC17FunctionPrototypeD1Ev
+__ZN3JSC15ObjectPrototypeD1Ev
+__ZN3JSC14ArrayPrototypeD1Ev
+__ZN3JSC15StringPrototypeD1Ev
+__ZN3JSC16BooleanPrototypeD1Ev
+__ZN3JSC15NumberPrototypeD1Ev
+__ZN3JSC13DatePrototypeD1Ev
+__ZN3JSC12DateInstanceD2Ev
+__ZN3JSC15RegExpPrototypeD1Ev
+__ZN3JSC14ErrorPrototypeD1Ev
+__ZN3JSC20NativeErrorPrototypeD1Ev
+__ZN3JSC17ObjectConstructorD1Ev
+__ZN3JSC19FunctionConstructorD1Ev
+__ZN3JSC16ArrayConstructorD1Ev
+__ZN3JSC17StringConstructorD1Ev
+__ZN3JSC18BooleanConstructorD1Ev
+__ZN3JSC17NumberConstructorD1Ev
+__ZN3JSC15DateConstructorD1Ev
+__ZN3JSC17RegExpConstructorD1Ev
+__ZN3JSC16ErrorConstructorD1Ev
+__ZN3JSC22NativeErrorConstructorD1Ev
+__ZN3JSC10MathObjectD1Ev
+__ZN3JSC18GlobalEvalFunctionD1Ev
+__ZN3JSC8JSObjectD1Ev
+__ZN3JSC9CodeBlock13unlinkCallersEv
+__ZN3WTF6VectorINS_6RefPtrIN3JSC6RegExpEEELm0EE6shrinkEm
+__ZN3JSC12JSActivationD1Ev
+__ZN3JSC12JSActivationD2Ev
+__ZN3JSC12RegExpObjectD1Ev
+__ZN3JSC18RegExpMatchesArrayD1Ev
+__ZN3JSC4Heap5sweepILNS_8HeapTypeE1EEEmv
+__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF17TCMalloc_PageHeap3NewEm
+__ZN3JSC8JITStubs28cti_op_construct_JSConstructEPPv
 __ZN3JSC8JSObject17createInheritorIDEv
-__ZL15makePostfixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
-__ZNK3JSC7ForNode6isLoopEv
-__ZN3JSC7ForNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13newLabelScopeENS_10LabelScope4TypeEPKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator8emitJumpEPNS_5LabelE
+__ZNK3JSC19BracketAccessorNode10isLocationEv
+__ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv
 __ZN3JSC17AssignBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC8ThisNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator12emitPutByValEPNS_10RegisterIDES2_S2_
-__ZN3JSC18PostfixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14emitJumpIfTrueEPNS_10RegisterIDEPNS_5LabelE
-__ZN3JSC7ForNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC7ForNodeD1Ev
-__ZN3JSC18PostfixResolveNodeD1Ev
-__ZN3JSC17AssignBracketNodeD1Ev
-__ZN3JSC17AssignBracketNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC8ThisNodeD1Ev
-__ZN3JSC3JIT27compileFastArith_op_pre_incEj
-__ZN3JSC12X86Assembler2joEv
-__ZN3JSC3JIT19emitSlowScriptCheckEv
-__ZN3JSC3JIT31compileFastArithSlow_op_pre_incEjRPNS_13SlowCaseEntryE
-__ZN3JSC11Interpreter22cti_op_call_arityCheckEPvz
-__ZN3JSC10JSFunction15argumentsGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZNK3JSC11Interpreter17retrieveArgumentsEPNS_9ExecStateEPNS_10JSFunctionE
-__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC11Interpreter17cti_op_get_by_valEPvz
-__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC11Interpreter17cti_op_put_by_valEPvz
-__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_10JSValuePtrE
-__ZN3JSC11Interpreter24cti_op_get_by_id_genericEPvz
-__ZN3JSCL21dateProtoFuncGetMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC12DateInstance21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
-__ZN3JSC21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
-__ZN3JSCL12getDSTOffsetEdd
-__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL20dateProtoFuncGetDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11concatenateEPNS_7UString3RepEi
-__ZN3JSC21ReadModifyResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC21ReadModifyResolveNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZL11makeSubNodePvPN3JSC14ExpressionNodeES2_b
-__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC10LessEqNode8opcodeIDEv
-__ZNK3JSC7SubNode8opcodeIDEv
-__ZN3JSC10LessEqNodeD1Ev
-__ZN3JSC7SubNodeD1Ev
-__ZN3JSC3JIT23compileFastArith_op_subEPNS_11InstructionE
-__ZN3JSC3JIT27compileFastArithSlow_op_subEPNS_11InstructionERPNS_13SlowCaseEntryE
-__ZN3JSCL21dateProtoFuncGetHoursEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter13cti_op_lesseqEPvz
-__ZN3JSCL23dateProtoFuncGetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC13GreaterEqNode8opcodeIDEv
-__ZN3JSC13GreaterEqNodeD1Ev
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_16SymbolTableEntryEENS_18PairFirstExtractorIS8_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS5_EENS2_26SymbolTableIndexHashTraitsEEESE_E4findIS5_NS_22IdentityHashTranslatorIS5_S8_SB_EEEENS_17HashTableIteratorIS5_S8_SA_SB_SG_SE_EERKT_
-__ZN3JSC8WithNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13emitPushScopeEPNS_10RegisterIDE
-__ZN3WTF6VectorIN3JSC18ControlFlowContextELm0EE14expandCapacityEm
-__ZN3JSC11Interpreter9cti_op_eqEPvz
-__ZN3JSCeqERKNS_7UStringES2_
-__ZN3JSC11Interpreter17cti_op_push_scopeEPvz
-__ZN3JSC11Interpreter14cti_op_resolveEPvz
-__ZN3JSC11Interpreter16cti_op_pop_scopeEPvz
-__ZN3JSC8NullNodeD1Ev
-__ZN3JSC8NullNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator20emitNextPropertyNameEPNS_10RegisterIDES2_PNS_5LabelE
-__ZN3JSC9ForInNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11Interpreter17cti_op_get_pnamesEPvz
-__ZN3JSC22JSPropertyNameIterator6createEPNS_9ExecStateENS_10JSValuePtrE
-__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZN3JSC9Structure26getEnumerablePropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayEPNS_8JSObjectE
-__ZN3JSC9Structure34getEnumerablePropertyNamesInternalERNS_17PropertyNameArrayE
-__ZNK3JSC6JSCell9classInfoEv
-__ZN3JSC9Structure26createCachedPrototypeChainEv
-__ZN3JSC14StructureChainC1EPNS_9StructureE
-__ZN3JSC11Interpreter17cti_op_next_pnameEPvz
-__ZN3JSC23structureChainsAreEqualEPNS_14StructureChainES1_
-__ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE
-__ZN3JSC11Interpreter10cti_op_neqEPvz
-__ZN3JSC16globalFuncEscapeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11JSImmediate8toStringENS_10JSValuePtrE
-__ZN3JSC7UString4fromEi
-__ZN3JSC7UString6appendERKS0_
-__ZN3JSC22JSPropertyNameIterator10invalidateEv
-__ZN3JSCL21dateProtoFuncSetMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL20dateProtoFuncSetDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCplERKNS_7UStringES2_
-__ZN3JSC14ExecutablePool13systemReleaseERKNS0_10AllocationE
-__ZNK3JSC8JSString11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZN3JSC14PostfixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17ReadModifyDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17AssignBracketNodeD0Ev
+__ZN3JSC14PostfixDotNodeD0Ev
+__ZN3JSC17ReadModifyDotNodeD0Ev
+__ZN3JSC3JIT18emit_op_put_by_valEPNS_11InstructionE
+__ZN3JSC3JIT22emitSlow_op_put_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSC16ArrayConstructor16getConstructDataERNS_13ConstructDataE
 __ZN3JSCL29constructWithArrayConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
 __ZN3JSCL27constructArrayWithSizeQuirkEPNS_9ExecStateERKNS_7ArgListE
-__ZL14makePrefixNodePvPN3JSC14ExpressionNodeENS0_8OperatorEiii
-__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC9WhileNode6isLoopEv
-__ZN3JSC9WhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC9WhileNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13PrefixDotNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13PrefixDotNodeD1Ev
-__ZN3JSC9WhileNodeD1Ev
-__ZN3JSC3JIT28compileFastArith_op_post_incEjj
-__ZN3JSC3JIT32compileFastArithSlow_op_post_incEjjRPNS_13SlowCaseEntryE
-__ZN3JSC11Interpreter22cti_op_push_activationEPvz
-__ZN3JSC12JSActivationC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_16FunctionBodyNodeEEE
+__ZN3JSC8JITStubs23cti_op_put_by_val_arrayEPPv
+__ZN3JSC8JITStubs13cti_op_strcatEPPv
+__ZN3JSC7UString3Rep15reserveCapacityEi
+__ZN3JSC7UString13appendNumericEi
+__ZN3JSC11concatenateEPNS_7UString3RepEi
 __ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZL11makeDivNodePvPN3JSC14ExpressionNodeES2_b
-__ZN3JSC15ConditionalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC7DivNode8opcodeIDEv
-__ZN3JSC15ConditionalNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC15ConditionalNodeD1Ev
-__ZN3JSC7DivNodeD1Ev
-__ZN3JSC7JSArrayC2EN3WTF10PassRefPtrINS_9StructureEEEj
-__ZN3JSC11Interpreter23cti_op_put_by_val_arrayEPvz
-__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_10JSValuePtrE
-__ZN3JSC7JSArray3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC11Interpreter10cti_op_divEPvz
-__ZN3JSC3JIT16patchGetByIdSelfEPNS_17StructureStubInfoEPNS_9StructureEmPv
-__ZN3JSC3JIT33privateCompilePatchGetArrayLengthEPv
-__ZN3JSC11Interpreter23cti_op_put_by_id_secondEPvz
-__ZN3JSC11Interpreter18tryCTICachePutByIDEPNS_9ExecStateEPNS_9CodeBlockEPvNS_10JSValuePtrERKNS_15PutPropertySlotE
-__ZN3JSCL19cachePrototypeChainEPNS_9ExecStateEPNS_9StructureE
-__ZN3JSC3JIT31privateCompilePutByIdTransitionEPNS_17StructureStubInfoEPNS_9StructureES4_mPNS_14StructureChainEPv
-__ZN3JSC9Structure22materializePropertyMapEv
-__ZN3JSC3JIT19patchPutByIdReplaceEPNS_17StructureStubInfoEPNS_9StructureEmPv
-__ZN3JSCL21resizePropertyStorageEPNS_8JSObjectEii
-__ZN3JSC8JSObject23allocatePropertyStorageEmm
-__ZN3JSC11Interpreter14cti_op_pre_incEPvz
-__ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC12StringObject12toThisStringEPNS_9ExecStateE
-__ZN3JSC11Interpreter26cti_op_tear_off_activationEPvz
-__ZN3JSC11Interpreter21cti_op_ret_scopeChainEPvz
-__ZN3JSC11Interpreter27cti_op_get_by_id_proto_listEPvz
-__ZN3JSC3JIT30privateCompileGetByIdProtoListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureES6_mPNS_9ExecStateE
-__ZN3JSC12JSActivationD0Ev
-__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC8JSString14toThisJSStringEPNS_9ExecStateE
-__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_10JSValuePtrE
-__ZN3WTF11fastReallocILb0EEEPvS1_m
-__ZN3JSCL24stringProtoFuncSubstringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11jsSubstringEPNS_12JSGlobalDataERKNS_7UStringEjj
-__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC19constructEmptyArrayEPNS_9ExecStateE
-__ZNK3JSC11BooleanNode6isPureERNS_17BytecodeGeneratorE
-__ZNK3JSC7ModNode8opcodeIDEv
-__ZN3JSC7ModNodeD1Ev
-__ZN3JSC3JIT23compileFastArith_op_modEjjj
-__ZN3JSC3JIT27compileFastArithSlow_op_modEjjjRPNS_13SlowCaseEntryE
-__ZN3JSCL23dateProtoFuncGetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC17BytecodeGenerator16emitPutScopedVarEmiPNS_10RegisterIDENS_10JSValuePtrE
-__ZN3JSC18globalFuncUnescapeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC7UString6appendEt
-__ZN3JSC11Interpreter19cti_vm_lazyLinkCallEPvz
-__ZN3JSC3JIT8linkCallEPNS_10JSFunctionEPNS_9CodeBlockEPvPNS_12CallLinkInfoEi
-__ZN3WTF6VectorIPN3JSC12CallLinkInfoELm0EE14expandCapacityEm
-__ZN3JSC12X86Assembler7cmpl_imEiiNS_3X8610RegisterIDE
-__ZN3JSC9CodeBlock13unlinkCallersEv
-__ZNK3JSC8JSString9toBooleanEPNS_9ExecStateE
-__ZN3JSC11Interpreter10cti_op_mulEPvz
-__ZN3JSC11Interpreter18cti_op_to_jsnumberEPvz
-__ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL18mathProtoFuncFloorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL13jsAddSlowCaseEPNS_9ExecStateENS_10JSValuePtrES2_
-__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC7UString4fromEj
-__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPNS_7UString3RepE
-__ZN3JSC7UString17expandPreCapacityEi
-__ZN3JSC9CommaNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC9CommaNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC16VarDeclCommaNodeD1Ev
-__ZN3JSC7UStringC1EPtib
-__ZN3JSC5Error6createEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringEilS6_
-__ZN3JSC22NativeErrorConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL35constructWithNativeErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC22NativeErrorConstructor9constructEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrEj
-__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
+__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC16globalFuncEscapeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12JSActivation14isDynamicScopeEv
+__ZN3WTF6VectorINS_6RefPtrIN3JSC10RegisterIDEEELm16EE14expandCapacityEm
+__ZN3JSC17ObjectConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithObjectConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC8JITStubs17cti_op_put_by_valEPPv
+__ZN3JSC15DateConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL28constructWithDateConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC13constructDateEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC8JITStubs18cti_op_is_functionEPPv
+__ZN3JSC16jsIsFunctionTypeENS_7JSValueE
+__ZN3JSC10Identifier5equalEPKNS_7UString3RepEPKc
+__ZN3JSC11JSImmediate8toStringENS_7JSValueE
+__ZN3JSC7UString4fromEi
+__ZN3JSC7UString3Rep11computeHashEPKti
+__ZNK3JSC8NullNode6isNullEv
+__ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE
+__ZN3JSC9BreakNodeD0Ev
+__ZN3JSC3JIT15emit_op_eq_nullEPNS_11InstructionE
+__ZN3JSC8JITStubs19cti_op_is_undefinedEPPv
+__ZN3JSC12JSActivation4markEv
+__ZN3JSC12DateInstanceD1Ev
+__ZNK3JSC18EmptyStatementNode16isEmptyStatementEv
+__ZN3JSC18EmptyStatementNodeD0Ev
+__ZN3JSC3JIT15emit_op_pre_decEPNS_11InstructionE
+__ZN3JSC3JIT19emitSlow_op_pre_decEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3WTF13tryFastMallocEm
+__ZN3JSC8JITStubs17cti_timeout_checkEPPv
+__ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE
+__ZN3JSC8JITStubs14cti_op_pre_decEPPv
+__ZN3JSC13jsAddSlowCaseEPNS_9ExecStateENS_7JSValueES2_
+__ZNK3JSC8JSString11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
 __ZNK3JSC8JSObject11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
 __ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
-__ZN3JSCL22errorProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
-__ZN3JSC7UString6appendEPKc
-__ZN3JSC3JIT10unlinkCallEPNS_12CallLinkInfoE
-__ZN3JSC11Interpreter24cti_op_put_by_id_genericEPvz
-__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE
-__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncExprNodeEEELm0EE15reserveCapacityEm
-__ZN3WTF7HashSetINS_6RefPtrIN3JSC7UString3RepEEENS2_17IdentifierRepHashENS_10HashTraitsIS5_EEE3addERKS5_
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEES5_NS_17IdentityExtractorIS5_EENS2_17IdentifierRepHashENS_10HashTraitsIS5_EESA_E6expandEv
-__ZL14compileBracketiPiPPhPPKtS3_P9ErrorCodeiS_S_R11CompileData
-__ZN3JSC4WREC9Generator20generateAssertionEOLERNS_14MacroAssembler8JumpListE
-__ZN3JSC17ObjectLiteralNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC4WREC31GeneratePatternCharacterFunctor12generateAtomEPNS0_9GeneratorERNS_14MacroAssembler8JumpListE
-__ZN3JSC4WREC31GeneratePatternCharacterFunctor9backtrackEPNS0_9GeneratorE
-__ZL20branchNeedsLineStartPKhjj
-__ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE
-__ZL17bracketIsAnchoredPKh
-__ZL32branchFindFirstAssertedCharacterPKhb
-__ZN3JSC10JSFunction3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC11concatenateEPNS_7UString3RepEd
-__ZNK3JSC12JSActivation14isDynamicScopeEv
-__ZN3JSC17TypeOfResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC15StrictEqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC12ContinueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14continueTargetERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi
-__ZN3JSC15TypeOfValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC15TypeOfValueNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC17TypeOfResolveNodeD1Ev
-__ZN3JSC15StrictEqualNodeD1Ev
-__ZN3JSC12ContinueNodeD1Ev
-__ZN3JSC15TypeOfValueNodeD1Ev
-__ZN3JSC11Interpreter33cti_op_create_arguments_no_paramsEPvz
-__ZN3JSC11Interpreter13cti_op_typeofEPvz
-__ZN3JSCL20jsTypeStringForValueEPNS_9ExecStateENS_10JSValuePtrE
+__ZN3JSCL22objectProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL25functionProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC10JSFunction9classInfoEv
+__ZNK3JSC21UStringSourceProvider8getRangeEii
+__ZNK3JSC7UString6substrEii
+__ZN3JSC8JITStubs26cti_op_get_by_id_self_failEPPv
+__ZN3JSC3JIT29privateCompileGetByIdSelfListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureEm
+__ZN3JSC8JITStubs16cti_op_nstricteqEPPv
+__ZN3JSC9ForInNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator20emitNextPropertyNameEPNS_10RegisterIDES2_PNS_5LabelE
+__ZN3JSC9ForInNodeD0Ev
+__ZN3JSC3JIT18emit_op_next_pnameEPNS_11InstructionE
+__ZN3JSC8JITStubs17cti_op_get_pnamesEPPv
+__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC9Structure26getEnumerablePropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayEPNS_8JSObjectE
+__ZN3JSC9Structure35getEnumerableNamesFromPropertyTableERNS_17PropertyNameArrayE
+__ZN3JSC8JITStubs17cti_op_next_pnameEPPv
+__ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE
+__ZN3JSC22JSPropertyNameIterator10invalidateEv
+__ZN3JSC3JIT22emit_op_init_argumentsEPNS_11InstructionE
+__ZN3JSC3JIT24emit_op_create_argumentsEPNS_11InstructionE
+__ZN3JSC8JITStubs33cti_op_create_arguments_no_paramsEPPv
+__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC3JIT16emit_op_post_decEPNS_11InstructionE
+__ZN3JSC3JIT20emitSlow_op_post_decEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC8JITStubs15cti_op_post_decEPPv
+__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC17RegExpConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC17RegExpConstructor3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC6JSCell11getCallDataERNS_8CallDataE
+__ZN3JSC10JSFunction3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC8JITStubs16cti_op_new_arrayEPPv
+__ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSCL18arrayProtoFuncPushEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL30comparePropertyMapEntryIndicesEPKvS1_
 __ZN3WTF6VectorIN3JSC10IdentifierELm20EE15reserveCapacityEm
-__ZN3JSCL22objectProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL22functionProtoFuncApplyEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC7JSArray9classInfoEv
-__ZN3JSCL18arrayProtoFuncPushEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter27cti_op_get_by_id_array_failEPvz
-__ZN3JSC14PostfixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC14PostfixDotNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11Interpreter32cti_op_get_by_id_proto_list_fullEPvz
-__ZN3JSC12FuncExprNodeD1Ev
-__ZN3JSC12FuncExprNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11Interpreter26cti_op_get_by_id_self_failEPvz
-__ZN3JSC3JIT29privateCompileGetByIdSelfListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureEm
-__ZN3JSCL19arrayProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter25cti_op_tear_off_argumentsEPvz
-__ZN3WTF6VectorIPN3JSC9StructureELm8EE14expandCapacityEm
-__ZN3JSCL44countPrototypeChainEntriesAndCheckForProxiesEPNS_9ExecStateENS_10JSValuePtrERKNS_12PropertySlotE
-__ZN3JSC17DeleteBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17DeleteBracketNodeD1Ev
-__ZN3JSC17DeleteBracketNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11Interpreter17cti_op_del_by_valEPvz
-__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
-__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZNK3JSC6JSCell9getUInt32ERj
-__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSCL11getPropertyEPNS_9ExecStateEPNS_8JSObjectEj
-__ZN3JSC17ReadModifyDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17ReadModifyDotNodeD1Ev
-__ZN3JSC17ReadModifyDotNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11JSImmediate9prototypeENS_10JSValuePtrEPNS_9ExecStateE
-__ZN3JSC9CodeBlock34reparseForExceptionInfoIfNecessaryEPNS_9ExecStateE
-__ZNK3JSC10ScopeChain10localDepthEv
-__ZNK3JSC12JSActivation9classInfoEv
-__ZN3JSC6Parser7reparseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPS5_
-__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm0EEERKNS_10SourceCodeEji
-__ZN3JSC13StatementNode6setLocEii
-__ZN3JSC16FunctionBodyNode14copyParametersEv
-__ZN3JSC16FunctionBodyNode13finishParsingEPNS_10IdentifierEm
-__ZN3JSC16FunctionBodyNode31bytecodeForExceptionInfoReparseEPNS_14ScopeChainNodeEPNS_9CodeBlockE
-__ZN3JSC9CodeBlock36hasGlobalResolveInfoAtBytecodeOffsetEj
-__ZN3JSC6RegExpD1Ev
-__Z12jsRegExpFreeP8JSRegExp
-__ZN3JSC12JSActivation4markEv
-__ZN3JSC9ThrowNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC9ThrowNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC9ThrowNodeD1Ev
-__ZNK3JSC21UStringSourceProvider6lengthEv
-__ZNK3JSC21UStringSourceProvider4dataEv
-__ZN3JSC21UStringSourceProviderD1Ev
-__ZN3JSC3JIT26privateCompileGetByIdChainEPNS_17StructureStubInfoEPNS_9StructureEPNS_14StructureChainEmmPvPNS_9ExecStateE
-__ZN3JSCL18arrayProtoFuncJoinEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3WTF7HashSetIPN3JSC8JSObjectENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
-__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3WTF6VectorItLm256EE14expandCapacityEm
-__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
-__ZN3JSC3JIT28compileFastArith_op_post_decEjj
-__ZN3JSC3JIT27compileFastArith_op_pre_decEj
-__ZN3JSC3JIT32compileFastArithSlow_op_post_decEjjRPNS_13SlowCaseEntryE
-__ZN3JSC3JIT31compileFastArithSlow_op_pre_decEjRPNS_13SlowCaseEntryE
-__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC9Arguments4markEv
-__ZN3JSC11Interpreter17cti_timeout_checkEPvz
-__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC17ObjectConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL30constructWithObjectConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC19JSStaticScopeObject4markEv
+__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC8JITStubs17cti_op_push_scopeEPPv
+__ZN3JSC8JITStubs14cti_op_resolveEPPv
+__ZN3JSC8JITStubs16cti_op_pop_scopeEPPv
+__ZN3JSC3JIT31privateCompilePutByIdTransitionEPNS_17StructureStubInfoEPNS_9StructureES4_mPNS_14StructureChainENS_22AbstractMacr
+__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common9ConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE
+__ZN3JSC3JIT19patchPutByIdReplaceEPNS_17StructureStubInfoEPNS_9StructureEmNS_22AbstractMacroAssemblerINS_12X86AssemblerEE22Proc
 __ZN3JSC17NumberConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC21ThrowableBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC6InNode8opcodeIDEv
-__ZN3JSC11Interpreter9cti_op_inEPvz
-__ZN3JSC11Interpreter21cti_op_put_by_id_failEPvz
-__ZN3JSC17RegExpConstructor3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC11Interpreter18cti_op_is_functionEPvz
-__ZN3JSC18globalFuncIsFiniteEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL21arrayProtoFuncForEachEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL17arrayProtoFuncMapEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC12StringObject14toThisJSStringEPNS_9ExecStateE
+__ZN3JSC8JITStubs16cti_op_is_stringEPPv
+__ZN3JSC8JITStubs19cti_op_convert_thisEPPv
 __ZNK3JSC8JSString12toThisObjectEPNS_9ExecStateE
-__ZN3JSCL21arrayProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL22stringProtoFuncReplaceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12StringObject14toThisJSStringEPNS_9ExecStateE
+__ZN3JSCL21arrayProtoFuncForEachEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11Interpreter20prepareForRepeatCallEPNS_16FunctionBodyNodeEPNS_9ExecStateEPNS_10JSFunctionEiPNS_14ScopeChainNodeEPNS_7J
+__ZN3JSC3JIT16emit_op_post_incEPNS_11InstructionE
+__ZN3JSC3JIT20emitSlow_op_post_incEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC11Interpreter7executeERNS_16CallFrameClosureEPNS_7JSValueE
+__ZN3JSC10MathObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC11Interpreter13endRepeatCallERNS_16CallFrameClosureE
+__ZN3JSCL21resizePropertyStorageEPNS_8JSObjectEii
+__ZN3JSC8JSObject23allocatePropertyStorageEmm
+__ZN3JSC14ExecutablePool12poolAllocateEm
+__ZN3JSC9Arguments4markEv
+__ZN3JSC22JSPropertyNameIterator4markEv
+__ZN3JSC3JIT10unlinkCallEPNS_12CallLinkInfoE
+__ZN3JSC22JSPropertyNameIteratorD1Ev
+__ZN3JSC9ArgumentsD1Ev
+__ZN3JSC9ArgumentsD2Ev
+__ZN3JSC12StringObjectD1Ev
+__ZN3WTF6VectorIPN3JSC9StructureELm8EE14expandCapacityEmPKS3_
+__ZN3WTF6VectorIPN3JSC9StructureELm8EE15reserveCapacityEm
+__ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL11getPropertyEPNS_9ExecStateEPNS_8JSObjectEj
+__ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC7JSArray9setLengthEj
+__ZN3JSC7UString6appendEPKc
+__ZN3JSC8JITStubs23cti_op_create_argumentsEPPv
+__ZN3JSCL19arrayProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE
+__ZN3JSC24ApplyFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14ExpressionNode13isSimpleArrayEv
+__ZN3JSC17BytecodeGenerator26emitJumpIfNotFunctionApplyEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC17BytecodeGenerator15emitCallVarargsEPNS_10RegisterIDES2_S2_S2_jjj
+__ZN3JSC24ApplyFunctionCallDotNodeD0Ev
+__ZN3JSC3JIT20emit_op_load_varargsEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_call_varargsEPNS_11InstructionE
+__ZN3JSC3JIT20compileOpCallVarargsEPNS_11InstructionE
+__ZN3JSC3JIT29compileOpCallVarargsSetupArgsEPNS_11InstructionE
+__ZN3JSC3JIT24emitSlow_op_call_varargsEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT28compileOpCallVarargsSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC8JITStubs19cti_op_load_varargsEPPv
+__ZNK3JSC7JSArray9classInfoEv
+__ZN3JSC7JSArray15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
+__ZNK3JSC7UString30spliceSubstringsWithSeparatorsEPKNS0_5RangeEiPKS0_i
+__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC7UString4fromEd
+__ZN3WTF4dtoaEPcdiPiS1_PS0_
+__ZN3JSC8JITStubs21cti_op_put_by_id_failEPPv
 __ZN3JSC13DeleteDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator14emitDeleteByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3JSC13DeleteDotNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11Interpreter16cti_op_del_by_idEPvz
+__ZN3JSC13DeleteDotNodeD0Ev
+__ZN3JSC3JIT17emit_op_del_by_idEPNS_11InstructionE
+__ZN3JSC8JITStubs16cti_op_del_by_idEPPv
 __ZN3JSC10JSFunction14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC10JSFunction12callerGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
-__ZN3JSCL22arrayProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZNK3JSC7ArgList8getSliceEiRS0_
+__ZN3JSC3JIT26emit_op_tear_off_argumentsEPNS_11InstructionE
+__ZN3JSC8JITStubs25cti_op_tear_off_argumentsEPPv
+__ZNK3JSC12StringObject12toThisStringEPNS_9ExecStateE
+__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13PrefixDotNodeD0Ev
+__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
+__ZN3JSCL22arrayProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21arrayProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC16ErrorConstructor16getConstructDataERNS_13ConstructDataE
 __ZN3JSCL29constructWithErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
 __ZN3JSC14constructErrorEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC12JSActivation3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3WTF6VectorIN3JSC14MacroAssembler4JumpELm16EE14expandCapacityEm
+__ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs32cti_op_get_by_id_proto_list_fullEPPv
 __ZN3JSC14InstanceOfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator14emitInstanceOfEPNS_10RegisterIDES2_S2_S2_
-__ZN3JSC14InstanceOfNodeD1Ev
-__ZN3JSC11JSImmediate8toObjectENS_10JSValuePtrEPNS_9ExecStateE
-__ZNK3JSC12NumberObject9classInfoEv
-__ZN3JSC11Interpreter17cti_op_instanceofEPvz
-__ZNK3JSC7UString6substrEii
-__ZN3JSCL20arrayProtoFuncSpliceEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC19FunctionConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL32constructWithFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
-__ZNK3JSC17ExprStatementNode15isExprStatementEv
-__ZNK3JSC12FuncExprNode14isFuncExprNodeEv
-__ZN3JSC7ArgList9markListsERN3WTF7HashSetIPS0_NS1_7PtrHashIS3_EENS1_10HashTraitsIS3_EEEE
-__ZN3JSC9CommaNodeD1Ev
-__ZN3JSC11Interpreter12cti_op_throwEPvz
-__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_10JSValuePtrEjb
-__ZNK3JSC8JSObject22isNotAnObjectErrorStubEv
-__ZN3JSC9CodeBlock32expressionRangeForBytecodeOffsetEPNS_9ExecStateEjRiS3_S3_
-__ZNK3JSC8JSObject19isWatchdogExceptionEv
-__ZN3JSC9CodeBlock24handlerForBytecodeOffsetEj
-__ZN3JSC11Interpreter15unwindCallFrameERPNS_9ExecStateENS_10JSValuePtrERjRPNS_9CodeBlockE
-__ZN3JSCL23returnToThrowTrampolineEPNS_12JSGlobalDataEPvRS2_
-__ZN3JSC19ctiSetReturnAddressEPPvS0_
-ctiVMThrowTrampoline
-__ZN3JSC11Interpreter12cti_vm_throwEPvz
-__ZN3JSC11Interpreter21cti_op_push_new_scopeEPvz
-__ZN3JSC19JSStaticScopeObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC9Arguments3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC4WREC9Generator27generateNonGreedyQuantifierERNS_14MacroAssembler8JumpListERNS0_19GenerateAtomFunctorEjj
-__ZN3JSCL21arrayProtoFuncReverseEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC7UString6appendEPKti
-__ZN3JSCL26stringProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC10JSValuePtr20toIntegerPreserveNaNEPNS_9ExecStateE
-__Z22jsc_pcre_ucp_othercasej
-__ZN3JSCL24regExpConstructorDollar1EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar2EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar3EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar4EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL19dateProtoFuncGetDayEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC19JSStaticScopeObject14isDynamicScopeEv
-__ZN3JSCL35objectProtoFuncPropertyIsEnumerableEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC8JSObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
-__ZN3WTF9HashTableIjSt4pairIjN3JSC10JSValuePtrEENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSA_IS3_EEEESB_EC2ERKSE_
-__ZN3JSC11Interpreter14cti_op_pre_decEPvz
-__ZN3JSC11Interpreter16cti_op_new_arrayEPvz
-__ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC10JSFunction11getCallDataERNS_8CallDataE
-__ZN3JSC4callEPNS_9ExecStateENS_10JSValuePtrENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
-__ZN3JSC11Interpreter7executeEPNS_16FunctionBodyNodeEPNS_9ExecStateEPNS_10JSFunctionEPNS_8JSObjectERKNS_7ArgListEPNS_14ScopeChainNodeEPNS_10JSValuePtrE
-__ZN3JSC9LabelNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC9LabelNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11Interpreter15cti_op_stricteqEPvz
-__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
-__ZL5matchPKtPKhiR9MatchData
-__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE
-__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC18RegExpMatchesArray17fillArrayInstanceEPNS_9ExecStateE
-__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC14InstanceOfNodeD0Ev
+__ZN3JSC3JIT18emit_op_instanceofEPNS_11InstructionE
+__ZN3JSC3JIT22emitSlow_op_instanceofEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC12X86Assembler6orl_irEiNS_3X8610RegisterIDE
+__ZN3JSC17RegExpConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC15constructRegExpEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC13DatePrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL20dateProtoFuncGetTimeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12DateInstance9classInfoEv
 __ZN3JSC12RegExpObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL19regExpProtoFuncTestEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL19regExpProtoFuncTestEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC12RegExpObject5matchEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSCL21functionProtoFuncCallEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC8JSString8toObjectEPNS_9ExecStateE
-__ZNK3JSC7ArgList8getSliceEiRS0_
-__ZN3JSC17RegExpConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC23FunctionCallBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC23FunctionCallBracketNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC23FunctionCallBracketNodeD1Ev
-__ZN3JSC11Interpreter16cti_op_is_stringEPvz
-__ZN3JSC7TryNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator9emitCatchEPNS_10RegisterIDEPNS_5LabelES4_
-__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14expandCapacityEm
-__ZN3JSC17BytecodeGenerator16emitPushNewScopeEPNS_10RegisterIDERNS_10IdentifierES2_
-__ZN3JSC7TryNode12releaseNodesERNS_12NodeReleaserE
-__ZN3WTF6VectorIN3JSC14ExecutablePool10AllocationELm2EE14expandCapacityEm
-__ZN3JSC11Interpreter19cti_op_loop_if_lessEPvz
-__ZN3JSCL22stringProtoFuncReplaceEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC7UString30spliceSubstringsWithSeparatorsEPKNS0_5RangeEiPKS0_i
-__Z15jsc_pcre_xclassiPKh
-__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateEjNS_10JSValuePtrE
-__ZN3JSC7JSArray9setLengthEj
-__ZN3JSCL21arrayProtoFuncUnShiftEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateEj
-__ZN3JSC11Interpreter19cti_op_is_undefinedEPvz
-__ZNK3JSC9Arguments9classInfoEv
-__ZN3JSC9Arguments11fillArgListEPNS_9ExecStateERNS_7ArgListE
-__ZN3JSC11Interpreter23cti_op_create_argumentsEPvz
+__ZN3JSC3JIT18emit_op_jmp_scopesEPNS_11InstructionE
+__ZN3JSC3JIT30privateCompileGetByIdChainListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureEPNS_1
+__ZN3JSC18globalFuncUnescapeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7UString6appendEt
+__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE
 __ZN3JSC17PropertyNameArray3addEPNS_7UString3RepE
 __ZN3WTF7HashSetIPN3JSC7UString3RepENS_7PtrHashIS4_EENS_10HashTraitsIS4_EEE3addERKS4_
-__ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7PtrHashIS4_EENS_10HashTraitsIS4_EESA_E6expandEv
+__ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7PtrHashIS4_EENS_10HashTraitsIS4_EESA_E6rehashEi
 __ZN3WTF6VectorIN3JSC10IdentifierELm20EE14expandCapacityEm
-__ZN3JSC11Interpreter19cti_op_convert_thisEPvz
-__ZN3JSC17PrefixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17PrefixBracketNodeD1Ev
-__ZN3JSC17PrefixBracketNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSCL25functionProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC10JSFunction9classInfoEv
-__ZN3JSC7CStringD1Ev
-__ZN3JSC6JSLock12DropAllLocksC1Eb
-__ZN3JSCL17createJSLockCountEv
-__ZN3JSC6JSLock12DropAllLocksD1Ev
+__ZN3JSCL20arrayProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC9ArrayNode13isSimpleArrayEv
+__ZN3JSC8JITStubs10cti_op_mulEPPv
+__ZN3JSC8JITStubs16cti_op_is_objectEPPv
+__ZN3JSC14jsIsObjectTypeENS_7JSValueE
+__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
+__ZN3JSC9CodeBlock34reparseForExceptionInfoIfNecessaryEPNS_9ExecStateE
+__ZNK3JSC10ScopeChain10localDepthEv
+__ZNK3JSC12JSActivation9classInfoEv
+__ZN3JSC6Parser7reparseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPS5_
+__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_IP
+__ZN3JSC13StatementNode6setLocEii
+__ZN3JSC16FunctionBodyNode14copyParametersEv
+__ZN3JSC16FunctionBodyNode13finishParsingEPNS_10IdentifierEm
+__ZN3JSC16FunctionBodyNode31bytecodeForExceptionInfoReparseEPNS_14ScopeChainNodeEPNS_9CodeBlockE
+__ZN3JSC9CodeBlock36hasGlobalResolveInfoAtBytecodeOffsetEj
+__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEPNS_9ExecStateEj
+__ZN3WTF6VectorIPvLm0EE14expandCapacityEmPKS1_
+__ZN3WTF6VectorIPvLm0EE15reserveCapacityEm
+__ZN3JSC3JIT16emit_op_jeq_nullEPNS_11InstructionE
+__ZN3JSC8JITStubs16cti_op_is_numberEPPv
+__ZN3JSCL23stringProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12StringObject9classInfoEv
+__ZN3JSC8JITStubs28cti_op_get_by_id_string_failEPPv
+__ZN3JSC11JSImmediate9prototypeENS_7JSValueEPNS_9ExecStateE
+__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC3JIT16emit_op_neq_nullEPNS_11InstructionE
+__ZN3JSC4Yarr23RegexPatternConstructor8copyTermERNS0_11PatternTermE
+__ZL17bracketIsAnchoredPKh
+__ZL32branchFindFirstAssertedCharacterPKhb
+__ZL20branchNeedsLineStartPKhjj
+__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL20stringProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC3JIT17emit_op_jneq_nullEPNS_11InstructionE
+__ZN3JSC8JITStubs25cti_op_call_NotJSFunctionEPPv
+__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callStringConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12StringObject8toStringEPNS_9ExecStateE
+__ZN3JSC23FunctionCallBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3JSC23FunctionCallBracketNodeD0Ev
+__ZN3JSC20EvalFunctionCallNodeD0Ev
+__ZN3JSC3JIT25emit_op_resolve_with_baseEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_call_evalEPNS_11InstructionE
+__ZN3JSC3JIT21emitSlow_op_call_evalEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC14MacroAssembler4jumpENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5LabelE
+__ZN3JSCL19regExpProtoFuncExecEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7UString12replaceRangeEiiRKS0_
+__ZN3JSC8JITStubs17cti_op_is_booleanEPPv
+__ZN3JSC3JIT22emit_op_put_global_varEPNS_11InstructionE
+__ZN3JSCL23regExpProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18regExpObjectSourceEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL18regExpObjectGlobalEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL22regExpObjectIgnoreCaseEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL21regExpObjectMultilineEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC4Yarr14RegexGenerator30generatePatternCharacterGreedyERNS1_19TermGenerationStateE
+__ZN3JSC8JITStubs27cti_op_get_by_id_proto_failEPPv
+__ZN3JSC17DeleteResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17DeleteResolveNodeD0Ev
+__ZN3JSC3JIT20emit_op_resolve_baseEPNS_11InstructionE
+__ZN3JSC8JITStubs19cti_op_resolve_baseEPPv
+__ZN3JSC12JSActivation14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZNK3JSC8JSString8toNumberEPNS_9ExecStateE
+__ZN3JSC8JITStubs24cti_op_resolve_with_baseEPPv
+__ZN3JSC8JITStubs16cti_op_call_evalEPPv
+__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEiiRNS_7JSValueE
+__ZN3JSC13LiteralParser5Lexer3lexERNS1_18LiteralParserTokenE
+__ZN3JSC13LiteralParser14parseStatementEv
+__ZN3JSC13LiteralParser15parseExpressionEv
+__ZN3JSC13LiteralParser10parseArrayEv
+__ZN3JSC13LiteralParser11parseObjectEv
+__ZN3JSC10Identifier3addEPNS_9ExecStateEPKti
+__ZN3JSC7JSArray4pushEPNS_9ExecStateENS_7JSValueE
+__ZN3JSCL19mathProtoFuncRandomEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF16weakRandomNumberEv
+__ZN3JSCL18mathProtoFuncFloorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC4Heap15recordExtraCostEm
+__ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
+__ZN3JSC9ExecState9thisValueEv
+__ZN3JSC11Interpreter7executeEPNS_8EvalNodeEPNS_9ExecStateEPNS_8JSObjectEiPNS_14ScopeChainNodeEPNS_7JSValueE
+__ZN3JSC8EvalNode16generateBytecodeEPNS_14ScopeChainNodeE
+__ZN3JSC17BytecodeGeneratorC2EPNS_8EvalNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3RepEEENS_16
+__ZN3JSC8EvalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZThn16_N3JSC8EvalNodeD0Ev
+__ZN3JSC8EvalNodeD0Ev
+__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSObject9classNameEv
+__ZN3JSC11JSImmediate12toThisObjectENS_7JSValueEPNS_9ExecStateE
+__ZNK3JSC6JSCell17getTruncatedInt32ERi
+__ZN3JSC15toInt32SlowCaseEdRb
+__ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12DateInstance21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
+__ZN3JSC21msToGregorianDateTimeEdbRNS_17GregorianDateTimeE
+__ZN3JSCL12getDSTOffsetEdd
+__ZN3JSC21gregorianDateTimeToMSERKNS_17GregorianDateTimeEdb
+__ZN3JSCL15dateToDayInYearEiii
+__ZN3JSC8JITStubs19cti_op_to_primitiveEPPv
+__ZN3JSCL21dateProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10formatTimeERKNS_17GregorianDateTimeEb
+__ZN3JSCL24dateProtoFuncToGMTStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7UString13appendNumericEd
+__ZN3JSC11concatenateEPNS_7UString3RepEd
+__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL20dateProtoFuncGetDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21dateProtoFuncGetMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21dateProtoFuncGetHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23dateProtoFuncGetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23dateProtoFuncGetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL19dateProtoFuncGetDayEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierEjPNS_9CodeBlockE
+__ZN3JSC9CodeBlock32expressionRangeForBytecodeOffsetEPNS_9ExecStateEjRiS3_S3_
+__ZN3JSC5Error6createEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringEilS6_
+__ZN3JSC22NativeErrorConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL35constructWithNativeErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC22NativeErrorConstructor9constructEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
+__ZN3JSCL23returnToThrowTrampolineEPNS_12JSGlobalDataEPvRS2_
+_ctiVMThrowTrampoline
+__ZN3JSC8JITStubs12cti_vm_throwEPPv
+__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_7JSValueEjb
+__ZNK3JSC8JSObject22isNotAnObjectErrorStubEv
+__ZNK3JSC8JSObject19isWatchdogExceptionEv
+__ZN3JSC9CodeBlock24handlerForBytecodeOffsetEj
+__ZN3JSC8JITStubs21cti_op_push_new_scopeEPPv
+__ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EE14expandCapacityEm
+__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS1_INS2_8EvalNodeEEENS_7StrHashIS5_EENS_10HashTraitsIS5_EENSA_IS7_EEE3getEPS4
+__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS1_INS2_8EvalNodeEEENS_7StrHashIS5_EENS_10HashTraitsIS5_EENSA_IS7_EEE3setEPS4_
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS1_INS2_8EvalNodeEEEENS_18PairFirstExtractorIS9_EENS_7StrHashIS5_
+__ZN3JSC10LessEqNodeD0Ev
+__ZN3JSC8JITStubs14cti_op_jlesseqEPPv
+__ZN3JSC8JSString18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
+__ZL18makeRightShiftNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC14RightShiftNodeD0Ev
+__ZN3JSC3JIT14emit_op_rshiftEPNS_11InstructionE
+__ZN3JSC3JIT18emitSlow_op_rshiftEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC18PostfixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC18PostfixBracketNodeD0Ev
+__ZN3JSC21ReadModifyBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC21ReadModifyBracketNodeD0Ev
+__ZN3JSC11Interpreter15unwindCallFrameERPNS_9ExecStateENS_7JSValueERjRPNS_9CodeBlockE
+__ZN3JSCL22errorProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF23waitForThreadCompletionEjPPv
+__ZN3WTF15ThreadConditionD1Ev
+__ZN3JSC9Structure24removePropertyTransitionEPS0_RKNS_10IdentifierERm
+__ZN3JSC12JSActivation3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC26createNotAnObjectErrorStubEPNS_9ExecStateEb
-__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
+__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZNK3JSC22JSNotAnObjectErrorStub22isNotAnObjectErrorStubEv
 __ZN3JSC22createNotAnObjectErrorEPNS_9ExecStateEPNS_22JSNotAnObjectErrorStubEjPNS_9CodeBlockE
 __ZN3JSC9CodeBlock37getByIdExceptionInfoForBytecodeOffsetEPNS_9ExecStateEjRNS_8OpcodeIDE
-__ZN3JSCL18createErrorMessageEPNS_9ExecStateEPNS_9CodeBlockEiiiNS_10JSValuePtrENS_7UStringE
+__ZN3JSCL18createErrorMessageEPNS_9ExecStateEPNS_9CodeBlockEiiiNS_7JSValueENS_7UStringE
+__ZN3JSC13ErrorInstanceD1Ev
+__ZN3JSC22JSNotAnObjectErrorStubD1Ev
+__ZN3JSC13JSNotAnObjectD1Ev
+__ZN3JSC19JSStaticScopeObjectD1Ev
+__ZN3JSC19JSStaticScopeObjectD2Ev
+__ZN3JSC17DeleteBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator15emitDeleteByValEPNS_10RegisterIDES2_S2_
+__ZN3JSC17DeleteBracketNodeD0Ev
+__ZN3JSC8JITStubs17cti_op_del_by_valEPPv
+__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC28globalFuncEncodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL6encodeEPNS_9ExecStateERKNS_7ArgListEPKc
+__ZNK3JSC7UString10UTF8StringEb
+__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
+__ZN3JSC10NegateNodeD0Ev
+__ZN3JSC8JITStubs13cti_op_negateEPPv
+__ZN3JSCL17mathProtoFuncSqrtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncAbsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18mathProtoFuncRoundEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncCosEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncSinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs10cti_op_subEPPv
+__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
+__ZN3JSC16ArrayConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL20callArrayConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs10cti_op_modEPPv
+__ZN3JSC8JITStubs12cti_op_jlessEPPv
+__ZL17makeLeftShiftNodePvPN3JSC14ExpressionNodeES2_b
+__ZN3JSC13LeftShiftNodeD0Ev
+__ZN3JSC3JIT14emit_op_lshiftEPNS_11InstructionE
+__ZN3JSC3JIT18emitSlow_op_lshiftEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC11JITStubCall11addArgumentENS_3X8610RegisterIDE
+__ZN3JSCL16mathProtoFuncMaxEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10BitAndNodeD0Ev
+__ZN3JSC3JIT14emit_op_bitandEPNS_11InstructionE
+__ZN3JSC3JIT18emitSlow_op_bitandEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC8JITStubs13cti_op_bitandEPPv
+__ZN3JSC14BitwiseNotNodeD0Ev
+__ZN3JSC3JIT14emit_op_bitnotEPNS_11InstructionE
+__ZN3JSC3JIT18emitSlow_op_bitnotEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC22UnsignedRightShiftNodeD0Ev
+__ZN3JSC10BitXOrNodeD0Ev
+__ZN3JSC3JIT14emit_op_bitxorEPNS_11InstructionE
+__ZN3JSC3JIT18emitSlow_op_bitxorEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSCL25stringProtoFuncCharCodeAtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs14cti_op_urshiftEPPv
+__ZN3JSC16toUInt32SlowCaseEdRb
+__ZN3JSCL17mathProtoFuncCeilEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC6JSCell18getTruncatedUInt32ERj
+__ZN3JSC3JIT13emit_op_bitorEPNS_11InstructionE
+__ZN3JSC3JIT17emitSlow_op_bitorEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC8JITStubs12cti_op_bitorEPPv
+__ZN3JSC9BitOrNodeD0Ev
+__ZN3JSC8JITStubs13cti_op_rshiftEPPv
+__ZN3JSC8JITStubs13cti_op_bitxorEPPv
+__ZN3JSC9parseDateERKNS_7UStringE
+__ZN3WTF6VectorIN3JSC10CallRecordELm0EE14expandCapacityEmPKS2_
+__ZNK3JSC12JSActivation12toThisObjectEPNS_9ExecStateE
+__ZN3JSC3JIT20emit_op_resolve_skipEPNS_11InstructionE
+__ZN3JSC8JITStubs19cti_op_resolve_skipEPPv
+__ZN3JSCL24dateProtoFuncGetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC17StringConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithStringConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC5equalEPKNS_7UString3RepES3_
+__ZN3JSC8EvalNode4markEv
+__ZN3JSC10SwitchNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13CaseBlockNode20emitBytecodeForBlockERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_
+__ZN3JSC13CaseBlockNode18tryOptimizedSwitchERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERiS7_
+__ZN3JSCL17processClauseListEPNS_14ClauseListNodeERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERNS_10SwitchKindERbRiSB_
+__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm8EE14expandCapacityEm
+__ZN3WTF6VectorINS_6RefPtrIN3JSC5LabelEEELm8EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator11beginSwitchEPNS_10RegisterIDENS_10SwitchInfo10SwitchTypeE
+__ZN3WTF6VectorIN3JSC10SwitchInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator9endSwitchEjPN3WTF6RefPtrINS_5LabelEEEPPNS_14ExpressionNodeEPS3_ii
+__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14expandCapacityEm
+__ZN3WTF6VectorIiLm0EE15reserveCapacityEm
+__ZN3JSC14CaseClauseNodeD0Ev
+__ZN3JSC14ClauseListNodeD0Ev
+__ZN3JSC13CaseBlockNodeD0Ev
+__ZN3JSC10SwitchNodeD0Ev
+__ZN3JSC3JIT19emit_op_switch_charEPNS_11InstructionE
+__ZN3WTF6VectorIN3JSC12SwitchRecordELm0EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE17CodeLocationLabelELm0EE4growEm
+__ZN3JSC8JITStubs18cti_op_switch_charEPPv
+__ZN3JSCL16mathProtoFuncPowEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorIcLm0EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC7UString5RangeELm16EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC7UStringELm16EE14expandCapacityEmPKS2_
+__ZN3WTF6VectorIN3JSC7UStringELm16EE15reserveCapacityEm
+__ZN3JSC7JSArray16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC9ExecState10arrayTableEPS0_
+__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
+__ZN3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehas
+__ZN3JSC8JITStubs24cti_op_get_by_val_stringEPPv
+__ZN3JSCL16mathProtoFuncLogEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7UString8toDoubleEv
+__ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7PtrHashIS4_EENS_10HashTraitsIS4_EESA_E4findIS4_NS_22Id
+__ZN3JSCL29objectProtoFuncHasOwnPropertyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18arrayProtoFuncSortEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray4sortEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE
+__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE6insertEi
+__ZN3JSCltERKNS_7UStringES2_
+__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE7balanceEi
+__Z12jsRegExpFreeP8JSRegExp
+__ZN3JSCL21stringProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC19globalFuncEncodeURIEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC19globalFuncDecodeURIEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL6decodeEPNS_9ExecStateERKNS_7ArgListEPKcb
+__ZN3WTF7Unicode18UTF8SequenceLengthEc
+__ZN3WTF7Unicode18decodeUTF8SequenceEPKc
+__ZN3JSCL22numberProtoFuncToFixedEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16integerPartNoExpEd
+__ZN3WTF14FastMallocZone10statisticsEP14_malloc_zone_tP19malloc_statistics_t
+__ZN3JSC4Heap26protectedGlobalObjectCountEv
+__ZN3JSC10JSFunction15argumentsGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZNK3JSC11Interpreter17retrieveArgumentsEPNS_9ExecStateEPNS_10JSFunctionE
+__ZN3JSCL21dateProtoFuncSetMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23setNewValueFromDateArgsEPNS_9ExecStateENS_7JSValueERKNS_7ArgListEib
+__ZN3JSCL20dateProtoFuncSetDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE14expandCapacityEm
+__ZN3JSC8JITStubs14cti_op_pre_incEPPv
+__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm16EE14expandCapacityEm
+__ZN3JSC13UnaryPlusNodeD0Ev
+__ZN3JSC3JIT19emit_op_to_jsnumberEPNS_11InstructionE
+__ZN3JSC3JIT23emitSlow_op_to_jsnumberEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC8JITStubs18cti_op_to_jsnumberEPPv
+__ZN3JSC6JSLock12DropAllLocksC1Eb
+__ZN3JSCL17createJSLockCountEv
+__ZN3JSC6JSLock12DropAllLocksD1Ev
+__ZN3JSCL24dateProtoFuncSetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE15reserveCapacityEm
+__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS2_14OffsetLocationENS_7StrHashIS5_EENS_10HashTraitsIS5_EENS9_IS6_EEE3addEPS4_
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_14OffsetLocationEENS_18PairFirstExtractorIS8_EENS_7StrHashIS5_
+__ZN3JSC3JIT21emit_op_switch_stringEPNS_11InstructionE
+__ZN3JSC8JITStubs20cti_op_switch_stringEPPv
+__ZN3WTF6VectorIN3JSC14ExecutablePool10AllocationELm2EE14expandCapacityEm
+__ZN3JSC12JSGlobalData6createEb
+__ZN3JSCL13allocateBlockILNS_8HeapTypeE1EEEPNS_14CollectorBlockEv
+__ZN3JSC7JSValueC1EPNS_9ExecStateEd
+__ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RK
+__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
+__ZN3JSC7CStringD1Ev
+__ZN3WTF7HashMapIPvjNS_7PtrHashIS1_EEN3JSC17JSValueHashTraitsENS_10HashTraitsIjEEE3addERKS1_RKj
+__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncExprNodeEEELm0EE14shrinkCapacityEm
+__ZN3JSC14ExpressionNodeD2Ev
+__ZThn12_N3JSC11ProgramNodeD0Ev
+__ZThn12_N3JSC12FuncExprNodeD0Ev
+__ZThn12_N3JSC16FunctionBodyNodeD0Ev
+__ZN3JSC8JITStubs16cti_op_new_arrayEPvz
+__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE15reserveCapacityEm
+__ZN3JSC17BytecodeGenerator10emitOpcodeENS_8OpcodeIDE
+__ZN3JSC23MacroAssemblerX86Common4moveENS_3X8610RegisterIDES2_
+__ZN3JSC8JITStubs15cti_op_new_funcEPvz
+__ZN3JSC8JITStubs21cti_op_resolve_globalEPvz
+__ZN3JSC8JITStubs16cti_op_get_by_idEPvz
+__ZN3JSC8JITStubs31cti_op_construct_NotJSConstructEPvz
+__ZN3JSC8JITStubs16cti_op_put_by_idEPvz
+__ZN3JSC8JITStubs13cti_op_strcatEPvz
+__ZN3JSC8JITStubs19cti_op_resolve_funcEPvz
+__ZN3JSC8JITStubs23cti_vm_dontLazyLinkCallEPvz
+__ZN3JSC8JITStubs22cti_op_call_JSFunctionEPvz
+__ZN3JSC8JITStubs23cti_register_file_checkEPvz
+__ZN3JSC8JITStubs13cti_op_negateEPvz
+__ZN3JSC8JITStubs28cti_op_construct_JSConstructEPvz
+__ZN3JSC23MacroAssemblerX86Common12branchTest32ENS0_9ConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_5Imm
+__ZN3JSC8JITStubs23cti_op_put_by_val_arrayEPvz
+__ZN3JSC8JITStubs23cti_op_put_by_id_secondEPvz
+__ZN3JSC15AssemblerBuffer14executableCopyEPNS_14ExecutablePoolE
+__ZN3JSC12X86Assembler8sarl_i8rEiNS_3X8610RegisterIDE
+__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_3X8610RegisterIDEi
+__ZN3JSC8JITStubs10cti_op_mulEPvz
+__ZN3JSC12jsNumberCellEPNS_12JSGlobalDataEd
+__ZN3JSC8JITStubs10cti_op_subEPvz
+__ZN3JSC8JITStubs10cti_op_divEPvz
+__ZN3JSC8JITStubs23cti_op_get_by_id_secondEPvz
+__ZN3JSC8JITStubs19cti_vm_lazyLinkCallEPvz
+__ZN3WTF6VectorIPN3JSC12CallLinkInfoELm0EE14expandCapacityEm
+__ZN3JSC8JITStubs19cti_op_convert_thisEPvz
+__ZN3JSC8JITStubs21cti_op_put_by_id_failEPvz
+__ZN3JSC8JITStubs10cti_op_addEPvz
+__ZN3JSC8JITStubs17cti_timeout_checkEPvz
+__ZN3JSC9jsBooleanEb
+__ZN3JSC9CodeBlock19isKnownNotImmediateEi
+__ZN3JSC12X86Assembler8movsd_mrEiNS_3X8610RegisterIDENS1_13XMMRegisterIDE
+__ZN3JSC8JITStubs25cti_op_call_NotJSFunctionEPvz
+__ZNK3JSC12JSNumberCell8toNumberEPNS_9ExecStateE
+__ZN3JSC8JITStubs26cti_op_get_by_id_self_failEPvz
+__ZN3JSC8JITStubs10cti_op_endEPvz
+__ZThn12_N3JSC12FuncDeclNodeD0Ev
+__ZN3JSC8JITStubs24cti_op_resolve_with_baseEPvz
+__ZN3JSC8JITStubs19cti_op_new_func_expEPvz
+__ZN3JSC8JITStubs22cti_op_push_activationEPvz
+__ZN3JSC8JITStubs17cti_op_get_by_valEPvz
+__ZN3JSC8JITStubs22cti_op_call_arityCheckEPvz
+__ZN3JSC8JITStubs11cti_op_lessEPvz
+__ZN3JSC12JSNumberCell18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDE
+__ZN3JSC8JITStubs27cti_op_get_by_id_proto_listEPvz
+__ZN3JSC8JITStubs12cti_op_jtrueEPvz
+__ZN3JSC8JITStubs10cti_op_modEPvz
+__ZN3JSC8JITStubs10cti_op_neqEPvz
+__ZN3JSC8JITStubs12cti_op_jlessEPvz
+__ZN3JSC8JITStubs24cti_op_get_by_id_genericEPvz
+__ZN3JSC8JITStubs14cti_op_jlesseqEPvz
+__ZN3JSC8JITStubs26cti_op_tear_off_activationEPvz
+__ZN3JSC8JITStubs21cti_op_ret_scopeChainEPvz
+__ZN3JSC8JITStubs19cti_op_to_primitiveEPvz
+__ZNK3JSC12JSNumberCell8toStringEPNS_9ExecStateE
+__ZN3JSC8JITStubs13cti_op_bitandEPvz
+__ZN3JSC8JITStubs13cti_op_lshiftEPvz
+__ZN3JSC8JITStubs13cti_op_bitnotEPvz
+__ZNK3JSC12JSNumberCell9toBooleanEPNS_9ExecStateE
+__ZN3JSC8JITStubs14cti_op_urshiftEPvz
+__ZNK3JSC12JSNumberCell18getTruncatedUInt32ERj
+__ZN3JSC4Yarr14RegexGenerator28generateCharacterClassSingleERNS1_19TermGenerationStateE
+__ZN3WTF15deleteAllValuesIPN3JSC4Yarr18PatternDisjunctionELm4EEEvRKNS_6VectorIT_XT0_EEE
+__ZN3JSC8JITStubs17cti_op_new_regexpEPvz
+__ZN3JSC8JITStubs12cti_op_bitorEPvz
+__ZNK3JSC12JSNumberCell17getTruncatedInt32ERi
+__ZN3JSC8JITStubs13cti_op_rshiftEPvz
+__ZN3JSC8JITStubs13cti_op_bitxorEPvz
+__ZN3WTF7HashSetINS_6RefPtrIN3JSC7UString3RepEEENS2_17IdentifierRepHashENS_10HashTraitsIS5_EEE3addERKS5_
+__ZN3JSC8JITStubs9cti_op_eqEPvz
+__ZN3JSC8JITStubs16cti_op_call_evalEPvz
+__ZN3JSC8JITStubs19cti_op_resolve_skipEPvz
+__ZN3JSC8JITStubs17cti_op_new_objectEPvz
+__ZN3JSC8JITStubs14cti_op_resolveEPvz
+__ZN3JSC8JITStubs17cti_op_put_by_valEPvz
+__ZN3JSC8JITStubs18cti_op_switch_charEPvz
+__ZN3JSC8JITStubs28cti_op_get_by_id_string_failEPvz
+__ZThn12_N3JSC8EvalNodeD0Ev
+__ZN3WTF6VectorIN3JSC7UStringELm16EE14expandCapacityEm
+__ZN3JSC8JITStubs17cti_op_get_pnamesEPvz
+__ZN3JSC8JITStubs17cti_op_next_pnameEPvz
+__ZN3WTF7HashSetIPN3JSC20MarkedArgumentBufferENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findI
+__ZN3JSC8JITStubs24cti_op_get_by_val_stringEPvz
+__ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE28CharacterClassParserDelegate25atomBuiltInCharacterClassENS0_23BuiltInChar
+__ZN3JSC12jsNumberCellEPNS_9ExecStateEd
+__ZN3JSC8JITStubs18cti_op_is_functionEPvz
+__ZN3JSC8JITStubs16cti_op_is_objectEPvz
+__ZN3JSC8JITStubs16cti_op_nstricteqEPvz
+__ZN3JSC8JITStubs13cti_op_lesseqEPvz
+__ZNK3JSC12JSNumberCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZN3JSC4Yarr14RegexGenerator27generateCharacterClassFixedERNS1_19TermGenerationStateE
+__ZN3JSC4Heap7destroyEv
+__ZN3JSC12JSGlobalDataD1Ev
+__ZN3JSC12JSGlobalDataD2Ev
+__ZN3JSC12RegisterFileD1Ev
+__ZNK3JSC9HashTable11deleteTableEv
+__ZN3JSC5LexerD1Ev
+__ZN3JSC5LexerD2Ev
+__ZN3WTF20deleteAllPairSecondsIP24OpaqueJSClassContextDataKNS_7HashMapIP13OpaqueJSClassS2_NS_7PtrHashIS5_EENS_10HashTraitsIS5_E
+__ZN3JSC17CommonIdentifiersD2Ev
+__ZN3JSC21deleteIdentifierTableEPNS_15IdentifierTableE
+__ZN3JSC4HeapD1Ev
+__ZN3JSC12SmallStringsD1Ev
+__ZN3JSCL16mathProtoFuncMinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray3popEv
+__ZN3JSC11DoWhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11DoWhileNodeD0Ev
+__ZN3JSC3JIT18emit_op_switch_immEPNS_11InstructionE
+__ZN3JSC8JITStubs17cti_op_switch_immEPPv
+__ZN3JSC13UnaryPlusNode14stripUnaryPlusEv
+__ZN3JSC15globalFuncIsNaNEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC17NumberConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callNumberConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEm
+__ZN3JSC8JITStubs19cti_op_is_undefinedEPvz
+__ZN3JSC8JITStubs13cti_op_typeofEPvz
+__ZN3JSC8JITStubs33cti_op_create_arguments_no_paramsEPvz
+__ZN3JSC8JITStubs19cti_op_load_varargsEPvz
+__ZN3JSC8JITStubs10cti_op_notEPvz
+__ZN3JSC8JITStubs16cti_op_is_stringEPvz
+__ZN3JSCL24regExpConstructorDollar1EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14expandCapacityEm
+__ZN3JSC8JITStubs20cti_op_switch_stringEPvz
+__ZN3JSC9Arguments3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC8JITStubs18cti_op_to_jsnumberEPvz
+__ZN3JSC8JITStubs19cti_op_loop_if_lessEPvz
+__ZN3JSC9LabelNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9LabelNodeD0Ev
 __ZNK3JSC7UString5asciiEv
-__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF10PassRefPtrINS_9StructureEEERKNS_10IdentifierE
-__ZN3WTF13tryFastCallocEmm
-__ZN3JSC13JSNotAnObjectD0Ev
-__ZN3JSCL31dateProtoFuncToLocaleTimeStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL16formatLocaleDateEPNS_9ExecStateEPNS_12DateInstanceEdNS_20LocaleDateTimeFormatERKNS_7ArgListE
+__ZN3JSC8JITStubs27cti_op_get_by_id_array_failEPvz
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiPv
+__ZN3JSC8JITStubs23cti_op_create_argumentsEPvz
+__ZN3JSCL21arrayProtoFuncUnShiftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs25cti_op_tear_off_argumentsEPvz
+__ZN3JSC7JSArray11sortNumericEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE
+__ZN3JSC7JSArray17compactForSortingEv
+__ZN3JSCL22compareNumbersForQSortEPKvS1_
+__ZN3JSC8JITStubs15cti_op_post_incEPPv
+__ZN3JSC8JITStubs24cti_op_put_by_id_genericEPvz
+__ZN3JSCL24regExpConstructorDollar2EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar3EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar4EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar5EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar6EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL21stringProtoFuncSubstrEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23stringProtoFuncFontsizeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncToUTCStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL19stringProtoFuncLinkEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL9dateParseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs21cti_op_loop_if_lesseqEPPv
+__ZN3JSCL16mathProtoFuncExpEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC4Yarr17nonwordcharCreateEv
+__ZN3WTF6VectorIPN3JSC4Yarr18PatternDisjunctionELm4EE14expandCapacityEmPKS4_
+__Z15jsc_pcre_xclassiPKh
+__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC28globalFuncDecodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs27cti_op_get_by_id_array_failEPPv
+__ZNK3JSC9Arguments9classInfoEv
+__ZN3JSC9Arguments15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
+__ZN3JSC19JSStaticScopeObject4markEv
+__ZN3JSC8JITStubs19cti_op_loop_if_lessEPPv
+__ZN3JSC8JITStubs16cti_op_del_by_idEPvz
+__ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC7UString6appendEPKti
+__ZN3JSC8JITStubs17cti_op_push_scopeEPvz
+__ZN3JSC8JITStubs19cti_op_resolve_baseEPvz
+__ZN3JSC8JITStubs16cti_op_pop_scopeEPvz
+__ZN3JSC8JITStubs17cti_op_is_booleanEPvz
+__ZN3JSCL20arrayProtoFuncSpliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs17cti_op_jmp_scopesEPvz
+__ZN3JSC8JITStubs9cti_op_inEPvz
+__ZN3JSC8JITStubs15cti_op_stricteqEPvz
+__ZN3JSC8JITStubs32cti_op_get_by_id_proto_list_fullEPvz
+__ZN3WTF6VectorIiLm8EE14expandCapacityEm
+__ZN3JSCL21stringProtoFuncSearchEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs12cti_vm_throwEPvz
+__ZN3JSC8JITStubs21cti_op_push_new_scopeEPvz
+__ZN3JSC8JITStubs16cti_op_is_numberEPvz
+__ZN3JSC16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZNK3JSC8JSString8toObjectEPNS_9ExecStateE
+__ZN3JSC12StringObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC9ExecState11stringTableEPS0_
+__ZN3JSC11JSImmediate8toObjectENS_7JSValueEPNS_9ExecStateE
+__ZN3JSC36constructBooleanFromImmediateBooleanEPNS_9ExecStateENS_7JSValueE
+__ZN3JSC13BooleanObjectD1Ev
+__ZN3JSCL17arrayProtoFuncMapEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArrayC2EN3WTF10PassRefPtrINS_9StructureEEEj
+__ZN3JSC8JITStubs17cti_op_del_by_valEPvz
+__ZN3JSC8JITStubs27cti_op_get_by_id_proto_failEPvz
+__ZN3JSC10JSFunction12callerGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
+__ZN3JSC18globalFuncIsFiniteEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZNK3JSC12JSNumberCell8toObjectEPNS_9ExecStateE
+__ZN3JSC15constructNumberEPNS_9ExecStateENS_7JSValueE
+__ZN3JSC12NumberObject11getJSNumberEv
+__ZN3JSCL7dateNowEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12NumberObjectD1Ev
+__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
+__ZN3JSCL22numberProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC19JSStaticScopeObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC16InternalFunction4nameEPNS_12JSGlobalDataE
-__ZNK3JSC6JSCell9getStringERNS_7UStringE
-__ZN3JSC28globalFuncDecodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC14ExpressionNode8isStringEv
+__ZN3JSCL18arrayProtoFuncSomeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC12JSNumberCell11getJSNumberEv
+__ZN3JSC23createNotAFunctionErrorEPNS_9ExecStateENS_7JSValueEjPNS_9CodeBlockE
+__ZN3JSC17PrefixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17PrefixBracketNodeD0Ev
 __ZN3JSC17RegExpConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC23createNotAFunctionErrorEPNS_9ExecStateENS_10JSValuePtrEjPNS_9CodeBlockE
-__ZN3JSC11Interpreter17cti_op_jmp_scopesEPvz
+__ZN3JSCL21callRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray4sortEPNS_9ExecStateE
+__ZN3JSCL27dateProtoFuncSetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncSetUTCHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23setNewValueFromTimeArgsEPNS_9ExecStateENS_7JSValueERKNS_7ArgListEib
+__ZN3JSC8JITStubs17cti_op_switch_immEPvz
+__ZN3JSC12RegExpObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSCL24setRegExpObjectLastIndexEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
+__ZN3JSCL28regExpConstructorLeftContextEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC18RegExpMatchesArray14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC10JSFunction12lengthGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZNK3JSC12NumberObject9classInfoEv
+__ZN3JSC8JITStubs12cti_op_throwEPvz
+__ZN3JSCL19isNonASCIIIdentPartEi
+__ZN3JSCL27dateProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16formatLocaleDateEPNS_9ExecStateEPNS_12DateInstanceEdNS_20LocaleDateTimeFormatERKNS_7ArgListE
+__ZN3JSCL21dateProtoFuncSetHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23dateProtoFuncSetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23dateProtoFuncSetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL28dateProtoFuncSetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12JSNumberCell12toThisObjectEPNS_9ExecStateE
+__ZN3JSC16ErrorConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL20callErrorConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectES6_RKNS_7ArgListEE
+__ZN3JSC17PrototypeFunctionC2EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectES6_RKNS_7ArgListEE
+__ZN3JSC17PrototypeFunction11getCallDataERNS_8CallDataE
+__ZN3JSC17PrototypeFunctionD1Ev
+__ZN3JSCL24booleanProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC17BytecodeGenerator18emitJumpSubroutineEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC3JIT11emit_op_jsrEPNS_11InstructionE
 __ZN3WTF6VectorIN3JSC3JIT7JSRInfoELm0EE14expandCapacityEm
-__ZN3JSC18RegExpMatchesArray16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierEjPNS_9CodeBlockE
-__ZN3JSC17DeleteResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSCL21stringProtoFuncSearchEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL27objectProtoFuncDefineGetterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
-__ZN3JSC9Structure22getterSetterTransitionEPS0_
-__ZN3JSCL27objectProtoFuncLookupGetterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
-__ZNK3JSC6JSCell14isGetterSetterEv
-__ZN3JSCL27objectProtoFuncLookupSetterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC10JSFunction12lengthGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL27objectProtoFuncDefineSetterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
-__ZNK3JSC12GetterSetter14isGetterSetterEv
-__ZN3JSC12GetterSetter4markEv
-__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj
-__ZN3JSC17BytecodeGenerator21emitComplexJumpScopesEPNS_5LabelEPNS_18ControlFlowContextES4_
-__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_10JSValuePtrE
-__ZN3JSC12PropertySlot14functionGetterEPNS_9ExecStateERKNS_10IdentifierERKS0_
-__ZN3JSC7JSArray4sortEPNS_9ExecStateE
-__ZN3JSC7JSArray17compactForSortingEv
-__ZN3JSCL24booleanProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC8VoidNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC8VoidNodeD1Ev
-__ZN3JSC8VoidNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSCL27compareByStringPairForQSortEPKvS1_
+__ZN3JSC3JIT12emit_op_sretEPNS_11InstructionE
 __ZN3JSC6Parser7reparseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPS5_
-__ZN3JSC8EvalNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm0EEERKNS_10SourceCodeEji
+__ZN3JSC8EvalNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPNS6_IPNS_12Func
 __ZN3JSC8EvalNode31bytecodeForExceptionInfoReparseEPNS_14ScopeChainNodeEPNS_9CodeBlockE
+__ZN3JSC20FixedVMPoolAllocator17coalesceFreeSpaceEv
+__ZN3WTF6VectorIPN3JSC13FreeListEntryELm0EE15reserveCapacityEm
+__ZN3JSCL35reverseSortFreeListEntriesByPointerEPKvS1_
+__ZN3JSC14globalFuncEvalEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21functionProtoFuncCallEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL22functionProtoFuncApplyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC9Arguments11fillArgListEPNS_9ExecStateERNS_20MarkedArgumentBufferE
+__ZNK3JSC7JSValue12toThisObjectEPNS_9ExecStateE
+__ZN3JSC8VoidNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8VoidNodeD0Ev
+__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF10PassRefPtrINS_9StructureEEERKNS_10IdentifierE
+__ZN3JSC20MarkedArgumentBuffer9markListsERN3WTF7HashSetIPS0_NS1_7PtrHashIS3_EENS1_10HashTraitsIS3_EEEE
+__ZN3JSC7CStringaSERKS0_
+__ZNK3JSC19JSStaticScopeObject14isDynamicScopeEv
+__ZN3JSCL33reverseSortCommonSizedAllocationsEPKvS1_
+__ZN3JSCL20arrayProtoFuncFilterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC17NumberConstructor16getConstructDataERNS_13ConstructDataE
 __ZN3JSCL30constructWithNumberConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC17BytecodeGenerator18emitUnexpectedLoadEPNS_10RegisterIDEb
+__ZN3JSC8JITStubs12cti_op_throwEPPv
+__ZN3JSC6JSCell9getObjectEv
+__ZN3JSCL21arrayProtoFuncReverseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZNK3JSC8JSObject16isVariableObjectEv
-__ZN3JSC36constructBooleanFromImmediateBooleanEPNS_9ExecStateENS_10JSValuePtrE
-__ZN3JSC13BooleanObjectD0Ev
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_14OffsetLocationEENS_18PairFirstExtractorIS8_EENS_7StrHashIS5_EENS_14PairHashTraitsINS_10HashTraitsIS5_EENSE_IS7_EEEESF_E4findIPS4_NS_29RefPtrHashMapRawKeyTranslatorISK_S8_SH_SC_EEEENS_17HashTableIteratorIS5_S8_SA_SC_SH_SF_EERKT_
-__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
-__ZN3JSC14globalFuncEvalEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter7executeEPNS_8EvalNodeEPNS_9ExecStateEPNS_8JSObjectEPNS_14ScopeChainNodeEPNS_10JSValuePtrE
-__ZN3JSC11Interpreter19cti_op_put_by_indexEPvz
+__ZN3JSC18EmptyStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSCL27compareByStringPairForQSortEPKvS1_
+__Z22jsc_pcre_ucp_othercasej
+__ZN3JSCL35objectProtoFuncPropertyIsEnumerableEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
+__ZN3WTF7HashMapIjN3JSC7JSValueENS_7IntHashIjEENS_10HashTraitsIjEENS5_IS2_EEE3setERKjRKS2_
+__ZN3WTF9HashTableIjSt4pairIjN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEE
+__ZN3JSC12RegisterFile21releaseExcessCapacityEv
+__ZN3JSCL20isNonASCIIIdentStartEi
+__ZN3JSC17BytecodeGenerator14emitPutByIndexEPNS_10RegisterIDEjS2_
+__ZN3JSC3JIT20emit_op_put_by_indexEPNS_11InstructionE
+__ZN3JSC8JITStubs19cti_op_put_by_indexEPPv
 __ZN3JSCL25numberConstructorMaxValueEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
 __ZN3JSCL28numberConstructorPosInfinityEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
 __ZN3JSCL28numberConstructorNegInfinityEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL17mathProtoFuncATanEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC18RegExpMatchesArray14deletePropertyEPNS_9ExecStateEj
-__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC18EmptyStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSCL17mathProtoFuncASinEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL18mathProtoFuncATan2EPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC16ErrorConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL20callErrorConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL7dateNowEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
 __ZN3JSC18BooleanConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL22callBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL20arrayProtoFuncFilterEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC4WREC9Generator28generateParenthesesAssertionERNS_14MacroAssembler8JumpListE
-__ZN3JSCL21regExpObjectLastIndexEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL18arrayProtoFuncSomeEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC12RegExpObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSCL24setRegExpObjectLastIndexEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrE
-__ZN3JSC26createNotAConstructorErrorEPNS_9ExecStateENS_10JSValuePtrEjPNS_9CodeBlockE
-__ZN3JSC15isStrWhiteSpaceEt
-__ZN3JSCL27dateProtoFuncGetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL24dateProtoFuncGetUTCMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL23dateProtoFuncGetUTCDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL24dateProtoFuncGetUTCHoursEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL26dateProtoFuncGetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL7dateUTCEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL21dateProtoFuncSetHoursEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL23setNewValueFromTimeArgsEPNS_9ExecStateENS_10JSValuePtrERKNS_7ArgListEib
-__ZN3JSCL23dateProtoFuncSetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL23dateProtoFuncSetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL28dateProtoFuncSetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC7CStringaSERKS0_
-__ZN3JSCL22dateProtoFuncGetUTCDayEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC7UString8toUInt32EPb
-__ZN3JSC12RegExpObject11getCallDataERNS_8CallDataE
-__ZNK3JSC8JSObject14isGlobalObjectEv
-__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_10JSValuePtrE
-__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
-__ZN3JSC16JSVariableObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZN3JSC17BytecodeGenerator18emitUnexpectedLoadEPNS_10RegisterIDEb
-__ZN3WTF6VectorIN3JSC10JSValuePtrELm0EE14expandCapacityEm
-__ZN3JSC18BooleanConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL31constructWithBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC16constructBooleanEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSCL26stringFromCharCodeSlowCaseEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSCL27dateProtoFuncSetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL26dateProtoFuncGetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL31dateProtoFuncGetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL28dateProtoFuncGetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZNK3JSC12JSNumberCell9getUInt32ERj
-__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSCL23booleanProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL27dateProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC9Arguments14deletePropertyEPNS_9ExecStateEj
-__ZNK3JSC21UStringSourceProvider8getRangeEii
-__ZN3JSC22NativeErrorConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL23dateProtoFuncSetUTCDateEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-JSClassCreate
+__ZN3JSCL22callBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL17mathProtoFuncATanEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JITStubs17cti_op_jmp_scopesEPPv
+__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj
+__ZN3JSCL17mathProtoFuncASinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11Interpreter7executeEPNS_8EvalNodeEPNS_9ExecStateEPNS_8JSObjectEPNS_14ScopeChainNodeEPNS_7JSValueE
+_JSContextGetGlobalObject
+__ZN3JSC4Heap14registerThreadEv
+__ZN3JSC6JSLockC1EPNS_9ExecStateE
+_JSStringCreateWithUTF8CString
+__ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b
+_JSClassCreate
 __ZN13OpaqueJSClass6createEPK17JSClassDefinition
 __ZN13OpaqueJSClassC2EPK17JSClassDefinitionPS_
 __ZN3JSC7UString3Rep14createFromUTF8EPKc
-__ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b
-__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEEP19StaticFunctionEntryNS_7StrHashIS5_EENS_10HashTraitsIS5_EENSA_IS7_EEE3addERKS5_RKS7_
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_P19StaticFunctionEntryENS_18PairFirstExtractorIS9_EENS_7StrHashIS5_EENS_14PairHashTraitsINS_10HashTraitsIS5_EENSF_IS8_EEEESG_E6expandEv
-JSClassRetain
-JSObjectMake
-__ZN3JSC4Heap14registerThreadEv
-__ZN3JSC6JSLockC1EPNS_9ExecStateE
+__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEEP19StaticFunctionEntryNS_7StrHashIS5_EENS_10HashTraitsIS5_EENSA_IS7_EEE3addERKS
+__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_P19StaticFunctionEntryENS_18PairFirstExtractorIS9_EENS_7StrHashIS5
+__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEEP16StaticValueEntryNS_7StrHashIS5_EENS_10HashTraitsIS5_EENSA_IS7_EEE3addERKS5_R
+_JSClassRetain
+_JSObjectMake
 __ZN3JSC16JSCallbackObjectINS_8JSObjectEE4initEPNS_9ExecStateE
 __ZN13OpaqueJSClass9prototypeEPN3JSC9ExecStateE
 __ZN13OpaqueJSClass11contextDataEPN3JSC9ExecStateE
-__ZN3WTF9HashTableIP13OpaqueJSClassSt4pairIS2_P24OpaqueJSClassContextDataENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS5_EEEESD_E6expandEv
+__ZN3WTF9HashTableIP13OpaqueJSClassSt4pairIS2_P24OpaqueJSClassContextDataENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14Pa
 __ZN24OpaqueJSClassContextDataC2EP13OpaqueJSClass
-JSStringCreateWithCFString
-JSObjectSetProperty
+__ZN3JSC7UString3Rep13createCopyingEPKti
+_JSObjectSetProperty
 __ZNK14OpaqueJSString10identifierEPN3JSC12JSGlobalDataE
-JSStringRelease
-__ZL30makeGetterOrSetterPropertyNodePvRKN3JSC10IdentifierES3_PNS0_13ParameterNodeEPNS0_16FunctionBodyNodeERKNS0_10SourceCodeE
-__ZN3JSC18ConstStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC13ConstDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC13ConstDeclNode14emitCodeSingleERNS_17BytecodeGeneratorE
-__ZN3JSC17BytecodeGenerator13emitPutGetterEPNS_10RegisterIDERKNS_10IdentifierES2_
-__ZN3JSC17BytecodeGenerator13emitPutSetterEPNS_10RegisterIDERKNS_10IdentifierES2_
-__ZN3JSC18ConstStatementNodeD1Ev
-__ZN3JSC18ConstStatementNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC13ConstDeclNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC11Interpreter17cti_op_put_getterEPvz
-__ZN3JSC11Interpreter17cti_op_put_setterEPvz
+__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
+_JSStringRelease
 __ZN3JSC16JSCallbackObjectINS_8JSObjectEE18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC7UString3Rep13createCopyingEPKti
 __ZN3JSC16JSCallbackObjectINS_8JSObjectEE20staticFunctionGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
 __ZN3JSC18JSCallbackFunctionC1EPNS_9ExecStateEPFPK13OpaqueJSValuePK15OpaqueJSContextPS3_S9_mPKS5_PS5_ERKNS_10IdentifierE
 __ZN3JSC18JSCallbackFunction11getCallDataERNS_8CallDataE
-__ZN3JSC18JSCallbackFunction4callEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSC18JSCallbackFunction4callEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE
-JSValueIsObjectOfClass
-__ZN3JSC6JSCell9getObjectEv
+_JSObjectGetPrivate
 __ZNK3JSC16JSCallbackObjectINS_8JSObjectEE9classInfoEv
-JSObjectGetPrivate
-JSValueMakeString
+_JSValueMakeUndefined
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE17staticValueGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN14OpaqueJSString6createERKN3JSC7UStringE
+_JSStringCreateWithCharacters
+_JSValueMakeString
 __ZNK14OpaqueJSString7ustringEv
-JSValueMakeBoolean
-JSContextGetGlobalObject
-JSStringCreateWithUTF8CString
-JSObjectGetProperty
-JSValueToObject
-JSObjectIsFunction
-JSObjectCallAsFunction
-JSValueMakeUndefined
-__ZN3JSC18JSCallbackFunctionD0Ev
-__ZN3JSC16JSCallbackObjectINS_8JSObjectEED0Ev
+__ZN3JSC7UStringC1EPtib
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEED1Ev
+_JSClassRelease
 __ZL25clearReferenceToPrototypeP13OpaqueJSValue
-JSClassRelease
-__ZN3JSC15AssignErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+_JSObjectGetProperty
+_JSValueToObject
+__ZN3JSCL22dateProtoFuncGetUTCDayEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncGetUTCMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23dateProtoFuncGetUTCDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL27dateProtoFuncGetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7UString8toUInt32EPb
+__ZN3JSCL24dateProtoFuncGetUTCHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL26dateProtoFuncGetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL26dateProtoFuncGetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL7dateUTCEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12RegExpObject11getCallDataERNS_8CallDataE
+__ZN3JSC9Arguments14deletePropertyEPNS_9ExecStateEj
+_JSValueMakeBoolean
+_JSValueToNumber
+_JSStringCreateWithCFString
+__ZN3WTF13tryFastCallocEmm
+_JSValueMakeNumber
+__ZN3JSC18JSCallbackFunctionD1Ev
+_JSValueToStringCopy
+_JSStringCopyCFString
+__ZN3JSC18ConstStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13ConstDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13ConstDeclNode14emitCodeSingleERNS_17BytecodeGeneratorE
+__ZN3JSC13ConstDeclNodeD0Ev
+__ZN3JSC18ConstStatementNodeD0Ev
+__ZN3JSC18BooleanConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL31constructWithBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC16constructBooleanEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSCL31dateProtoFuncGetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL28dateProtoFuncGetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL31dateProtoFuncToLocaleTimeStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21regExpObjectLastIndexEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC21DebuggerStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC21DebuggerStatementNodeD0Ev
+__ZN3JSC4Yarr12RegexPattern21newlineCharacterClassEv
+__ZN3JSC17ObjectConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL23dateProtoFuncSetUTCDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL26stringFromCharCodeSlowCaseEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSCL21callObjectConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL27objectProtoFuncDefineGetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
+__ZN3JSC12GetterSetter4markEv
+__ZN3JSC12GetterSetterD1Ev
+__ZN3JSCL22regExpProtoFuncCompileEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC17NumberConstructor9classInfoEv
+__ZNK3JSC17RegExpConstructor9classInfoEv
+__ZN3JSCL31dateProtoFuncToLocaleDateStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSObject14isGlobalObjectEv
+_JSValueToBoolean
+__ZN3JSC8JITStubs13cti_op_lshiftEPPv
+__ZN3JSC8JITStubs13cti_op_bitnotEPPv
+__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC19FunctionConstructor11getCallDataERNS_8CallDataE
+__ZN3WTF9ByteArray6createEm
+__ZNK3JSC6JSCell9getStringERNS_7UStringE
+__ZN3JSC3JIT12emit_op_loopEPNS_11InstructionE
+__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
+__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
+__ZN3JSC11JSByteArrayC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
+__ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC11JSByteArray3putEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC11JSByteArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC8JITStubs28cti_op_get_by_val_byte_arrayEPPv
+__ZN3JSC8JITStubs28cti_op_put_by_val_byte_arrayEPPv
+__ZL30makeGetterOrSetterPropertyNodePvRKN3JSC10IdentifierES3_PNS0_13ParameterNodeEPNS0_16FunctionBodyNodeERKNS0_10SourceCodeE
+__ZN3JSC17BytecodeGenerator13emitPutGetterEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC17BytecodeGenerator13emitPutSetterEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC3JIT18emit_op_put_getterEPNS_11InstructionE
+__ZN3JSC3JIT18emit_op_put_setterEPNS_11InstructionE
+__ZN3JSC8JITStubs17cti_op_put_getterEPPv
+__ZN3JSC8JITStubs17cti_op_put_setterEPPv
+__ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_
+__ZNK3JSC12GetterSetter14isGetterSetterEv
+__ZNK3JSC6JSCell14isGetterSetterEv
+__ZN3JSCL29regExpConstructorRightContextEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSC5Lexer19copyCodeWithoutBOMsEv
+__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE
+__ZN3JSC26createNotAConstructorErrorEPNS_9ExecStateENS_7JSValueEjPNS_9CodeBlockE
+__ZN3JSC15isStrWhiteSpaceEt
+__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
+__ZNK3JSC22NativeErrorConstructor9classInfoEv
+__ZNK3JSC16JSCallbackObjectINS_8JSObjectEE9classNameEv
+__ZN3JSC4Heap11objectCountEv
+__ZNK3JSC12SmallStrings5countEv
+__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
+__ZN3JSCL27objectProtoFuncLookupGetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSCL27objectProtoFuncDefineSetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
+__ZN3JSC9Structure22getterSetterTransitionEPS0_
+__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_7JSValueE
+__ZN3JSC12PropertySlot14functionGetterEPNS_9ExecStateERKNS_10IdentifierERKS0_
+__ZN3JSCL28objectProtoFuncIsPrototypeOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringE
+__ZNK3JSC7UString6is8BitEv
+__ZN3JSC8JSObject15unwrappedObjectEv
+__ZN3JSC22NativeErrorConstructor11getCallDataERNS_8CallDataE
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE11getCallDataERNS_8CallDataE
+__ZN3JSC17BytecodeGenerator21emitComplexJumpScopesEPNS_5LabelEPNS_18ControlFlowContextES4_
 __ZN3JSC23ThrowableExpressionData14emitThrowErrorERNS_17BytecodeGeneratorENS_9ErrorTypeEPKc
-__ZN3JSC17BytecodeGenerator12emitNewErrorEPNS_10RegisterIDENS_9ErrorTypeENS_10JSValuePtrE
-__ZN3JSC15AssignErrorNodeD1Ev
-__ZN3JSC15AssignErrorNode12releaseNodesERNS_12NodeReleaserE
+__ZN3JSC17BytecodeGenerator12emitNewErrorEPNS_10RegisterIDENS_9ErrorTypeENS_7JSValueE
+__ZN3JSC3JIT17emit_op_new_errorEPNS_11InstructionE
+__ZN3JSC23MacroAssemblerX86Common8branch16ENS0_9ConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE9BaseIndexENS4_5Imm32E
+_JSStringRetain
+__ZN3JSCL19arrayProtoFuncEveryEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL20arrayProtoFuncReduceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL25arrayProtoFuncReduceRightEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL28arrayProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL25arrayProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC15AssignErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC8JITStubs16cti_op_new_errorEPPv
+__ZN3JSC15AssignErrorNodeD0Ev
+__ZN3JSC17BytecodeGenerator18emitUnexpectedLoadEPNS_10RegisterIDEd
+__ZN3JSC19JSStaticScopeObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC9ExecState9dateTableEPS0_
+__ZNK3JSC15RegExpPrototype9classInfoEv
 __ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC12StringObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
-__ZN3JSC9ExecState11stringTableEPS0_
-__ZN3JSCL24dateProtoFuncSetUTCHoursEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN14OpaqueJSString6createERKN3JSC7UStringE
-JSStringIsEqualToUTF8CString
-__ZN3JSC16JSCallbackObjectINS_8JSObjectEE14callbackGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-JSValueToStringCopy
-JSStringCopyCFString
-JSValueMakeNumber
-__ZN3JSC16JSCallbackObjectINS_8JSObjectEE3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-JSValueToNumber
-JSObjectSetPrivate
-__ZN3JSC8Profiler8profilerEv
-__ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
-__ZN3JSC8JSObject15unwrappedObjectEv
-JSStringCreateWithCharacters
-__ZN3JSC9Structure18startIgnoringLeaksEv
-__ZN3JSC9Structure17stopIgnoringLeaksEv
-JSValueProtect
-JSObjectCallAsConstructor
-__ZN3JSC10JSFunction16getConstructDataERNS_13ConstructDataE
-__ZN3JSC9constructEPNS_9ExecStateENS_10JSValuePtrENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
-__ZN3JSC10JSFunction9constructEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSCL28stringProtoFuncLocaleCompareEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
+__ZN3JSCL25dateProtoFuncToDateStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL25dateProtoFuncToTimeStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL25numberConstructorNaNValueEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL31dateProtoFuncSetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL26dateProtoFuncSetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL26dateProtoFuncSetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncSetUTCMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23throwStackOverflowErrorEPNS_9ExecStateEPNS_12JSGlobalDataEPvRS4_
+__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
+__ZN3JSC15DeleteValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15DeleteValueNodeD0Ev
+__ZN3JSC16PostfixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15PrefixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC16PostfixErrorNodeD0Ev
+__ZN3JSC15PrefixErrorNodeD0Ev
+__ZN3JSC23createInvalidParamErrorEPNS_9ExecStateEPKcNS_7JSValueEjPNS_9CodeBlockE
+__ZNK3JSC15DotAccessorNode17isDotAccessorNodeEv
+__ZNK3JSC14ExpressionNode17isDotAccessorNodeEv
+__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC4Heap24setGCProtectNeedsLockingEv
+__ZN3JSCL23callFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC16JSCallbackObjectINS_8JSObjectEE8toStringEPNS_9ExecStateE
+__ZN3JSC8JITStubs17cti_op_instanceofEPPv
+__ZN3JSC17BytecodeGenerator35emitThrowExpressionTooDeepExceptionEv
+__ZN3JSCL25numberConstructorMinValueEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL17mathProtoFuncACosEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18mathProtoFuncATan2EPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncTanEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL28numberProtoFuncToExponentialEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL26numberProtoFuncToPrecisionEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL12charSequenceEci
+__ZN3JSCL29objectProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
+__ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
+__ZN3JSCL27objectProtoFuncLookupSetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
+__ZNK3JSC16JSVariableObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
+__ZN3JSC9ExecState22regExpConstructorTableEPS0_
+__ZN3JSCL24regExpConstructorDollar7EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar8EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar9EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL22regExpConstructorInputEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL25setRegExpConstructorInputEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
+__ZN3JSCL26regExpConstructorLastMatchEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL26regExpConstructorLastParenEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL26regExpConstructorMultilineEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL29setRegExpConstructorMultilineEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
+__ZN3JSC4Yarr15nondigitsCreateEv
+__ZNK3JSC19JSStaticScopeObject12toThisObjectEPNS_9ExecStateE
+__ZN3JSC12JSActivation18getArgumentsGetterEv
+__ZN3JSC12JSActivation15argumentsGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL23booleanProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL28stringProtoFuncLocaleCompareEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3WTF8Collator11userDefaultEv
 __ZNK3WTF8Collator7collateEPKtmS2_m
 __ZNK3WTF8Collator14createCollatorEv
 __ZN3WTF8CollatorD1Ev
 __ZN3WTF8Collator15releaseCollatorEv
-__ZNK3JSC22NativeErrorConstructor9classInfoEv
-JSValueUnprotect
-JSValueIsNumber
-__ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
-__ZN3WTF7HashSetIPN3JSC14JSGlobalObjectENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
-__ZN3WTF9HashTableIPN3JSC14JSGlobalObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3JSC4Heap14primaryHeapEndEv
-__ZN3JSC4Heap16primaryHeapBeginEv
-__ZNK3JSC15RegExpPrototype9classInfoEv
-__ZNK3JSC17NumberConstructor9classInfoEv
-__ZNK3JSC17RegExpConstructor9classInfoEv
 __ZNK3JSC10MathObject9classInfoEv
-__ZNK3JSC18JSCallbackFunction9classInfoEv
-JSValueIsString
-JSStringGetLength
-JSStringGetCharactersPtr
-__ZN3JSC11Interpreter12cti_op_debugEPvz
-__ZN3JSC11Interpreter5debugEPNS_9ExecStateENS_11DebugHookIDEii
-__ZNK3JSC17DebuggerCallFrame4typeEv
-__ZNK3JSC17DebuggerCallFrame12functionNameEv
-__ZNK3JSC17DebuggerCallFrame10thisObjectEv
-__ZN3WTF28setMainThreadCallbacksPausedEb
-__ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
-__ZN3WTF9HashTableIPN3JSC14JSGlobalObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
+__ZN3JSC9ExecState9mathTableEPS0_
 __ZN3WTF6VectorIN3JSC20FunctionRegisterInfoELm0EE14expandCapacityEm
+__ZN3JSC3JIT25emit_op_profile_will_callEPNS_11InstructionE
+__ZN3JSC3JIT24emit_op_profile_did_callEPNS_11InstructionE
+__ZN3JSC8Profiler8profilerEv
 __ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC16ProfileGenerator6createERKNS_7UStringEPNS_9ExecStateEj
 __ZN3JSC16ProfileGeneratorC2ERKNS_7UStringEPNS_9ExecStateEj
 __ZN3JSC7Profile6createERKNS_7UStringEj
-__ZN3JSC11TreeProfile6createERKNS_7UStringEj
 __ZN3JSC7ProfileC2ERKNS_7UStringEj
 __ZN3JSC11ProfileNodeC1ERKNS_14CallIdentifierEPS0_S4_
 __ZN3JSC33getCurrentUTCTimeWithMicrosecondsEv
 __ZN3JSC16ProfileGenerator24addParentForConsoleStartEPNS_9ExecStateE
-__ZN3JSC8Profiler20createCallIdentifierEPNS_12JSGlobalDataENS_10JSValuePtrERKNS_7UStringEi
+__ZN3JSC8Profiler20createCallIdentifierEPNS_12JSGlobalDataENS_7JSValueERKNS_7UStringEi
+__ZN3JSC16InternalFunction21calculatedDisplayNameEPNS_12JSGlobalDataE
 __ZN3JSC11ProfileNode10insertNodeEN3WTF10PassRefPtrIS0_EE
+__ZN3WTF6VectorINS_6RefPtrIN3JSC11ProfileNodeEEELm0EE14expandCapacityEm
 __ZN3WTF6VectorINS_6RefPtrIN3JSC16ProfileGeneratorEEELm0EE14expandCapacityEm
-__ZN3WTF10RefCountedIN3JSC16ProfileGeneratorEE5derefEv
-__ZN3JSC8Profiler11willExecuteEPNS_9ExecStateENS_10JSValuePtrE
-__ZN3JSC8Profiler10didExecuteEPNS_9ExecStateENS_10JSValuePtrE
-__ZN3JSC16ProfileGenerator11willExecuteERKNS_14CallIdentifierE
-__ZN3JSC11ProfileNode11willExecuteERKNS_14CallIdentifierE
-__ZN3JSC11Interpreter24cti_op_profile_will_callEPvz
-__ZN3JSC11Interpreter23cti_op_profile_did_callEPvz
+__ZN3JSC8JITStubs23cti_op_profile_did_callEPPv
+__ZN3JSC8Profiler10didExecuteEPNS_9ExecStateENS_7JSValueE
 __ZN3JSC16ProfileGenerator10didExecuteERKNS_14CallIdentifierE
 __ZN3JSC11ProfileNode10didExecuteEv
-__ZN3JSCL28numberProtoFuncToExponentialEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL26numberProtoFuncToPrecisionEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter16cti_op_new_errorEPvz
-__ZN3JSC19JSStaticScopeObject3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC4WREC14CharacterClass11nonwordcharEv
-__ZN3JSC19FunctionConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL23callFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC17ObjectConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callObjectConstructorEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC12JSActivation14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSCL26dateProtoFuncSetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL26dateProtoFuncSetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC15PrefixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC15PrefixErrorNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC15PrefixErrorNodeD1Ev
-__ZN3JSCL19stringProtoFuncBoldEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm512EEELm32EE15reserveCapacityEm
-__ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringE
-__ZN3JSCL24regExpConstructorDollar5EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
-__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-JSValueIsEqual
-__ZN3JSC10JSValuePtr13equalSlowCaseEPNS_9ExecStateES0_S0_
-__ZN3JSCL16mathProtoFuncTanEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC11Interpreter15cti_op_post_decEPvz
-__ZN3JSCL28regExpConstructorLeftContextEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL31dateProtoFuncToLocaleDateStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC21DebuggerStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC21DebuggerStatementNodeD1Ev
-__ZN3JSCL12charSequenceEci
-__ZN3JSCL17mathProtoFuncACosEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC4Heap24setGCProtectNeedsLockingEv
-__ZNK3JSC7UString6is8BitEv
-__ZN3WTF9ByteArray6createEm
-__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
-__ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC11Interpreter28cti_op_get_by_val_byte_arrayEPvz
-__ZN3JSC11JSByteArray3putEPNS_9ExecStateEjNS_10JSValuePtrE
-__ZN3JSC11JSByteArray3putEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrERNS_15PutPropertySlotE
-__ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC11Interpreter28cti_op_put_by_val_byte_arrayEPvz
-__ZN3JSCL28objectProtoFuncIsPrototypeOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
-__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectE
-__ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL25numberConstructorNaNValueEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL23throwStackOverflowErrorEPNS_9ExecStateEPNS_12JSGlobalDataEPvRS4_
-__ZN3JSCL24regExpConstructorDollar6EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar7EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC9ExecState9mathTableEPS0_
-__ZN3JSC9ExecState22regExpConstructorTableEPS0_
-__ZN3JSCL24regExpConstructorDollar8EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar9EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL22regExpConstructorInputEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL25setRegExpConstructorInputEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrE
-__ZN3JSCL26regExpConstructorLastMatchEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL26regExpConstructorLastParenEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL26regExpConstructorMultilineEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL29setRegExpConstructorMultilineEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrE
-__ZN3JSCL29regExpConstructorRightContextEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC16PostfixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC16PostfixErrorNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC16PostfixErrorNodeD1Ev
-__ZN3JSC6JSCell11getJSNumberEv
-__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_10JSValuePtrEj
-__ZN3JSCL25arrayProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL25numberConstructorMinValueEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL22regExpProtoFuncCompileEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL19arrayProtoFuncEveryEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL29objectProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
-__ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
-__ZN3JSCL31dateProtoFuncSetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL24dateProtoFuncSetUTCMonthEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL28arrayProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC12JSActivation18getArgumentsGetterEv
-__ZN3JSC12JSActivation15argumentsGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC9ExecState9dateTableEPS0_
-__ZN3JSC23createInvalidParamErrorEPNS_9ExecStateEPKcNS_10JSValuePtrEjPNS_9CodeBlockE
-__ZNK3JSC15DotAccessorNode17isDotAccessorNodeEv
-__ZNK3JSC14ExpressionNode17isDotAccessorNodeEv
-__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateEjNS_10JSValuePtrE
-__ZN3JSC15DeleteValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC15DeleteValueNodeD1Ev
-__ZN3JSC15DeleteValueNode12releaseNodesERNS_12NodeReleaserE
-__ZN3JSC17BytecodeGenerator18emitUnexpectedLoadEPNS_10RegisterIDEd
-__ZN3JSC4WREC14CharacterClass9nondigitsEv
-__ZNK3JSC19JSStaticScopeObject12toThisObjectEPNS_9ExecStateE
-__ZNK3JSC16JSVariableObject21getPropertyAttributesEPNS_9ExecStateERKNS_10IdentifierERj
-__ZN3JSCL25dateProtoFuncToDateStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSCL25dateProtoFuncToTimeStringEPNS_9ExecStateEPNS_8JSObjectENS_10JSValuePtrERKNS_7ArgListE
-__ZN3JSC17BytecodeGenerator35emitThrowExpressionTooDeepExceptionEv
-__ZN3JSC12JSGlobalData6createEv
-__ZN3WTF12isMainThreadEv
-__ZN3JSC4Heap7destroyEv
-__ZN3JSC12JSGlobalDataD1Ev
-__ZN3JSC11InterpreterD1Ev
-__ZN3JSC12RegisterFileD1Ev
-__ZNK3JSC9HashTable11deleteTableEv
-__ZN3JSC5LexerD1Ev
-__ZN3WTF20deleteAllPairSecondsIP24OpaqueJSClassContextDataKNS_7HashMapIP13OpaqueJSClassS2_NS_7PtrHashIS5_EENS_10HashTraitsIS5_EENS8_IS2_EEEEEEvRT0_
-__ZN3JSC17CommonIdentifiersD2Ev
-__ZN3JSC21deleteIdentifierTableEPNS_15IdentifierTableE
-__ZN3JSC4HeapD1Ev
-__ZN3JSC12SmallStringsD1Ev
+__ZN3JSC8JITStubs24cti_op_profile_will_callEPPv
+__ZN3JSC8Profiler11willExecuteEPNS_9ExecStateENS_7JSValueE
+__ZN3JSC16ProfileGenerator11willExecuteERKNS_14CallIdentifierE
+__ZN3JSC11ProfileNode11willExecuteERKNS_14CallIdentifierE
+__ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
+__ZN3JSC16ProfileGenerator13stopProfilingEv
+__ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE
+__ZNK3JSC11ProfileNode25traverseNextNodePostOrderEv
+__ZN3JSC11ProfileNode13stopProfilingEv
+__ZN3JSCeqERKNS_7UStringEPKc
+__ZN3JSC11ProfileNode11removeChildEPS0_
+__ZN3JSC11ProfileNode8addChildEN3WTF10PassRefPtrIS0_EE
+_JSValueIsObjectOfClass
+_JSObjectCallAsConstructor
+__ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
+_JSObjectCallAsFunction
+__ZN3JSC4Heap14primaryHeapEndEv
+__ZN3JSC4Heap16primaryHeapBeginEv
+__ZNK3JSC18JSCallbackFunction9classInfoEv
+__ZN3JSC8Profiler11willExecuteEPNS_9ExecStateERKNS_7UStringEi
+__ZN3JSC8Profiler10didExecuteEPNS_9ExecStateERKNS_7UStringEi
+__ZNK3JSC16ProfileGenerator5titleEv
+__ZN3JSC7ProfileD0Ev
+__ZN3WTF10RefCountedIN3JSC11ProfileNodeEE5derefEv
+__ZN3JSC4Yarr14RegexGenerator33generatePatternCharacterNonGreedyERNS1_19TermGenerationStateE
+__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
+__ZNK3JSC25InterruptedExecutionError19isWatchdogExceptionEv
+__ZN3JSC25InterruptedExecutionErrorD1Ev
 __ZN3JSC12JSGlobalData10ClientDataD2Ev
+__ZN3JSC18RegExpMatchesArray16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
 __ZN3WTF8CollatorC1EPKc
 __ZN3WTF8Collator18setOrderLowerFirstEb
-__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
-__ZNK3JSC25InterruptedExecutionError19isWatchdogExceptionEv
+__ZN3WTF12randomNumberEv
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZNK3JSC6JSCell9getStringEv
+__ZNK3JSC12DateInstance7getTimeERdRi
+__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringE
+_JSGlobalContextCreate
+_JSGlobalContextCreateInGroup
+__ZN3JSC4Heap29makeUsableFromMultipleThreadsEv
+_JSGlobalContextRetain
+__ZN3JSC6JSLock6unlockEb
+_JSEvaluateScript
+__ZNK3JSC14JSGlobalObject17supportsProfilingEv
+_JSGlobalContextRelease
+__ZN3JSC14JSGlobalObjectD1Ev
+__ZN3JSC14JSGlobalObject18JSGlobalObjectDataD0Ev
+__ZN3JSC17FunctionPrototype11getCallDataERNS_8CallDataE
+__ZN3JSC15DateConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL8callDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC13JSNotAnObject4markEv
+_JSObjectIsFunction
+__ZN3JSC4Heap17globalObjectCountEv
+__ZN3JSC4Heap20protectedObjectCountEv
+__ZN3JSC4Heap25protectedObjectTypeCountsEv
+__ZN3WTF9HashTableIPKcSt4pairIS2_jENS_18PairFirstExtractorIS4_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSA_I
+__ZN3WTF20fastMallocStatisticsEv
+__ZNK3JSC4Heap10statisticsEv
+__ZN3WTF27releaseFastMallocFreeMemoryEv
+__ZN3JSC10JSFunction16getConstructDataERNS_13ConstructDataE
+__ZN3JSC10JSFunction9constructEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
+__ZN3WTF7HashSetIPN3JSC14JSGlobalObjectENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC14JSGlobalObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3JSC3JIT13emit_op_debugEPNS_11InstructionE
+__ZN3JSC8JITStubs12cti_op_debugEPPv
+__ZN3JSC11Interpreter5debugEPNS_9ExecStateENS_11DebugHookIDEii
+__ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
+__ZN3JSC9CodeBlock33functionRegisterForBytecodeOffsetEjRi
+_JSStringIsEqualToUTF8CString
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE14callbackGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+_JSObjectSetPrivate
+__ZN3JSC7UString3Rep11computeHashEPKci
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+_JSGarbageCollect
+__ZN3JSC4Heap6isBusyEv
+__ZN3JSCL18styleFromArgStringERKNS_7UStringEl
index 6aee0aa56018e4d4a67b3a10d0f5782c82bd9b72..91a8ce08b9c34d34b503674803e762744cff6379 100644 (file)
@@ -1,36 +1,75 @@
 # JavaScriptCore - Qt4 build info
 VPATH += $$PWD
 
-INCLUDEPATH += tmp
-INCLUDEPATH += $$PWD $$PWD/parser $$PWD/bytecompiler $$PWD/debugger $$PWD/runtime $$PWD/wtf $$PWD/wtf/unicode $$PWD/interpreter $$PWD/jit $$PWD/profiler $$PWD/wrec $$PWD/API $$PWD/.. \
-               $$PWD/ForwardingHeaders $$PWD/bytecode $$PWD/assembler
-DEFINES += BUILDING_QT__
+CONFIG(debug, debug|release) {
+    isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = generated$${QMAKE_DIR_SEP}debug
+    OBJECTS_DIR = obj/debug
+} else { # Release
+    isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = generated$${QMAKE_DIR_SEP}release
+    OBJECTS_DIR = obj/release
+}
+
+INCLUDEPATH += $$GENERATED_SOURCES_DIR \
+               $$PWD \
+               $$PWD/parser \
+               $$PWD/bytecompiler \
+               $$PWD/debugger \
+               $$PWD/runtime \
+               $$PWD/wtf \
+               $$PWD/wtf/unicode \
+               $$PWD/interpreter \
+               $$PWD/jit \
+               $$PWD/profiler \
+               $$PWD/wrec \
+               $$PWD/yarr \
+               $$PWD/API \
+               $$PWD/.. \
+               $$PWD/ForwardingHeaders \
+               $$PWD/bytecode \
+               $$PWD/assembler \
 
-isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp
-GENERATED_SOURCES_DIR_SLASH = $$GENERATED_SOURCES_DIR/
+DEFINES += BUILDING_QT__ BUILDING_JavaScriptCore BUILDING_WTF
+
+GENERATED_SOURCES_DIR_SLASH = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}
 win32-* {
-    GENERATED_SOURCES_DIR_SLASH ~= s|/|\|
     LIBS += -lwinmm
 }
 
-# Disable the JIT due to numerous observed miscompilations :(
-#CONFIG(release):isEqual(QT_ARCH,i386) {
-#     JIT_DEFINES = ENABLE_JIT ENABLE_WREC ENABLE_JIT_OPTIMIZE_CALL ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS ENABLE_JIT_OPTIMIZE_ARITHMETIC
-#     # gcc <= 4.1 is known to miscompile, so require >= 4.2, written as major > 3 and minor > 1
-#     linux-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,1) {
-#         DEFINES += $$JIT_DEFINES
-#         SOURCES += wtf/TCSystemAlloc.cpp
-#         DEFINES -= USE_SYSTEM_MALLOC
-#     }
-#     win32-msvc* {
-#         DEFINES += $$JIT_DEFINES
-#     }
-#}
+# Default rules to turn JIT on/off
+!contains(DEFINES, ENABLE_JIT=.) {
+    isEqual(QT_ARCH,i386)|isEqual(QT_ARCH,windows) {
+        # Require gcc >= 4.1
+        CONFIG(release):linux-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,0) {
+            DEFINES += ENABLE_JIT=1
+        }
+        win32-msvc* {
+            DEFINES += ENABLE_JIT=1
+        }
+    }
+}
+
+# Rules when JIT enabled
+contains(DEFINES, ENABLE_JIT=1) {
+    !contains(DEFINES, ENABLE_YARR=.): DEFINES += ENABLE_YARR=1
+    !contains(DEFINES, ENABLE_YARR_JIT=.): DEFINES += ENABLE_YARR_JIT=1
+    !contains(DEFINES, ENABLE_JIT_OPTIMIZE_CALL=.): DEFINES += ENABLE_JIT_OPTIMIZE_CALL=1
+    !contains(DEFINES, ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS=.): DEFINES += ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS=1
+    !contains(DEFINES, ENABLE_JIT_OPTIMIZE_ARITHMETIC=.): DEFINES += ENABLE_JIT_OPTIMIZE_ARITHMETIC=1
+    linux-g++* {
+        !contains(DEFINES, WTF_USE_JIT_STUB_ARGUMENT_VA_LIST=.): DEFINES += WTF_USE_JIT_STUB_ARGUMENT_VA_LIST=1
+        QMAKE_CXXFLAGS += -fno-stack-protector
+        QMAKE_CFLAGS += -fno-stack-protector
+    }
+    win32-msvc* {
+        !contains(DEFINES, WTF_USE_JIT_STUB_ARGUMENT_REGISTER=.): DEFINES += WTF_USE_JIT_STUB_ARGUMENT_REGISTER=1
+    }
+}
 
 include(pcre/pcre.pri)
 
 LUT_FILES += \
     runtime/DatePrototype.cpp \
+    runtime/JSONObject.cpp \
     runtime/NumberConstructor.cpp \
     runtime/StringPrototype.cpp \
     runtime/ArrayPrototype.cpp \
@@ -51,6 +90,7 @@ SOURCES += \
     wtf/MainThread.cpp \
     wtf/RandomNumber.cpp \
     wtf/RefCountedLeakCounter.cpp \
+    wtf/TypeTraits.cpp \
     wtf/unicode/CollatorDefault.cpp \
     wtf/unicode/icu/CollatorICU.cpp \
     wtf/unicode/UTF8.cpp \
@@ -71,26 +111,28 @@ SOURCES += \
     runtime/JSVariableObject.cpp \
     runtime/JSActivation.cpp \
     runtime/JSNotAnObject.cpp \
+    runtime/JSONObject.cpp \
+    runtime/LiteralParser.cpp \
+    runtime/TimeoutChecker.cpp \
     bytecode/CodeBlock.cpp \
     bytecode/StructureStubInfo.cpp \
     bytecode/JumpTable.cpp \
     jit/JIT.cpp \
     jit/JITCall.cpp \
     jit/JITArithmetic.cpp \
+    jit/JITOpcodes.cpp \
     jit/JITPropertyAccess.cpp \
     jit/ExecutableAllocator.cpp \
+    jit/JITStubs.cpp \
     bytecompiler/BytecodeGenerator.cpp \
     runtime/ExceptionHelpers.cpp \
     runtime/JSPropertyNameIterator.cpp \
     interpreter/Interpreter.cpp \
     bytecode/Opcode.cpp \
     bytecode/SamplingTool.cpp \
-    wrec/CharacterClass.cpp \
-    wrec/CharacterClassConstructor.cpp \
-    wrec/WREC.cpp \
-    wrec/WRECFunctors.cpp \
-    wrec/WRECGenerator.cpp \
-    wrec/WRECParser.cpp \
+    yarr/RegexCompiler.cpp \
+    yarr/RegexInterpreter.cpp \
+    yarr/RegexJIT.cpp \
     interpreter/RegisterFile.cpp
 
 win32-*: SOURCES += jit/ExecutableAllocatorWin.cpp
@@ -112,8 +154,8 @@ SOURCES += \
     runtime/ConstructData.cpp \
     wtf/CurrentTime.cpp \
     runtime/DateConstructor.cpp \
+    runtime/DateConversion.cpp \
     runtime/DateInstance.cpp \
-    runtime/DateMath.cpp \
     runtime/DatePrototype.cpp \
     debugger/Debugger.cpp \
     debugger/DebuggerCallFrame.cpp \
@@ -132,6 +174,7 @@ SOURCES += \
     runtime/InternalFunction.cpp \
     runtime/Completion.cpp \
     runtime/JSArray.cpp \
+    runtime/JSAPIValueWrapper.cpp \
     runtime/JSByteArray.cpp \
     runtime/JSCell.cpp \
     runtime/JSFunction.cpp \
@@ -156,6 +199,7 @@ SOURCES += \
     runtime/ObjectPrototype.cpp \
     runtime/Operations.cpp \
     parser/Parser.cpp \
+    parser/ParserArena.cpp \
     runtime/PropertyNameArray.cpp \
     runtime/PropertySlot.cpp \
     runtime/PrototypeFunction.cpp \
@@ -177,13 +221,20 @@ SOURCES += \
     profiler/ProfileNode.cpp \
     profiler/Profiler.cpp \
     profiler/TreeProfile.cpp \
+    wtf/DateMath.cpp \
     wtf/FastMalloc.cpp \
     wtf/Threading.cpp \
-    wtf/ThreadingQt.cpp \
     wtf/qt/MainThreadQt.cpp
 
+!contains(DEFINES, ENABLE_SINGLE_THREADED=1) {
+    SOURCES += wtf/qt/ThreadingQt.cpp
+} else {
+    DEFINES += ENABLE_JSC_MULTIPLE_THREADS=0
+    SOURCES += wtf/ThreadingNone.cpp
+}
+
 # GENERATOR 1-A: LUT creator
-lut.output = $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.lut.h
+lut.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.lut.h
 lut.commands = perl $$PWD/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
 lut.depend = ${QMAKE_FILE_NAME}
 lut.input = LUT_FILES
@@ -191,7 +242,7 @@ lut.CONFIG += no_link
 addExtraCompiler(lut)
 
 # GENERATOR 1-B: particular LUT creator (for 1 file only)
-keywordlut.output = $$GENERATED_SOURCES_DIR/Lexer.lut.h
+keywordlut.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Lexer.lut.h
 keywordlut.commands = perl $$PWD/create_hash_table ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
 keywordlut.depend = ${QMAKE_FILE_NAME}
 keywordlut.input = KEYWORDLUT_FILES
@@ -199,8 +250,8 @@ keywordlut.CONFIG += no_link
 addExtraCompiler(keywordlut)
 
 # GENERATOR 2: bison grammar
-jscbison.output = $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.cpp
-jscbison.commands = bison -d -p jscyy ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_BASE}.tab.c && $(MOVE) ${QMAKE_FILE_BASE}.tab.c ${QMAKE_FILE_OUT} && $(MOVE) ${QMAKE_FILE_BASE}.tab.h $$GENERATED_SOURCES_DIR/${QMAKE_FILE_BASE}.h
+jscbison.output = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.cpp
+jscbison.commands = bison -d -p jscyy ${QMAKE_FILE_NAME} -o $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c && $(MOVE) $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.c ${QMAKE_FILE_OUT} && $(MOVE) $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.tab.h $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}${QMAKE_FILE_BASE}.h
 jscbison.depend = ${QMAKE_FILE_NAME}
 jscbison.input = JSCBISON
 jscbison.variable_out = GENERATED_SOURCES
index 56dae058e66a94fd5a05ac6e6fde45d9233b396c..28f0e6bc45e22c64d0bcda7f4dd1f95e0a89053e 100644 (file)
@@ -21,13 +21,16 @@ CONFIG(QTDIR_build) {
 }
 
 isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp
-GENERATED_SOURCES_DIR_SLASH = $$GENERATED_SOURCES_DIR/
-win32-*: GENERATED_SOURCES_DIR_SLASH ~= s|/|\|
+GENERATED_SOURCES_DIR_SLASH = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}
 
 INCLUDEPATH += $$GENERATED_SOURCES_DIR
 
 !CONFIG(QTDIR_build) {
-     OBJECTS_DIR = tmp
+    CONFIG(debug, debug|release) {
+        OBJECTS_DIR = obj/debug
+    } else { # Release
+        OBJECTS_DIR = obj/release
+    }
 }
 
 include($$OUTPUT_DIR/config.pri)
@@ -64,7 +67,7 @@ include(JavaScriptCore.pri)
 
 QMAKE_EXTRA_TARGETS += generated_files
 
-qt-port: lessThan(QT_MINOR_VERSION, 4) {
+lessThan(QT_MINOR_VERSION, 4) {
     DEFINES += QT_BEGIN_NAMESPACE="" QT_END_NAMESPACE=""
 }
 
diff --git a/JavaScriptCore.scons b/JavaScriptCore.scons
deleted file mode 100644 (file)
index 24e5003..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-# The keys in sources are the paths to the directories
-# the values are an array of source files in those directories to compile
-sources = {}
-sources['API'] = [
-    'API/JSBase.cpp',
-    'API/JSCallbackConstructor.cpp',
-    'API/JSCallbackFunction.cpp',
-    'API/JSCallbackObject.cpp',
-    'API/JSClassRef.cpp',
-    'API/JSContextRef.cpp',
-    'API/JSObjectRef.cpp',
-    'API/JSProfilerPrivate.cpp',
-    'API/JSStringRef.cpp',
-    'API/JSValueRef.cpp',
-    'API/OpaqueJSString.cpp',
-]
-sources['bytecompiler'] = [
-    'bytecompiler/BytecodeGenerator.cpp',
-]
-sources['debugger'] = [
-    'debugger/Debugger.cpp',
-    'debugger/DebuggerActivation.cpp',
-    'debugger/DebuggerCallFrame.cpp',
-]
-sources['parser'] = [
-    'parser/Lexer.cpp',
-    'parser/Nodes.cpp',
-    'parser/Parser.cpp',
-]
-sources['pcre'] = [
-    'pcre/pcre_compile.cpp',
-    'pcre/pcre_exec.cpp',
-    'pcre/pcre_tables.cpp',
-    'pcre/pcre_ucp_searchfuncs.cpp',
-    'pcre/pcre_xclass.cpp',
-]
-sources['profiler'] = [
-    'profiler/HeavyProfile.cpp',
-    'profiler/Profile.cpp',
-    'profiler/ProfileGenerator.cpp',
-    'profiler/ProfileNode.cpp',
-    'profiler/Profiler.cpp',
-    'profiler/TreeProfile.cpp',
-]
-sources['runtime'] = [
-    'runtime/ArgList.cpp',
-    'runtime/Arguments.cpp',
-    'runtime/ArrayConstructor.cpp',
-    'runtime/ArrayPrototype.cpp',
-    'runtime/BooleanConstructor.cpp',
-    'runtime/BooleanObject.cpp',
-    'runtime/BooleanPrototype.cpp',
-    'runtime/CallData.cpp',
-    'runtime/Collector.cpp',
-    'runtime/Completion.cpp',
-    'runtime/CommonIdentifiers.cpp',
-    'runtime/ConstructData.cpp',
-    'runtime/DateConstructor.cpp',
-    'runtime/DateInstance.cpp',
-    'runtime/DateMath.cpp',
-    'runtime/DatePrototype.cpp',
-    'runtime/Error.cpp',
-    'runtime/ErrorConstructor.cpp',
-    'runtime/ErrorInstance.cpp',
-    'runtime/ErrorPrototype.cpp',
-    'runtime/ExceptionHelpers.cpp',
-    'runtime/FunctionConstructor.cpp',
-    'runtime/FunctionPrototype.cpp',
-    'runtime/GetterSetter.cpp',
-    'runtime/GlobalEvalFunction.cpp',
-    'runtime/Identifier.cpp',
-    'runtime/InitializeThreading.cpp',
-    'runtime/InternalFunction.cpp',
-    'runtime/JSActivation.cpp',
-    'runtime/JSArray.cpp',
-    'runtime/JSByteArray.cpp',
-    'runtime/JSCell.cpp',
-    'runtime/JSFunction.cpp',
-    'runtime/JSGlobalData.cpp',
-    'runtime/JSGlobalObject.cpp',
-    'runtime/JSGlobalObjectFunctions.cpp',
-    'runtime/JSImmediate.cpp',
-    'runtime/JSLock.cpp',
-    'runtime/JSNotAnObject.cpp',
-    'runtime/JSNumberCell.cpp',
-    'runtime/JSObject.cpp',
-    'runtime/JSPropertyNameIterator.cpp',
-    'runtime/JSStaticScopeObject.cpp',
-    'runtime/JSString.cpp',
-    'runtime/JSValue.cpp',
-    'runtime/JSVariableObject.cpp',
-    'runtime/JSWrapperObject.cpp',
-    'runtime/Lookup.cpp',
-    'runtime/MathObject.cpp',
-    'runtime/NativeErrorConstructor.cpp',
-    'runtime/NativeErrorPrototype.cpp',
-    'runtime/NumberConstructor.cpp',
-    'runtime/NumberObject.cpp',
-    'runtime/NumberPrototype.cpp',
-    'runtime/ObjectConstructor.cpp',
-    'runtime/ObjectPrototype.cpp',
-    'runtime/Operations.cpp',
-    'runtime/PropertyNameArray.cpp',
-    'runtime/PropertySlot.cpp',
-    'runtime/PrototypeFunction.cpp',
-    'runtime/RegExp.cpp',
-    'runtime/RegExpConstructor.cpp',
-    'runtime/RegExpObject.cpp',
-    'runtime/RegExpPrototype.cpp',
-    'runtime/ScopeChain.cpp',
-    'runtime/SmallStrings.cpp',
-    'runtime/StringConstructor.cpp',
-    'runtime/StringObject.cpp',
-    'runtime/StringPrototype.cpp',
-    'runtime/Structure.cpp',
-    'runtime/StructureChain.cpp',
-    'runtime/UString.cpp',
-]
-sources['bytecode'] = [
-    'bytecode/CodeBlock.cpp',
-    'bytecode/StructureStubInfo.cpp',
-    'bytecode/JumpTable.cpp',
-    'bytecode/Opcode.cpp',
-    'bytecode/SamplingTool.cpp',
-]
-sources['interpreter'] = [
-    'interpreter/CallFrame.cpp',
-    'interpreter/Interpreter.cpp',
-    'interpreter/RegisterFile.cpp',
-]
-sources['jit'] = [
-    'jit/ExecutableAllocator.cpp',
-    'jit/JIT.cpp',
-]
-sources['wrec'] = [
-    'wrec/CharacterClass.cpp',
-    'wrec/CharacterClassConstructor.cpp',
-    'wrec/WREC.cpp',
-    'wrec/WRECFunctors.cpp',
-    'wrec/WRECGenerator.cpp',
-    'wrec/WRECParser.cpp',
-]
-sources['wtf'] = [
-    'wtf/Assertions.cpp',
-    'wtf/ByteArray.cpp',
-    'wtf/CurrentTime.cpp',
-    'wtf/FastMalloc.cpp',
-    'wtf/HashTable.cpp',
-    'wtf/RandomNumber.cpp',
-    'wtf/RefCountedLeakCounter.cpp',
-    'wtf/Threading.cpp',
-    'wtf/dtoa.cpp',
-]
-sources['wtf/unicode'] = [
-    'wtf/unicode/CollatorDefault.cpp',
-    'wtf/unicode/UTF8.cpp',
-]
-sources['wtf/unicode/icu'] = [
-    'wtf/unicode/icu/CollatorICU.cpp',
-]
-
-env = Environment()
-
-building_on_win32 = env['PLATFORM'] == 'win32' or env['PLATFORM'] == 'cygwin'
-
-# Scons uses gcc when building under cygwin by default
-# We also have to manually force 8.0 or Scons will try and
-# look up what version to use using the registry and fail
-# due to lack of cygwin-python registry support
-if env['PLATFORM'] == 'cygwin':
-    env['MSVS_VERSION'] = '8.0'
-    # Some systems have PROGRAMFILES, some have ProgramFiles
-    # Scons msvc tool only expects 'ProgramFiles'
-    import os
-    if os.getenv('PROGRAMFILES') and not os.getenv('ProgramFiles'):
-        os.environ['ProgramFiles'] = os.getenv('PROGRAMFILES')
-
-    env.Tool('msvc')
-    env.Tool('mslink')
-    env.Tool('mslib')
-
-# Scons is failing to carry the %PATH% value through correctly
-# Hack IncrediBuild into our path so cl.exe doesn't crash
-if env['PLATFORM'] == 'win32':
-    env.AppendENVPath('PATH', 'c:/Program Files/Xoreax/IncrediBuild')
-
-if env['PLATFORM'] == 'darwin':
-    sources['API'].append('API/JSStringRefCF.cpp')
-    sources['profiler'].append('profiler/ProfilerServer.mm')
-    sources['wtf'].append('wtf/ThreadingPthreads.cpp')
-    sources['wtf'].append('wtf/MainThread.cpp')
-    sources['wtf/mac'] = ['wtf/mac/MainThreadMac.mm']
-    sources['wtf'].append('wtf/TCSystemAlloc.cpp')
-    sources['jit'].append('jit/ExecutableAllocatorPosix.cpp')
-elif building_on_win32:
-    sources['wtf'].append('wtf/ThreadingNone.cpp')
-    sources['jit'].append('jit/ExecutableAllocatorWin.cpp')
-    env.Append(CPPDEFINES = ['ENABLE_JSC_MULTIPLE_THREADS=0'])
-
-derived_sources_path = 'DerivedSources/JavaScriptCore/'
-def DerivedSources(path):
-    return derived_sources_path + path
-
-derived_sources_results = map(DerivedSources, [
-    'ArrayPrototype.lut.h',
-    'DatePrototype.lut.h',
-    'MathObject.lut.h',
-    'NumberConstructor.lut.h',
-    'RegExpConstructor.lut.h',
-    'RegExpObject.lut.h',
-    'StringPrototype.lut.h'
-    'chartables.c',
-    'grammar.cpp',
-    'grammar.h',
-    'lexer.lut.h',
-])
-
-derived_sources_sources = [
-    'runtime/ArrayPrototype.cpp',
-    'runtime/DatePrototype.cpp',
-    'runtime/MathObject.cpp',
-    'runtime/NumberConstructor.cpp',
-    'runtime/RegExpConstructor.cpp',
-    'runtime/RegExpObject.cpp',
-    'runtime/StringPrototype.cpp',
-    'parser/Grammar.y',
-    'parser/Lexer.cpp',
-]
-
-# Generate DerivedSources
-# Make sure Windows knows where bash (and all the other cygwin commands) live
-if env['PLATFORM'] == 'win32':
-    env.AppendENVPath('PATH', 'C:/cygwin/bin')
-env.Command(derived_sources_results, derived_sources_sources, 'bash make-generated-sources.sh')
-sources[derived_sources_path] = [DerivedSources('Grammar.cpp')]
-
-# Handle os-version specific build settings
-if env['PLATFORM'] == 'darwin':
-    from subprocess import Popen, PIPE
-    version_pieces = Popen(["sw_vers", "-productVersion"], stdout = PIPE).communicate()[0].split('.')
-    if map(int, version_pieces)[:2] > (10, 5):
-        # Dtrace doesn't exist in Tiger, and was broken in Leopard
-        env.Command(DerivedSources('TracingDtrace.h'), 'runtime/Tracing.d', '/usr/sbin/dtrace -h -o $TARGET -s $SOURCE')
-
-# This build file builds the Chromium port for now, support for
-# others could be added later.
-env.Append(CPPDEFINES = ['BUILDING_CHROMIUM__'])
-
-# I'm not certain how many of these windows defines are actually required.
-if building_on_win32:
-    env.Append(CPPDEFINES = ['_WIN32_WINNT=0x0600', 'WINVER=0x0600', 'WIN32', '_WINDOWS', 'NOMINMAX', 'UNICODE', '_UNICODE', '__STD_C', '_HAS_EXCEPTIONS=0'])
-
-# Scons out-of-the-box only supports precompiled headers for MSVC
-# remove this when we fix Scons to understand GCC precompiled headers
-if env['CC'] == 'gcc':
-    env['CCFLAGS'] = '-include JavaScriptCorePrefix.h'
-# Turns out the MSVC PCH support is badly broken
-# env['PCH'] = 'JavaScriptCorePrefix.h'
-# env['PCHSTOP'] = 'JavaScriptCorePrefix.h'
-
-if env['PLATFORM'] == 'darwin':
-    env['FRAMEWORKS'] = ['CoreFoundation', 'Foundation']
-    env['LIBS'] = ['icucore']
-    # Apple does not ship the ICU headers with Mac OS X, so WebKit includes a copy of 3.2 headers
-    env.Append(CPPPATH = 'icu')
-
-webkit_libraries_path = "../WebKitLibraries/win/"
-def WebKitLibraries(path):
-    return webkit_libraries_path + path
-
-include_paths = ['.', '..', 'ForwardingHeaders'] + sources.keys()
-env.Append(CPPPATH = include_paths)
-if building_on_win32:
-    env.Append(CPPPATH = ['os-win32', WebKitLibraries('include')])
-    env.Prepend(LIBPATH = [WebKitLibraries('lib')])
-    env.Append(LIBS = ['icuin', 'icuuc', 'user32', 'winmm'])
-
-# Save off a copy of the environment for use with jsc
-jsc_env = env.Clone()
-
-if building_on_win32:
-    env.StaticLibrary("JavaScriptCore", sources.values())
-else:
-    env.SharedLibrary("JavaScriptCore", sources.values())
-
-
-env = jsc_env
-
-# Build the jsc testing shell
-shell_sources = ['jsc.cpp']
-build_directory = '.' # This should be changed to point to wherever JavaScriptCore gets built to
-
-# It's hacky to re-use the same environment from JavaScriptCore
-# but it makes building on windows easier for now
-env['CPPPATH'] = include_paths
-env['LIBS'] = ['JavaScriptCore']
-env['LIBPATH'] = [build_directory]
-
-if env['PLATFORM'] == 'darwin':
-    env.Append(LIBS = ['edit'])
-    env.Append(CPPPATH = 'icu')
-elif building_on_win32:
-    env.Append(CPPPATH = ['os-win32', WebKitLibraries('include')])
-    env.Prepend(LIBPATH = [WebKitLibraries('lib')])
-    env.Append(LIBS = ['icuin', 'icuuc', 'user32', 'winmm'])
-
-env.Program('jsc', shell_sources)
index e71c8a83223ae879487600782cd1446b7d384447..13b21bbbe61a53d93561979e4df818013e57c329 100644 (file)
 
 #endif
 
-#if defined(__APPLE__)
-#import <AvailabilityMacros.h>
-#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
-#define BUILDING_ON_TIGER 1
-#elif MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5
-#define BUILDING_ON_LEOPARD 1
-#endif
-#endif
-
 #ifdef __cplusplus
 #define new ("if you use new/delete make sure to include config.h at the top of the file"()) 
 #define delete ("if you use new/delete make sure to include config.h at the top of the file"()) 
index 7ba3e09397b60db636531ac0062193a3a5904977..1bdf2510a88cb2a5a8f491833e50e393a84d9838 100644 (file)
@@ -64,6 +64,7 @@ Source files for JSCore.
         parser/Lexer.cpp
         parser/Nodes.cpp
         parser/Parser.cpp
+        parser/ParserArena.cpp
     </set>
     <set append="1" var="JSCORE_PROFILER_SOURCES">
         profiler/HeavyProfile.cpp
@@ -86,8 +87,8 @@ Source files for JSCore.
         runtime/CommonIdentifiers.cpp
         runtime/ConstructData.cpp
         runtime/DateConstructor.cpp
+        runtime/DateConversion.cpp
         runtime/DateInstance.cpp
-        runtime/DateMath.cpp
         runtime/DatePrototype.cpp
         runtime/Error.cpp
         runtime/ErrorConstructor.cpp
@@ -115,12 +116,14 @@ Source files for JSCore.
         runtime/JSNotAnObject.cpp
         runtime/JSNumberCell.cpp
         runtime/JSObject.cpp
+        runtime/JSONObject.cpp
         runtime/JSPropertyNameIterator.cpp
         runtime/JSStaticScopeObject.cpp
         runtime/JSString.cpp
         runtime/JSValue.cpp
         runtime/JSVariableObject.cpp
         runtime/JSWrapperObject.cpp
+        runtime/LiteralParser.cpp
         runtime/Lookup.cpp
         runtime/MathObject.cpp
         runtime/NativeErrorConstructor.cpp
@@ -152,15 +155,24 @@ Source files for JSCore.
         bytecode/StructureStubInfo.cpp
         bytecode/JumpTable.cpp
         runtime/ExceptionHelpers.cpp
+        runtime/TimeoutChecker.cpp
         interpreter/Interpreter.cpp
         bytecode/Opcode.cpp
         bytecode/SamplingTool.cpp
         interpreter/RegisterFile.cpp
+        jit/ExecutableAllocator.cpp
+    </set>
+    <set append="1" var="JSCORE_VM_SOURCES_WIN">
+       jit/ExecutableAllocatorWin.cpp
+    </set>
+   <set append="1" var="JSCORE_VM_SOURCES_POSIX">
+       jit/ExecutableAllocatorPosix.cpp
     </set>
     <set append="1" var="JSCORE_WTF_SOURCES">
         wtf/Assertions.cpp
         wtf/ByteArray.cpp
         wtf/CurrentTime.cpp
+        wtf/DateMath.cpp
         wtf/FastMalloc.cpp
         wtf/HashTable.cpp
         wtf/MainThread.cpp
@@ -169,6 +181,7 @@ Source files for JSCore.
         wtf/TCSystemAlloc.cpp
         wtf/Threading.cpp
         wtf/ThreadingNone.cpp
+        wtf/TypeTraits.cpp
         wtf/wx/MainThreadWx.cpp
         wtf/unicode/CollatorDefault.cpp
         wtf/unicode/icu/CollatorICU.cpp
diff --git a/SConstruct b/SConstruct
deleted file mode 100644 (file)
index b77d202..0000000
+++ /dev/null
@@ -1 +0,0 @@
-SConscript(['JavaScriptCore.scons'])
diff --git a/assembler/ARMv7Assembler.h b/assembler/ARMv7Assembler.h
new file mode 100644 (file)
index 0000000..7cf8873
--- /dev/null
@@ -0,0 +1,1758 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ARMAssembler_h
+#define ARMAssembler_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER) && PLATFORM_ARM_ARCH(7)
+
+#include "AssemblerBuffer.h"
+#include <wtf/Assertions.h>
+#include <wtf/Vector.h>
+#include <stdint.h>
+
+namespace JSC {
+
+namespace ARM {
+    typedef enum {
+        r0,
+        r1,
+        r2,
+        r3,
+        r4,
+        r5,
+        r6,
+        r7, wr = r7,   // thumb work register
+        r8,
+        r9, sb = r9,   // static base
+        r10, sl = r10, // stack limit
+        r11, fp = r11, // frame pointer
+        r12, ip = r12,
+        r13, sp = r13,
+        r14, lr = r14,
+        r15, pc = r15,
+    } RegisterID;
+
+    // s0 == d0 == q0
+    // s4 == d2 == q1
+    // etc
+    typedef enum {
+        s0 = 0,
+        s1 = 1,
+        s2 = 2,
+        s3 = 3,
+        s4 = 4,
+        s5 = 5,
+        s6 = 6,
+        s7 = 7,
+        s8 = 8,
+        s9 = 9,
+        s10 = 10,
+        s11 = 11,
+        s12 = 12,
+        s13 = 13,
+        s14 = 14,
+        s15 = 15,
+        s16 = 16,
+        s17 = 17,
+        s18 = 18,
+        s19 = 19,
+        s20 = 20,
+        s21 = 21,
+        s22 = 22,
+        s23 = 23,
+        s24 = 24,
+        s25 = 25,
+        s26 = 26,
+        s27 = 27,
+        s28 = 28,
+        s29 = 29,
+        s30 = 30,
+        s31 = 31,
+        d0 = 0 << 1,
+        d1 = 1 << 1,
+        d2 = 2 << 1,
+        d3 = 3 << 1,
+        d4 = 4 << 1,
+        d5 = 5 << 1,
+        d6 = 6 << 1,
+        d7 = 7 << 1,
+        d8 = 8 << 1,
+        d9 = 9 << 1,
+        d10 = 10 << 1,
+        d11 = 11 << 1,
+        d12 = 12 << 1,
+        d13 = 13 << 1,
+        d14 = 14 << 1,
+        d15 = 15 << 1,
+        d16 = 16 << 1,
+        d17 = 17 << 1,
+        d18 = 18 << 1,
+        d19 = 19 << 1,
+        d20 = 20 << 1,
+        d21 = 21 << 1,
+        d22 = 22 << 1,
+        d23 = 23 << 1,
+        d24 = 24 << 1,
+        d25 = 25 << 1,
+        d26 = 26 << 1,
+        d27 = 27 << 1,
+        d28 = 28 << 1,
+        d29 = 29 << 1,
+        d30 = 30 << 1,
+        d31 = 31 << 1,
+        q0 = 0 << 2,
+        q1 = 1 << 2,
+        q2 = 2 << 2,
+        q3 = 3 << 2,
+        q4 = 4 << 2,
+        q5 = 5 << 2,
+        q6 = 6 << 2,
+        q7 = 7 << 2,
+        q8 = 8 << 2,
+        q9 = 9 << 2,
+        q10 = 10 << 2,
+        q11 = 11 << 2,
+        q12 = 12 << 2,
+        q13 = 13 << 2,
+        q14 = 14 << 2,
+        q15 = 15 << 2,
+        q16 = 16 << 2,
+        q17 = 17 << 2,
+        q18 = 18 << 2,
+        q19 = 19 << 2,
+        q20 = 20 << 2,
+        q21 = 21 << 2,
+        q22 = 22 << 2,
+        q23 = 23 << 2,
+        q24 = 24 << 2,
+        q25 = 25 << 2,
+        q26 = 26 << 2,
+        q27 = 27 << 2,
+        q28 = 28 << 2,
+        q29 = 29 << 2,
+        q30 = 30 << 2,
+        q31 = 31 << 2,
+    } FPRegisterID;
+}
+
+class ARMv7Assembler;
+class ARMThumbImmediate {
+    friend class ARMv7Assembler;
+
+    typedef uint8_t ThumbImmediateType;
+    static const ThumbImmediateType TypeInvalid = 0;
+    static const ThumbImmediateType TypeEncoded = 1;
+    static const ThumbImmediateType TypeUInt16 = 2;
+
+    typedef union {
+        int16_t asInt;
+        struct {
+            unsigned imm8 : 8;
+            unsigned imm3 : 3;
+            unsigned i    : 1;
+            unsigned imm4 : 4;
+        };
+        // If this is an encoded immediate, then it may describe a shift, or a pattern.
+        struct {
+            unsigned shiftValue7 : 7;
+            unsigned shiftAmount : 5;
+        };
+        struct {
+            unsigned immediate   : 8;
+            unsigned pattern     : 4;
+        };
+    } ThumbImmediateValue;
+
+    // byte0 contains least significant bit; not using an array to make client code endian agnostic.
+    typedef union {
+        int32_t asInt;
+        struct {
+            uint8_t byte0;
+            uint8_t byte1;
+            uint8_t byte2;
+            uint8_t byte3;
+        };
+    } PatternBytes;
+
+    ALWAYS_INLINE static int32_t countLeadingZerosPartial(uint32_t& value, int32_t& zeros, const int N)
+    {
+        if (value & ~((1<<N)-1)) /* check for any of the top N bits (of 2N bits) are set */ \
+            value >>= N;         /* if any were set, lose the bottom N */ \
+        else                     /* if none of the top N bits are set, */ \
+            zeros += N;          /* then we have identified N leading zeros */
+    }
+
+    static int32_t countLeadingZeros(uint32_t value)
+    {
+        if (!value)
+            return 32;
+
+        int32_t zeros = 0;
+        countLeadingZerosPartial(value, zeros, 16);
+        countLeadingZerosPartial(value, zeros, 8);
+        countLeadingZerosPartial(value, zeros, 4);
+        countLeadingZerosPartial(value, zeros, 2);
+        countLeadingZerosPartial(value, zeros, 1);
+        return zeros;
+    }
+
+    ARMThumbImmediate()
+        : m_type(TypeInvalid)
+    {
+        m_value.asInt = 0;
+    }
+        
+    ARMThumbImmediate(ThumbImmediateType type, ThumbImmediateValue value)
+        : m_type(type)
+        , m_value(value)
+    {
+    }
+
+    ARMThumbImmediate(ThumbImmediateType type, uint16_t value)
+        : m_type(TypeUInt16)
+    {
+        m_value.asInt = value;
+    }
+
+public:
+    static ARMThumbImmediate makeEncodedImm(uint32_t value)
+    {
+        ThumbImmediateValue encoding;
+        encoding.asInt = 0;
+
+        // okay, these are easy.
+        if (value < 256) {
+            encoding.immediate = value;
+            encoding.pattern = 0;
+            return ARMThumbImmediate(TypeEncoded, encoding);
+        }
+
+        int32_t leadingZeros = countLeadingZeros(value);
+        // if there were 24 or more leading zeros, then we'd have hit the (value < 256) case.
+        ASSERT(leadingZeros < 24);
+
+        // Given a number with bit fields Z:B:C, where count(Z)+count(B)+count(C) == 32,
+        // Z are the bits known zero, B is the 8-bit immediate, C are the bits to check for
+        // zero.  count(B) == 8, so the count of bits to be checked is 24 - count(Z).
+        int32_t rightShiftAmount = 24 - leadingZeros;
+        if (value == ((value >> rightShiftAmount) << rightShiftAmount)) {
+            // Shift the value down to the low byte position.  The assign to 
+            // shiftValue7 drops the implicit top bit.
+            encoding.shiftValue7 = value >> rightShiftAmount;
+            // The endoded shift amount is the magnitude of a right rotate.
+            encoding.shiftAmount = 8 + leadingZeros;
+            return ARMThumbImmediate(TypeEncoded, encoding);
+        }
+        
+        PatternBytes bytes;
+        bytes.asInt = value;
+
+        if ((bytes.byte0 == bytes.byte1) && (bytes.byte0 == bytes.byte2) && (bytes.byte0 == bytes.byte3)) {
+            encoding.immediate = bytes.byte0;
+            encoding.pattern = 3;
+            return ARMThumbImmediate(TypeEncoded, encoding);
+        }
+
+        if ((bytes.byte0 == bytes.byte2) && !(bytes.byte1 | bytes.byte3)) {
+            encoding.immediate = bytes.byte0;
+            encoding.pattern = 1;
+            return ARMThumbImmediate(TypeEncoded, encoding);
+        }
+
+        if ((bytes.byte1 == bytes.byte3) && !(bytes.byte0 | bytes.byte2)) {
+            encoding.immediate = bytes.byte0;
+            encoding.pattern = 2;
+            return ARMThumbImmediate(TypeEncoded, encoding);
+        }
+
+        return ARMThumbImmediate();
+    }
+
+    static ARMThumbImmediate makeUInt12(int32_t value)
+    {
+        return (!(value & 0xfffff000))
+            ? ARMThumbImmediate(TypeUInt16, (uint16_t)value)
+            : ARMThumbImmediate();
+    }
+
+    static ARMThumbImmediate makeUInt12OrEncodedImm(int32_t value)
+    {
+        // If this is not a 12-bit unsigned it, try making an encoded immediate.
+        return (!(value & 0xfffff000))
+            ? ARMThumbImmediate(TypeUInt16, (uint16_t)value)
+            : makeEncodedImm(value);
+    }
+
+    // The 'make' methods, above, return a !isValid() value if the argument
+    // cannot be represented as the requested type.  This methods  is called
+    // 'get' since the argument can always be represented.
+    static ARMThumbImmediate makeUInt16(uint16_t value)
+    {
+        return ARMThumbImmediate(TypeUInt16, value);
+    }
+    
+    bool isValid()
+    {
+        return m_type != TypeInvalid;
+    }
+
+    // These methods rely on the format of encoded byte values.
+    bool isUInt3() { return !(m_value.asInt & 0xfff8); }
+    bool isUInt4() { return !(m_value.asInt & 0xfff0); }
+    bool isUInt5() { return !(m_value.asInt & 0xffe0); }
+    bool isUInt6() { return !(m_value.asInt & 0xffc0); }
+    bool isUInt7() { return !(m_value.asInt & 0xff80); }
+    bool isUInt8() { return !(m_value.asInt & 0xff00); }
+    bool isUInt9() { return (m_type == TypeUInt16) && !(m_value.asInt & 0xfe00); }
+    bool isUInt10() { return (m_type == TypeUInt16) && !(m_value.asInt & 0xfc00); }
+    bool isUInt12() { return (m_type == TypeUInt16) && !(m_value.asInt & 0xf000); }
+    bool isUInt16() { return m_type == TypeUInt16; }
+    uint8_t getUInt3() { ASSERT(isUInt3()); return m_value.asInt; }
+    uint8_t getUInt4() { ASSERT(isUInt4()); return m_value.asInt; }
+    uint8_t getUInt5() { ASSERT(isUInt5()); return m_value.asInt; }
+    uint8_t getUInt6() { ASSERT(isUInt6()); return m_value.asInt; }
+    uint8_t getUInt7() { ASSERT(isUInt7()); return m_value.asInt; }
+    uint8_t getUInt8() { ASSERT(isUInt8()); return m_value.asInt; }
+    uint8_t getUInt9() { ASSERT(isUInt9()); return m_value.asInt; }
+    uint8_t getUInt10() { ASSERT(isUInt10()); return m_value.asInt; }
+    uint16_t getUInt12() { ASSERT(isUInt12()); return m_value.asInt; }
+    uint16_t getUInt16() { ASSERT(isUInt16()); return m_value.asInt; }
+
+    bool isEncodedImm() { return m_type == TypeEncoded; }
+
+private:
+    ThumbImmediateType m_type;
+    ThumbImmediateValue m_value;
+};
+
+
+typedef enum {
+    SRType_LSL,
+    SRType_LSR,
+    SRType_ASR,
+    SRType_ROR,
+
+    SRType_RRX = SRType_ROR
+} ARMShiftType;
+
+class ARMv7Assembler;
+class ShiftTypeAndAmount {
+    friend class ARMv7Assembler;
+
+public:
+    ShiftTypeAndAmount()
+    {
+        m_u.type = (ARMShiftType)0;
+        m_u.amount = 0;
+    }
+    
+    ShiftTypeAndAmount(ARMShiftType type, unsigned amount)
+    {
+        m_u.type = type;
+        m_u.amount = amount & 31;
+    }
+    
+    unsigned lo4() { return m_u.lo4; }
+    unsigned hi4() { return m_u.hi4; }
+    
+private:
+    union {
+        struct {
+            unsigned lo4 : 4;
+            unsigned hi4 : 4;
+        };
+        struct {
+            unsigned type   : 2;
+            unsigned amount : 5;
+        };
+    } m_u;
+};
+
+
+/*
+Some features of the Thumb instruction set are deprecated in ARMv7. Deprecated features affecting 
+instructions supported by ARMv7-M are as follows: 
+• use of the PC as <Rd> or <Rm> in a 16-bit ADD (SP plus register) instruction 
+• use of the SP as <Rm> in a 16-bit ADD (SP plus register) instruction 
+• use of the SP as <Rm> in a 16-bit CMP (register) instruction 
+• use of MOV (register) instructions in which <Rd> is the SP or PC and <Rm> is also the SP or PC. 
+• use of <Rn> as the lowest-numbered register in the register list of a 16-bit STM instruction with base 
+register writeback 
+*/
+
+class ARMv7Assembler {
+public:
+    typedef ARM::RegisterID RegisterID;
+    typedef ARM::FPRegisterID FPRegisterID;
+
+    // (HS, LO, HI, LS) -> (AE, B, A, BE)
+    // (VS, VC) -> (O, NO)
+    typedef enum {
+        ConditionEQ,
+        ConditionNE,
+        ConditionHS,
+        ConditionLO,
+        ConditionMI,
+        ConditionPL,
+        ConditionVS,
+        ConditionVC,
+        ConditionHI,
+        ConditionLS,
+        ConditionGE,
+        ConditionLT,
+        ConditionGT,
+        ConditionLE,
+        ConditionAL,
+
+        ConditionCS = ConditionHS,
+        ConditionCC = ConditionLO,
+    } Condition;
+
+    class JmpSrc {
+        friend class ARMv7Assembler;
+        friend class ARMInstructionFormatter;
+    public:
+        JmpSrc()
+            : m_offset(-1)
+        {
+        }
+
+    private:
+        JmpSrc(int offset)
+            : m_offset(offset)
+        {
+        }
+
+        int m_offset;
+    };
+    
+    class JmpDst {
+        friend class ARMv7Assembler;
+        friend class ARMInstructionFormatter;
+    public:
+        JmpDst()
+            : m_offset(-1)
+            , m_used(false)
+        {
+        }
+
+        bool isUsed() const { return m_used; }
+        void used() { m_used = true; }
+    private:
+        JmpDst(int offset)
+            : m_offset(offset)
+            , m_used(false)
+        {
+            ASSERT(m_offset == offset);
+        }
+
+        int m_offset : 31;
+        int m_used : 1;
+    };
+
+private:
+
+    // ARMv7, Appx-A.6.3
+    bool BadReg(RegisterID reg)
+    {
+        return (reg == ARM::sp) || (reg == ARM::pc);
+    }
+
+    bool isSingleRegister(FPRegisterID reg)
+    {
+        // Check that the high bit isn't set (q16+), and that the low bit isn't (s1, s3, etc).
+        return !(reg & ~31);
+    }
+
+    bool isDoubleRegister(FPRegisterID reg)
+    {
+        // Check that the high bit isn't set (q16+), and that the low bit isn't (s1, s3, etc).
+        return !(reg & ~(31 << 1));
+    }
+
+    bool isQuadRegister(FPRegisterID reg)
+    {
+        return !(reg & ~(31 << 2));
+    }
+
+    uint32_t singleRegisterNum(FPRegisterID reg)
+    {
+        ASSERT(isSingleRegister(reg));
+        return reg;
+    }
+
+    uint32_t doubleRegisterNum(FPRegisterID reg)
+    {
+        ASSERT(isDoubleRegister(reg));
+        return reg >> 1;
+    }
+
+    uint32_t quadRegisterNum(FPRegisterID reg)
+    {
+        ASSERT(isQuadRegister(reg));
+        return reg >> 2;
+    }
+
+    uint32_t singleRegisterMask(FPRegisterID rd, int highBitsShift, int lowBitShift)
+    {
+        uint32_t rdNum = singleRegisterNum(rd);
+        uint32_t rdMask = (rdNum >> 1) << highBitsShift;
+        if (rdNum & 1)
+            rdMask |= 1 << lowBitShift;
+        return rdMask;
+    }
+
+    uint32_t doubleRegisterMask(FPRegisterID rd, int highBitShift, int lowBitsShift)
+    {
+        uint32_t rdNum = doubleRegisterNum(rd);
+        uint32_t rdMask = (rdNum & 0xf) << lowBitsShift;
+        if (rdNum & 16)
+            rdMask |= 1 << highBitShift;
+        return rdMask;
+    }
+
+    typedef enum {
+        OP_ADD_reg_T1       = 0x1800,
+        OP_ADD_S_reg_T1     = 0x1800,
+        OP_SUB_reg_T1       = 0x1A00,
+        OP_SUB_S_reg_T1     = 0x1A00,
+        OP_ADD_imm_T1       = 0x1C00,
+        OP_ADD_S_imm_T1     = 0x1C00,
+        OP_SUB_imm_T1       = 0x1E00,
+        OP_SUB_S_imm_T1     = 0x1E00,
+        OP_MOV_imm_T1       = 0x2000,
+        OP_CMP_imm_T1       = 0x2800,
+        OP_ADD_imm_T2       = 0x3000,
+        OP_ADD_S_imm_T2     = 0x3000,
+        OP_SUB_imm_T2       = 0x3800,
+        OP_SUB_S_imm_T2     = 0x3800,
+        OP_AND_reg_T1       = 0x4000,
+        OP_EOR_reg_T1       = 0x4040,
+        OP_TST_reg_T1       = 0x4200,
+        OP_CMP_reg_T1       = 0x4280,
+        OP_ORR_reg_T1       = 0x4300,
+        OP_MVN_reg_T1       = 0x43C0,
+        OP_ADD_reg_T2       = 0x4400,
+        OP_MOV_reg_T1       = 0x4600,
+        OP_BLX              = 0x4700,
+        OP_BX               = 0x4700,
+        OP_LDRH_reg_T1      = 0x5A00,
+        OP_STR_reg_T1       = 0x5000,
+        OP_LDR_reg_T1       = 0x5800,
+        OP_STR_imm_T1       = 0x6000,
+        OP_LDR_imm_T1       = 0x6800,
+        OP_LDRH_imm_T1      = 0x8800,
+        OP_STR_imm_T2       = 0x9000,
+        OP_LDR_imm_T2       = 0x9800,
+        OP_ADD_SP_imm_T1    = 0xA800,
+        OP_ADD_SP_imm_T2    = 0xB000,
+        OP_SUB_SP_imm_T1    = 0xB080,
+        OP_BKPT             = 0xBE00,
+        OP_IT               = 0xBF00,
+    } OpcodeID;
+
+    typedef enum {
+        OP_AND_reg_T2   = 0xEA00,
+        OP_TST_reg_T2   = 0xEA10,
+        OP_ORR_reg_T2   = 0xEA40,
+        OP_ASR_imm_T1   = 0xEA4F,
+        OP_LSL_imm_T1   = 0xEA4F,
+        OP_LSR_imm_T1   = 0xEA4F,
+        OP_ROR_imm_T1   = 0xEA4F,
+        OP_MVN_reg_T2   = 0xEA6F,
+        OP_EOR_reg_T2   = 0xEA80,
+        OP_ADD_reg_T3   = 0xEB00,
+        OP_ADD_S_reg_T3 = 0xEB10,
+        OP_SUB_reg_T2   = 0xEBA0,
+        OP_SUB_S_reg_T2 = 0xEBB0,
+        OP_CMP_reg_T2   = 0xEBB0,
+        OP_B_T4a        = 0xF000,
+        OP_AND_imm_T1   = 0xF000,
+        OP_TST_imm      = 0xF010,
+        OP_ORR_imm_T1   = 0xF040,
+        OP_MOV_imm_T2   = 0xF040,
+        OP_MVN_imm      = 0xF060,
+        OP_EOR_imm_T1   = 0xF080,
+        OP_ADD_imm_T3   = 0xF100,
+        OP_ADD_S_imm_T3 = 0xF110,
+        OP_CMN_imm      = 0xF110,
+        OP_SUB_imm_T3   = 0xF1A0,
+        OP_SUB_S_imm_T3 = 0xF1B0,
+        OP_CMP_imm_T2   = 0xF1B0,
+        OP_ADD_imm_T4   = 0xF200,
+        OP_MOV_imm_T3   = 0xF240,
+        OP_SUB_imm_T4   = 0xF2A0,
+        OP_MOVT         = 0xF2C0,
+        OP_LDRH_reg_T2  = 0xF830,
+        OP_LDRH_imm_T3  = 0xF830,
+        OP_STR_imm_T4   = 0xF840,
+        OP_STR_reg_T2   = 0xF840,
+        OP_LDR_imm_T4   = 0xF850,
+        OP_LDR_reg_T2   = 0xF850,
+        OP_LDRH_imm_T2  = 0xF8B0,
+        OP_STR_imm_T3   = 0xF8C0,
+        OP_LDR_imm_T3   = 0xF8D0,
+        OP_LSL_reg_T2   = 0xFA00,
+        OP_LSR_reg_T2   = 0xFA20,
+        OP_ASR_reg_T2   = 0xFA40,
+        OP_ROR_reg_T2   = 0xFA60,
+        OP_SMULL_T1     = 0xFB80,
+    } OpcodeID1;
+
+    typedef enum {
+        OP_B_T4b        = 0x9000,
+    } OpcodeID2;
+
+    struct FourFours {
+        FourFours(unsigned f3, unsigned f2, unsigned f1, unsigned f0)
+        {
+            m_u.f0 = f0;
+            m_u.f1 = f1;
+            m_u.f2 = f2;
+            m_u.f3 = f3;
+        }
+
+        union {
+            unsigned value;
+            struct {
+                unsigned f0 : 4;
+                unsigned f1 : 4;
+                unsigned f2 : 4;
+                unsigned f3 : 4;
+            };
+        } m_u;
+    };
+
+    class ARMInstructionFormatter;
+
+    // false means else!
+    bool ifThenElseConditionBit(Condition condition, bool isIf)
+    {
+        return isIf ? (condition & 1) : !(condition & 1);
+    }
+    uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if, bool inst4if)
+    {
+        int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
+            | (ifThenElseConditionBit(condition, inst3if) << 2)
+            | (ifThenElseConditionBit(condition, inst4if) << 1)
+            | 1;
+        ASSERT((condition != ConditionAL) || (mask & (mask - 1)));
+        return (condition << 4) | mask;
+    }
+    uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if)
+    {
+        int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
+            | (ifThenElseConditionBit(condition, inst3if) << 2)
+            | 2;
+        ASSERT((condition != ConditionAL) || (mask & (mask - 1)));
+        return (condition << 4) | mask;
+    }
+    uint8_t ifThenElse(Condition condition, bool inst2if)
+    {
+        int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
+            | 4;
+        ASSERT((condition != ConditionAL) || (mask & (mask - 1)));
+        return (condition << 4) | mask;
+    }
+
+    uint8_t ifThenElse(Condition condition)
+    {
+        int mask = 8;
+        ASSERT((condition != ConditionAL) || (mask & (mask - 1)));
+        return (condition << 4) | mask;
+    }
+
+public:
+
+    void add(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
+    {
+        // Rd can only be SP if Rn is also SP.
+        ASSERT((rd != ARM::sp) || (rn == ARM::sp));
+        ASSERT(rd != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(imm.isValid());
+
+        if (rn == ARM::sp) {
+            if (!(rd & 8) && imm.isUInt10()) {
+                m_formatter.oneWordOp5Reg3Imm8(OP_ADD_SP_imm_T1, rd, imm.getUInt10() >> 2);
+                return;
+            } else if ((rd == ARM::sp) && imm.isUInt9()) {
+                m_formatter.oneWordOp9Imm7(OP_ADD_SP_imm_T2, imm.getUInt9() >> 2);
+                return;
+            }
+        } else if (!((rd | rn) & 8)) {
+            if (imm.isUInt3()) {
+                m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
+                return;
+            } else if ((rd == rn) && imm.isUInt8()) {
+                m_formatter.oneWordOp5Reg3Imm8(OP_ADD_imm_T2, rd, imm.getUInt8());
+                return;
+            }
+        }
+
+        if (imm.isEncodedImm())
+            m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADD_imm_T3, rn, rd, imm);
+        else {
+            ASSERT(imm.isUInt12());
+            m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADD_imm_T4, rn, rd, imm);
+        }
+    }
+
+    void add(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT((rd != ARM::sp) || (rn == ARM::sp));
+        ASSERT(rd != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_ADD_reg_T3, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    // NOTE: In an IT block, add doesn't modify the flags register.
+    void add(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        if (rd == rn)
+            m_formatter.oneWordOp8RegReg143(OP_ADD_reg_T2, rm, rd);
+        else if (rd == rm)
+            m_formatter.oneWordOp8RegReg143(OP_ADD_reg_T2, rn, rd);
+        else if (!((rd | rn | rm) & 8))
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_reg_T1, rm, rn, rd);
+        else
+            add(rd, rn, rm, ShiftTypeAndAmount());
+    }
+
+    // Not allowed in an IT (if then) block.
+    void add_S(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
+    {
+        // Rd can only be SP if Rn is also SP.
+        ASSERT((rd != ARM::sp) || (rn == ARM::sp));
+        ASSERT(rd != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(imm.isEncodedImm());
+
+        if (!((rd | rn) & 8)) {
+            if (imm.isUInt3()) {
+                m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_S_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
+                return;
+            } else if ((rd == rn) && imm.isUInt8()) {
+                m_formatter.oneWordOp5Reg3Imm8(OP_ADD_S_imm_T2, rd, imm.getUInt8());
+                return;
+            }
+        }
+
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ADD_S_imm_T3, rn, rd, imm);
+    }
+
+    // Not allowed in an IT (if then) block?
+    void add_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT((rd != ARM::sp) || (rn == ARM::sp));
+        ASSERT(rd != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_ADD_S_reg_T3, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    // Not allowed in an IT (if then) block.
+    void add_S(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        if (!((rd | rn | rm) & 8))
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_S_reg_T1, rm, rn, rd);
+        else
+            add_S(rd, rn, rm, ShiftTypeAndAmount());
+    }
+
+    void ARM_and(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(imm.isEncodedImm());
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_AND_imm_T1, rn, rd, imm);
+    }
+
+    void ARM_and(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_AND_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    void ARM_and(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        if ((rd == rn) && !((rd | rm) & 8))
+            m_formatter.oneWordOp10Reg3Reg3(OP_AND_reg_T1, rm, rd);
+        else if ((rd == rm) && !((rd | rn) & 8))
+            m_formatter.oneWordOp10Reg3Reg3(OP_AND_reg_T1, rn, rd);
+        else
+            ARM_and(rd, rn, rm, ShiftTypeAndAmount());
+    }
+
+    void asr(RegisterID rd, RegisterID rm, int32_t shiftAmount)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rm));
+        ShiftTypeAndAmount shift(SRType_ASR, shiftAmount);
+        m_formatter.twoWordOp16FourFours(OP_ASR_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    void asr(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_ASR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
+    }
+
+    // Only allowed in IT (if then) block if last instruction.
+    JmpSrc b()
+    {
+        m_formatter.twoWordOp16Op16(OP_B_T4a, OP_B_T4b);
+        return JmpSrc(m_formatter.size());
+    }
+    
+    // Only allowed in IT (if then) block if last instruction.
+    JmpSrc blx(RegisterID rm)
+    {
+        ASSERT(rm != ARM::pc);
+        m_formatter.oneWordOp8RegReg143(OP_BLX, rm, (RegisterID)8);
+        return JmpSrc(m_formatter.size());
+    }
+
+    // Only allowed in IT (if then) block if last instruction.
+    JmpSrc bx(RegisterID rm)
+    {
+        m_formatter.oneWordOp8RegReg143(OP_BX, rm, (RegisterID)0);
+        return JmpSrc(m_formatter.size());
+    }
+
+    void bkpt(uint8_t imm=0)
+    {
+        m_formatter.oneWordOp8Imm8(OP_BKPT, imm);
+    }
+
+    void cmn(RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(rn != ARM::pc);
+        ASSERT(imm.isEncodedImm());
+
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_CMN_imm, rn, (RegisterID)0xf, imm);
+    }
+
+    void cmp(RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(rn != ARM::pc);
+        ASSERT(imm.isEncodedImm());
+
+        if (!(rn & 8) && imm.isUInt8())
+            m_formatter.oneWordOp5Reg3Imm8(OP_CMP_imm_T1, rn, imm.getUInt8());
+        else
+            m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_CMP_imm_T2, rn, (RegisterID)0xf, imm);
+    }
+
+    void cmp(RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT(rn != ARM::pc);
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_CMP_reg_T2, rn, FourFours(shift.hi4(), 0xf, shift.lo4(), rm));
+    }
+
+    void cmp(RegisterID rn, RegisterID rm)
+    {
+        if ((rn | rm) & 8)
+            cmp(rn, rm, ShiftTypeAndAmount());
+        else
+            m_formatter.oneWordOp10Reg3Reg3(OP_CMP_reg_T1, rm, rn);
+    }
+
+    // xor is not spelled with an 'e'. :-(
+    void eor(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(imm.isEncodedImm());
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_EOR_imm_T1, rn, rd, imm);
+    }
+
+    // xor is not spelled with an 'e'. :-(
+    void eor(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_EOR_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    // xor is not spelled with an 'e'. :-(
+    void eor(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        if ((rd == rn) && !((rd | rm) & 8))
+            m_formatter.oneWordOp10Reg3Reg3(OP_EOR_reg_T1, rm, rd);
+        else if ((rd == rm) && !((rd | rn) & 8))
+            m_formatter.oneWordOp10Reg3Reg3(OP_EOR_reg_T1, rn, rd);
+        else
+            eor(rd, rn, rm, ShiftTypeAndAmount());
+    }
+
+    void it(Condition cond)
+    {
+        m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond));
+    }
+
+    void it(Condition cond, bool inst2if)
+    {
+        m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if));
+    }
+
+    void it(Condition cond, bool inst2if, bool inst3if)
+    {
+        m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if, inst3if));
+    }
+
+    void it(Condition cond, bool inst2if, bool inst3if, bool inst4if)
+    {
+        m_formatter.oneWordOp8Imm8(OP_IT, ifThenElse(cond, inst2if, inst3if, inst4if));
+    }
+
+    // rt == ARM::pc only allowed if last instruction in IT (if then) block.
+    void ldr(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(rn != ARM::pc); // LDR (literal)
+        ASSERT(imm.isUInt12());
+
+        if (!((rt | rn) & 8) && imm.isUInt7())
+            m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDR_imm_T1, imm.getUInt7() >> 2, rn, rt);
+        else if ((rn == ARM::sp) && !(rt & 8) && imm.isUInt10())
+            m_formatter.oneWordOp5Reg3Imm8(OP_LDR_imm_T2, rt, imm.getUInt10() >> 2);
+        else
+            m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T3, rn, rt, imm.getUInt12());
+    }
+
+    // If index is set, this is a regular offset or a pre-indexed load;
+    // if index is not set then is is a post-index load.
+    //
+    // If wback is set rn is updated - this is a pre or post index load,
+    // if wback is not set this is a regular offset memory access.
+    //
+    // (-255 <= offset <= 255)
+    // _reg = REG[rn]
+    // _tmp = _reg + offset
+    // MEM[index ? _tmp : _reg] = REG[rt]
+    // if (wback) REG[rn] = _tmp
+    void ldr(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
+    {
+        ASSERT(rt != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(index || wback);
+        ASSERT(!wback | (rt != rn));
+    
+        bool add = true;
+        if (offset < 0) {
+            add = false;
+            offset = -offset;
+        }
+        ASSERT((offset & ~0xff) == 0);
+        
+        offset |= (wback << 8);
+        offset |= (add   << 9);
+        offset |= (index << 10);
+        offset |= (1 << 11);
+        
+        m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDR_imm_T4, rn, rt, offset);
+    }
+
+    // rt == ARM::pc only allowed if last instruction in IT (if then) block.
+    void ldr(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift=0)
+    {
+        ASSERT(rn != ARM::pc); // LDR (literal)
+        ASSERT(!BadReg(rm));
+        ASSERT(shift <= 3);
+
+        if (!shift && !((rt | rn | rm) & 8))
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDR_reg_T1, rm, rn, rt);
+        else
+            m_formatter.twoWordOp12Reg4FourFours(OP_LDR_reg_T2, rn, FourFours(rt, 0, shift, rm));
+    }
+
+    // rt == ARM::pc only allowed if last instruction in IT (if then) block.
+    void ldrh(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(rn != ARM::pc); // LDR (literal)
+        ASSERT(imm.isUInt12());
+
+        if (!((rt | rn) & 8) && imm.isUInt6())
+            m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDRH_imm_T1, imm.getUInt6() >> 2, rn, rt);
+        else
+            m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRH_imm_T2, rn, rt, imm.getUInt12());
+    }
+
+    // If index is set, this is a regular offset or a pre-indexed load;
+    // if index is not set then is is a post-index load.
+    //
+    // If wback is set rn is updated - this is a pre or post index load,
+    // if wback is not set this is a regular offset memory access.
+    //
+    // (-255 <= offset <= 255)
+    // _reg = REG[rn]
+    // _tmp = _reg + offset
+    // MEM[index ? _tmp : _reg] = REG[rt]
+    // if (wback) REG[rn] = _tmp
+    void ldrh(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
+    {
+        ASSERT(rt != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(index || wback);
+        ASSERT(!wback | (rt != rn));
+    
+        bool add = true;
+        if (offset < 0) {
+            add = false;
+            offset = -offset;
+        }
+        ASSERT((offset & ~0xff) == 0);
+        
+        offset |= (wback << 8);
+        offset |= (add   << 9);
+        offset |= (index << 10);
+        offset |= (1 << 11);
+        
+        m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRH_imm_T3, rn, rt, offset);
+    }
+
+    void ldrh(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift=0)
+    {
+        ASSERT(!BadReg(rt));   // Memory hint
+        ASSERT(rn != ARM::pc); // LDRH (literal)
+        ASSERT(!BadReg(rm));
+        ASSERT(shift <= 3);
+
+        if (!shift && !((rt | rn | rm) & 8))
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRH_reg_T1, rm, rn, rt);
+        else
+            m_formatter.twoWordOp12Reg4FourFours(OP_LDRH_reg_T2, rn, FourFours(rt, 0, shift, rm));
+    }
+
+    void lsl(RegisterID rd, RegisterID rm, int32_t shiftAmount)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rm));
+        ShiftTypeAndAmount shift(SRType_LSL, shiftAmount);
+        m_formatter.twoWordOp16FourFours(OP_LSL_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    void lsl(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_LSL_reg_T2, rn, FourFours(0xf, rd, 0, rm));
+    }
+
+    void lsr(RegisterID rd, RegisterID rm, int32_t shiftAmount)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rm));
+        ShiftTypeAndAmount shift(SRType_LSR, shiftAmount);
+        m_formatter.twoWordOp16FourFours(OP_LSR_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    void lsr(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_LSR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
+    }
+
+    void movT3(RegisterID rd, ARMThumbImmediate imm)
+    {
+        ASSERT(imm.isValid());
+        ASSERT(!imm.isEncodedImm());
+        ASSERT(!BadReg(rd));
+        
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOV_imm_T3, imm.m_value.imm4, rd, imm);
+    }
+
+     void mov(RegisterID rd, ARMThumbImmediate imm)
+    {
+        ASSERT(imm.isValid());
+        ASSERT(!BadReg(rd));
+        
+        if ((rd < 8) && imm.isUInt8())
+            m_formatter.oneWordOp5Reg3Imm8(OP_MOV_imm_T1, rd, imm.getUInt8());
+        else if (imm.isEncodedImm())
+            m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOV_imm_T2, 0xf, rd, imm);
+        else
+            movT3(rd, imm);
+    }
+
+   void mov(RegisterID rd, RegisterID rm)
+    {
+        m_formatter.oneWordOp8RegReg143(OP_MOV_reg_T1, rm, rd);
+    }
+
+    void movt(RegisterID rd, ARMThumbImmediate imm)
+    {
+        ASSERT(imm.isUInt16());
+        ASSERT(!BadReg(rd));
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MOVT, imm.m_value.imm4, rd, imm);
+    }
+
+    void mvn(RegisterID rd, ARMThumbImmediate imm)
+    {
+        ASSERT(imm.isEncodedImm());
+        ASSERT(!BadReg(rd));
+        
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_MVN_imm, 0xf, rd, imm);
+    }
+
+    void mvn(RegisterID rd, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp16FourFours(OP_MVN_reg_T2, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    void mvn(RegisterID rd, RegisterID rm)
+    {
+        if (!((rd | rm) & 8))
+            m_formatter.oneWordOp10Reg3Reg3(OP_MVN_reg_T1, rm, rd);
+        else
+            mvn(rd, rm, ShiftTypeAndAmount());
+    }
+
+    void orr(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(imm.isEncodedImm());
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_ORR_imm_T1, rn, rd, imm);
+    }
+
+    void orr(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_ORR_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    void orr(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        if ((rd == rn) && !((rd | rm) & 8))
+            m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rm, rd);
+        else if ((rd == rm) && !((rd | rn) & 8))
+            m_formatter.oneWordOp10Reg3Reg3(OP_ORR_reg_T1, rn, rd);
+        else
+            orr(rd, rn, rm, ShiftTypeAndAmount());
+    }
+
+    void ror(RegisterID rd, RegisterID rm, int32_t shiftAmount)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rm));
+        ShiftTypeAndAmount shift(SRType_ROR, shiftAmount);
+        m_formatter.twoWordOp16FourFours(OP_ROR_imm_T1, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    void ror(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_ROR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
+    }
+
+    void smull(RegisterID rdLo, RegisterID rdHi, RegisterID rn, RegisterID rm)
+    {
+        ASSERT(!BadReg(rdLo));
+        ASSERT(!BadReg(rdHi));
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        ASSERT(rdLo != rdHi);
+        m_formatter.twoWordOp12Reg4FourFours(OP_SMULL_T1, rn, FourFours(rdLo, rdHi, 0, rm));
+    }
+
+    // rt == ARM::pc only allowed if last instruction in IT (if then) block.
+    void str(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(rt != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(imm.isUInt12());
+
+        if (!((rt | rn) & 8) && imm.isUInt7())
+            m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STR_imm_T1, imm.getUInt7() >> 2, rn, rt);
+        else if ((rn == ARM::sp) && !(rt & 8) && imm.isUInt10())
+            m_formatter.oneWordOp5Reg3Imm8(OP_STR_imm_T2, rt, imm.getUInt10() >> 2);
+        else
+            m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STR_imm_T3, rn, rt, imm.getUInt12());
+    }
+
+    // If index is set, this is a regular offset or a pre-indexed store;
+    // if index is not set then is is a post-index store.
+    //
+    // If wback is set rn is updated - this is a pre or post index store,
+    // if wback is not set this is a regular offset memory access.
+    //
+    // (-255 <= offset <= 255)
+    // _reg = REG[rn]
+    // _tmp = _reg + offset
+    // MEM[index ? _tmp : _reg] = REG[rt]
+    // if (wback) REG[rn] = _tmp
+    void str(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
+    {
+        ASSERT(rt != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(index || wback);
+        ASSERT(!wback | (rt != rn));
+    
+        bool add = true;
+        if (offset < 0) {
+            add = false;
+            offset = -offset;
+        }
+        ASSERT((offset & ~0xff) == 0);
+        
+        offset |= (wback << 8);
+        offset |= (add   << 9);
+        offset |= (index << 10);
+        offset |= (1 << 11);
+        
+        m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STR_imm_T4, rn, rt, offset);
+    }
+
+    // rt == ARM::pc only allowed if last instruction in IT (if then) block.
+    void str(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift=0)
+    {
+        ASSERT(rn != ARM::pc);
+        ASSERT(!BadReg(rm));
+        ASSERT(shift <= 3);
+
+        if (!shift && !((rt | rn | rm) & 8))
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_STR_reg_T1, rm, rn, rt);
+        else
+            m_formatter.twoWordOp12Reg4FourFours(OP_STR_reg_T2, rn, FourFours(rt, 0, shift, rm));
+    }
+
+    void sub(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
+    {
+        // Rd can only be SP if Rn is also SP.
+        ASSERT((rd != ARM::sp) || (rn == ARM::sp));
+        ASSERT(rd != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(imm.isValid());
+
+        if ((rn == ARM::sp) && (rd == ARM::sp) && imm.isUInt9()) {
+            m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, imm.getUInt9() >> 2);
+            return;
+        } else if (!((rd | rn) & 8)) {
+            if (imm.isUInt3()) {
+                m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
+                return;
+            } else if ((rd == rn) && imm.isUInt8()) {
+                m_formatter.oneWordOp5Reg3Imm8(OP_SUB_imm_T2, rd, imm.getUInt8());
+                return;
+            }
+        }
+
+        if (imm.isEncodedImm())
+            m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_imm_T3, rn, rd, imm);
+        else {
+            ASSERT(imm.isUInt12());
+            m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_imm_T4, rn, rd, imm);
+        }
+    }
+
+    void sub(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT((rd != ARM::sp) || (rn == ARM::sp));
+        ASSERT(rd != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_SUB_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    // NOTE: In an IT block, add doesn't modify the flags register.
+    void sub(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        if (!((rd | rn | rm) & 8))
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_reg_T1, rm, rn, rd);
+        else
+            sub(rd, rn, rm, ShiftTypeAndAmount());
+    }
+
+    // Not allowed in an IT (if then) block.
+    void sub_S(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
+    {
+        // Rd can only be SP if Rn is also SP.
+        ASSERT((rd != ARM::sp) || (rn == ARM::sp));
+        ASSERT(rd != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(imm.isValid());
+
+        if ((rn == ARM::sp) && (rd == ARM::sp) && imm.isUInt9()) {
+            m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, imm.getUInt9() >> 2);
+            return;
+        } else if (!((rd | rn) & 8)) {
+            if (imm.isUInt3()) {
+                m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_S_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
+                return;
+            } else if ((rd == rn) && imm.isUInt8()) {
+                m_formatter.oneWordOp5Reg3Imm8(OP_SUB_S_imm_T2, rd, imm.getUInt8());
+                return;
+            }
+        }
+
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_SUB_S_imm_T3, rn, rd, imm);
+    }
+
+    // Not allowed in an IT (if then) block?
+    void sub_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT((rd != ARM::sp) || (rn == ARM::sp));
+        ASSERT(rd != ARM::pc);
+        ASSERT(rn != ARM::pc);
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_SUB_S_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    // Not allowed in an IT (if then) block.
+    void sub_S(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        if (!((rd | rn | rm) & 8))
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_S_reg_T1, rm, rn, rd);
+        else
+            sub_S(rd, rn, rm, ShiftTypeAndAmount());
+    }
+
+    void tst(RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(!BadReg(rn));
+        ASSERT(imm.isEncodedImm());
+
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_TST_imm, rn, (RegisterID)0xf, imm);
+    }
+
+    void tst(RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_TST_reg_T2, rn, FourFours(shift.hi4(), 0xf, shift.lo4(), rm));
+    }
+
+    void tst(RegisterID rn, RegisterID rm)
+    {
+        if ((rn | rm) & 8)
+            tst(rn, rm, ShiftTypeAndAmount());
+        else
+            m_formatter.oneWordOp10Reg3Reg3(OP_TST_reg_T1, rm, rn);
+    }
+
+    void vadd_F64(FPRegisterID rd, FPRegisterID rn, FPRegisterID rm)
+    {
+        m_formatter.vfpOp(0x0b00ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16));
+    }
+
+    void vcmp_F64(FPRegisterID rd, FPRegisterID rm)
+    {
+        m_formatter.vfpOp(0x0bc0eeb4 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rm, 21, 16));
+    }
+
+    void vcvt_F64_S32(FPRegisterID fd, FPRegisterID sm)
+    {
+        m_formatter.vfpOp(0x0bc0eeb8 | doubleRegisterMask(fd, 6, 28) | singleRegisterMask(sm, 16, 21));
+    }
+
+    void vcvt_S32_F64(FPRegisterID sd, FPRegisterID fm)
+    {
+        m_formatter.vfpOp(0x0bc0eebd | singleRegisterMask(sd, 28, 6) | doubleRegisterMask(fm, 21, 16));
+    }
+
+    void vldr(FPRegisterID rd, RegisterID rn, int32_t imm)
+    {
+        vmem(rd, rn, imm, true);
+    }
+
+    void vmov(RegisterID rd, FPRegisterID sn)
+    {
+        m_formatter.vfpOp(0x0a10ee10 | (rd << 28) | singleRegisterMask(sn, 0, 23));
+    }
+
+    void vmov(FPRegisterID sn, RegisterID rd)
+    {
+        m_formatter.vfpOp(0x0a10ee00 | (rd << 28) | singleRegisterMask(sn, 0, 23));
+    }
+
+    // move FPSCR flags to APSR.
+    void vmrs_APSR_nzcv_FPSCR()
+    {
+        m_formatter.vfpOp(0xfa10eef1);
+    }
+
+    void vmul_F64(FPRegisterID rd, FPRegisterID rn, FPRegisterID rm)
+    {
+        m_formatter.vfpOp(0x0b00ee20 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16));
+    }
+
+    void vstr(FPRegisterID rd, RegisterID rn, int32_t imm)
+    {
+        vmem(rd, rn, imm, false);
+    }
+
+    void vsub_F64(FPRegisterID rd, FPRegisterID rn, FPRegisterID rm)
+    {
+        m_formatter.vfpOp(0x0b40ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16));
+    }
+
+
+    JmpDst label()
+    {
+        return JmpDst(m_formatter.size());
+    }
+    
+    JmpDst align(int alignment)
+    {
+        while (!m_formatter.isAligned(alignment))
+            bkpt();
+
+        return label();
+    }
+    
+    static void* getRelocatedAddress(void* code, JmpSrc jump)
+    {
+        ASSERT(jump.m_offset != -1);
+
+        return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
+    }
+    
+    static void* getRelocatedAddress(void* code, JmpDst destination)
+    {
+        ASSERT(destination.m_offset != -1);
+
+        return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + destination.m_offset);
+    }
+    
+    static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
+    {
+        return dst.m_offset - src.m_offset;
+    }
+    
+    static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
+    {
+        return dst.m_offset - src.m_offset;
+    }
+    
+    static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
+    {
+        return dst.m_offset - src.m_offset;
+    }
+    
+    // Assembler admin methods:
+
+    size_t size() const
+    {
+        return m_formatter.size();
+    }
+
+    void* executableCopy(ExecutablePool* allocator)
+    {
+        void* copy = m_formatter.executableCopy(allocator);
+        ASSERT(copy);
+        return copy;
+    }
+
+    static unsigned getCallReturnOffset(JmpSrc call)
+    {
+        ASSERT(call.m_offset >= 0);
+        return call.m_offset;
+    }
+
+    // Linking & patching:
+    //
+    // 'link' and 'patch' methods are for use on unprotected code - such as the code
+    // within the AssemblerBuffer, and code being patched by the patch buffer.  Once
+    // code has been finalized it is (platform support permitting) within a non-
+    // writable region of memory; to modify the code in an execute-only execuable
+    // pool the 'repatch' and 'relink' methods should be used.
+
+    void linkJump(JmpSrc from, JmpDst to)
+    {
+        ASSERT(to.m_offset != -1);
+        ASSERT(from.m_offset != -1);
+
+        uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(m_formatter.data()) + from.m_offset);
+        intptr_t relative = to.m_offset - from.m_offset;
+
+        linkWithOffset(location, relative);
+    }
+
+    static void linkJump(void* code, JmpSrc from, void* to)
+    {
+        ASSERT(from.m_offset != -1);
+        
+        uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
+        intptr_t relative = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(location);
+
+        linkWithOffset(location, relative);
+    }
+
+    // bah, this mathod should really be static, since it is used by the LinkBuffer.
+    // return a bool saying whether the link was successful?
+    static void linkCall(void* code, JmpSrc from, void* to)
+    {
+        ASSERT(!(reinterpret_cast<intptr_t>(code) & 1));
+        ASSERT(from.m_offset != -1);
+        ASSERT(reinterpret_cast<intptr_t>(to) & 1);
+
+        setPointer(reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset) - 1, to);
+    }
+
+    static void linkPointer(void* code, JmpDst where, void* value)
+    {
+        setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
+    }
+
+    static void relinkJump(void* from, void* to)
+    {
+        ASSERT(!(reinterpret_cast<intptr_t>(from) & 1));
+        ASSERT(!(reinterpret_cast<intptr_t>(to) & 1));
+
+        intptr_t relative = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
+        linkWithOffset(reinterpret_cast<uint16_t*>(from), relative);
+
+        ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 2, 2 * sizeof(uint16_t));
+    }
+    
+    static void relinkCall(void* from, void* to)
+    {
+        ASSERT(!(reinterpret_cast<intptr_t>(from) & 1));
+        ASSERT(reinterpret_cast<intptr_t>(to) & 1);
+
+        setPointer(reinterpret_cast<uint16_t*>(from) - 1, to);
+
+        ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(from) - 5, 4 * sizeof(uint16_t));
+    }
+
+    static void repatchInt32(void* where, int32_t value)
+    {
+        ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
+        
+        setInt32(where, value);
+
+        ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(where) - 4, 4 * sizeof(uint16_t));
+    }
+
+    static void repatchPointer(void* where, void* value)
+    {
+        ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
+        
+        setPointer(where, value);
+
+        ExecutableAllocator::cacheFlush(reinterpret_cast<uint16_t*>(where) - 4, 4 * sizeof(uint16_t));
+    }
+
+    static void repatchLoadPtrToLEA(void* where)
+    {
+        ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
+
+        uint16_t* loadOp = reinterpret_cast<uint16_t*>(where) + 4;
+        ASSERT((*loadOp & 0xfff0) == OP_LDR_reg_T2);
+
+        *loadOp = OP_ADD_reg_T3 | (*loadOp & 0xf);
+        ExecutableAllocator::cacheFlush(loadOp, sizeof(uint16_t));
+    }
+
+private:
+
+    // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
+    // (i.e. +/-(0..255) 32-bit words)
+    void vmem(FPRegisterID rd, RegisterID rn, int32_t imm, bool isLoad)
+    {
+        bool up;
+        uint32_t offset;
+        if (imm < 0) {
+            offset = -imm;
+            up = false;
+        } else {
+            offset = imm;
+            up = true;
+        }
+
+        // offset is effectively leftshifted by 2 already (the bottom two bits are zero, and not
+        // reperesented in the instruction.  Left shift by 14, to mov it into position 0x00AA0000.
+        ASSERT((offset & ~(0xff << 2)) == 0);
+        offset <<= 14;
+
+        m_formatter.vfpOp(0x0b00ed00 | offset | (up << 7) | (isLoad << 4) | doubleRegisterMask(rd, 6, 28) | rn);
+    }
+
+    static void setInt32(void* code, uint32_t value)
+    {
+        uint16_t* location = reinterpret_cast<uint16_t*>(code);
+
+        uint16_t lo16 = value;
+        uint16_t hi16 = value >> 16;
+
+        spliceHi5(location - 4, lo16);
+        spliceLo11(location - 3, lo16);
+        spliceHi5(location - 2, hi16);
+        spliceLo11(location - 1, hi16);
+
+        ExecutableAllocator::cacheFlush(location - 4, 4 * sizeof(uint16_t));
+    }
+
+    static void setPointer(void* code, void* value)
+    {
+        setInt32(code, reinterpret_cast<uint32_t>(value));
+    }
+
+    // Linking & patching:
+    // This method assumes that the JmpSrc being linked is a T4 b instruction.
+    static void linkWithOffset(uint16_t* instruction, intptr_t relative)
+    {
+        // Currently branches > 16m = mostly deathy.
+        if (((relative << 7) >> 7) != relative) {
+            // FIXME: This CRASH means we cannot turn the JIT on by default on arm-v7.
+            fprintf(stderr, "Error: Cannot link T4b.\n");
+            CRASH();
+        }
+        
+        // ARM encoding for the top two bits below the sign bit is 'peculiar'.
+        if (relative >= 0)
+            relative ^= 0xC00000;
+
+        // All branch offsets should be an even distance.
+        ASSERT(!(relative & 1));
+
+        int word1 = ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12);
+        int word2 = ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1);
+
+        instruction[-2] = OP_B_T4a | word1;
+        instruction[-1] = OP_B_T4b | word2;
+    }
+
+    // These functions can be used to splice 16-bit immediates back into previously generated instructions.
+    static void spliceHi5(uint16_t* where, uint16_t what)
+    {
+        uint16_t pattern = (what >> 12) | ((what & 0x0800) >> 1);
+        *where = (*where & 0xFBF0) | pattern;
+    }
+    static void spliceLo11(uint16_t* where, uint16_t what)
+    {
+        uint16_t pattern = ((what & 0x0700) << 4) | (what & 0x00FF);
+        *where = (*where & 0x8F00) | pattern;
+    }
+
+    class ARMInstructionFormatter {
+    public:
+        void oneWordOp5Reg3Imm8(OpcodeID op, RegisterID rd, uint8_t imm)
+        {
+            m_buffer.putShort(op | (rd << 8) | imm);
+        }
+        
+        void oneWordOp5Imm5Reg3Reg3(OpcodeID op, uint8_t imm, RegisterID reg1, RegisterID reg2)
+        {
+            m_buffer.putShort(op | (imm << 6) | (reg1 << 3) | reg2);
+        }
+
+        void oneWordOp7Reg3Reg3Reg3(OpcodeID op, RegisterID reg1, RegisterID reg2, RegisterID reg3)
+        {
+            m_buffer.putShort(op | (reg1 << 6) | (reg2 << 3) | reg3);
+        }
+
+        void oneWordOp8Imm8(OpcodeID op, uint8_t imm)
+        {
+            m_buffer.putShort(op | imm);
+        }
+
+        void oneWordOp8RegReg143(OpcodeID op, RegisterID reg1, RegisterID reg2)
+        {
+            m_buffer.putShort(op | ((reg2 & 8) << 4) | (reg1 << 3) | (reg2 & 7));
+        }
+        void oneWordOp9Imm7(OpcodeID op, uint8_t imm)
+        {
+            m_buffer.putShort(op | imm);
+        }
+
+        void oneWordOp10Reg3Reg3(OpcodeID op, RegisterID reg1, RegisterID reg2)
+        {
+            m_buffer.putShort(op | (reg1 << 3) | reg2);
+        }
+
+        void twoWordOp12Reg4FourFours(OpcodeID1 op, RegisterID reg, FourFours ff)
+        {
+            m_buffer.putShort(op | reg);
+            m_buffer.putShort(ff.m_u.value);
+        }
+        
+        void twoWordOp16FourFours(OpcodeID1 op, FourFours ff)
+        {
+            m_buffer.putShort(op);
+            m_buffer.putShort(ff.m_u.value);
+        }
+        
+        void twoWordOp16Op16(OpcodeID1 op1, OpcodeID2 op2)
+        {
+            m_buffer.putShort(op1);
+            m_buffer.putShort(op2);
+        }
+
+        void twoWordOp5i6Imm4Reg4EncodedImm(OpcodeID1 op, int imm4, RegisterID rd, ARMThumbImmediate imm)
+        {
+            m_buffer.putShort(op | (imm.m_value.i << 10) | imm4);
+            m_buffer.putShort((imm.m_value.imm3 << 12) | (rd << 8) | imm.m_value.imm8);
+        }
+
+        void twoWordOp12Reg4Reg4Imm12(OpcodeID1 op, RegisterID reg1, RegisterID reg2, uint16_t imm)
+        {
+            m_buffer.putShort(op | reg1);
+            m_buffer.putShort((reg2 << 12) | imm);
+        }
+
+        void vfpOp(int32_t op)
+        {
+            m_buffer.putInt(op);
+        }
+
+
+        // Administrative methods:
+
+        size_t size() const { return m_buffer.size(); }
+        bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
+        void* data() const { return m_buffer.data(); }
+        void* executableCopy(ExecutablePool* allocator) { return m_buffer.executableCopy(allocator); }
+
+    private:
+        AssemblerBuffer m_buffer;
+    } m_formatter;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER) && PLATFORM_ARM_ARCH(7)
+
+#endif // ARMAssembler_h
diff --git a/assembler/AbstractMacroAssembler.h b/assembler/AbstractMacroAssembler.h
new file mode 100644 (file)
index 0000000..0b23d02
--- /dev/null
@@ -0,0 +1,536 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef AbstractMacroAssembler_h
+#define AbstractMacroAssembler_h
+
+#include <wtf/Platform.h>
+
+#include <MacroAssemblerCodeRef.h>
+#include <CodeLocation.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/UnusedParam.h>
+
+#if ENABLE(ASSEMBLER)
+
+namespace JSC {
+
+class LinkBuffer;
+class RepatchBuffer;
+
+template <class AssemblerType>
+class AbstractMacroAssembler {
+public:
+    typedef AssemblerType AssemblerType_T;
+
+    typedef MacroAssemblerCodePtr CodePtr;
+    typedef MacroAssemblerCodeRef CodeRef;
+
+    class Jump;
+
+    typedef typename AssemblerType::RegisterID RegisterID;
+    typedef typename AssemblerType::FPRegisterID FPRegisterID;
+    typedef typename AssemblerType::JmpSrc JmpSrc;
+    typedef typename AssemblerType::JmpDst JmpDst;
+
+
+    // Section 1: MacroAssembler operand types
+    //
+    // The following types are used as operands to MacroAssembler operations,
+    // describing immediate  and memory operands to the instructions to be planted.
+
+
+    enum Scale {
+        TimesOne,
+        TimesTwo,
+        TimesFour,
+        TimesEight,
+    };
+
+    // Address:
+    //
+    // Describes a simple base-offset address.
+    struct Address {
+        explicit Address(RegisterID base, int32_t offset = 0)
+            : base(base)
+            , offset(offset)
+        {
+        }
+
+        RegisterID base;
+        int32_t offset;
+    };
+
+    // ImplicitAddress:
+    //
+    // This class is used for explicit 'load' and 'store' operations
+    // (as opposed to situations in which a memory operand is provided
+    // to a generic operation, such as an integer arithmetic instruction).
+    //
+    // In the case of a load (or store) operation we want to permit
+    // addresses to be implicitly constructed, e.g. the two calls:
+    //
+    //     load32(Address(addrReg), destReg);
+    //     load32(addrReg, destReg);
+    //
+    // Are equivalent, and the explicit wrapping of the Address in the former
+    // is unnecessary.
+    struct ImplicitAddress {
+        ImplicitAddress(RegisterID base)
+            : base(base)
+            , offset(0)
+        {
+        }
+
+        ImplicitAddress(Address address)
+            : base(address.base)
+            , offset(address.offset)
+        {
+        }
+
+        RegisterID base;
+        int32_t offset;
+    };
+
+    // BaseIndex:
+    //
+    // Describes a complex addressing mode.
+    struct BaseIndex {
+        BaseIndex(RegisterID base, RegisterID index, Scale scale, int32_t offset = 0)
+            : base(base)
+            , index(index)
+            , scale(scale)
+            , offset(offset)
+        {
+        }
+
+        RegisterID base;
+        RegisterID index;
+        Scale scale;
+        int32_t offset;
+    };
+
+    // AbsoluteAddress:
+    //
+    // Describes an memory operand given by a pointer.  For regular load & store
+    // operations an unwrapped void* will be used, rather than using this.
+    struct AbsoluteAddress {
+        explicit AbsoluteAddress(void* ptr)
+            : m_ptr(ptr)
+        {
+        }
+
+        void* m_ptr;
+    };
+
+    // ImmPtr:
+    //
+    // A pointer sized immediate operand to an instruction - this is wrapped
+    // in a class requiring explicit construction in order to differentiate
+    // from pointers used as absolute addresses to memory operations
+    struct ImmPtr {
+        explicit ImmPtr(void* value)
+            : m_value(value)
+        {
+        }
+
+        intptr_t asIntptr()
+        {
+            return reinterpret_cast<intptr_t>(m_value);
+        }
+
+        void* m_value;
+    };
+
+    // Imm32:
+    //
+    // A 32bit immediate operand to an instruction - this is wrapped in a
+    // class requiring explicit construction in order to prevent RegisterIDs
+    // (which are implemented as an enum) from accidentally being passed as
+    // immediate values.
+    struct Imm32 {
+        explicit Imm32(int32_t value)
+            : m_value(value)
+#if PLATFORM_ARM_ARCH(7)
+            , m_isPointer(false)
+#endif
+        {
+        }
+
+#if !PLATFORM(X86_64)
+        explicit Imm32(ImmPtr ptr)
+            : m_value(ptr.asIntptr())
+#if PLATFORM_ARM_ARCH(7)
+            , m_isPointer(true)
+#endif
+        {
+        }
+#endif
+
+        int32_t m_value;
+#if PLATFORM_ARM_ARCH(7)
+        // We rely on being able to regenerate code to recover exception handling
+        // information.  Since ARMv7 supports 16-bit immediates there is a danger
+        // that if pointer values change the layout of the generated code will change.
+        // To avoid this problem, always generate pointers (and thus Imm32s constructed
+        // from ImmPtrs) with a code sequence that is able  to represent  any pointer
+        // value - don't use a more compact form in these cases.
+        bool m_isPointer;
+#endif
+    };
+
+
+    // Section 2: MacroAssembler code buffer handles
+    //
+    // The following types are used to reference items in the code buffer
+    // during JIT code generation.  For example, the type Jump is used to
+    // track the location of a jump instruction so that it may later be
+    // linked to a label marking its destination.
+
+
+    // Label:
+    //
+    // A Label records a point in the generated instruction stream, typically such that
+    // it may be used as a destination for a jump.
+    class Label {
+        template<class TemplateAssemblerType>
+        friend class AbstractMacroAssembler;
+        friend class Jump;
+        friend class MacroAssemblerCodeRef;
+        friend class LinkBuffer;
+
+    public:
+        Label()
+        {
+        }
+
+        Label(AbstractMacroAssembler<AssemblerType>* masm)
+            : m_label(masm->m_assembler.label())
+        {
+        }
+        
+        bool isUsed() const { return m_label.isUsed(); }
+        void used() { m_label.used(); }
+    private:
+        JmpDst m_label;
+    };
+
+    // DataLabelPtr:
+    //
+    // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
+    // patched after the code has been generated.
+    class DataLabelPtr {
+        template<class TemplateAssemblerType>
+        friend class AbstractMacroAssembler;
+        friend class LinkBuffer;
+    public:
+        DataLabelPtr()
+        {
+        }
+
+        DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm)
+            : m_label(masm->m_assembler.label())
+        {
+        }
+        
+    private:
+        JmpDst m_label;
+    };
+
+    // DataLabel32:
+    //
+    // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
+    // patched after the code has been generated.
+    class DataLabel32 {
+        template<class TemplateAssemblerType>
+        friend class AbstractMacroAssembler;
+        friend class LinkBuffer;
+    public:
+        DataLabel32()
+        {
+        }
+
+        DataLabel32(AbstractMacroAssembler<AssemblerType>* masm)
+            : m_label(masm->m_assembler.label())
+        {
+        }
+
+    private:
+        JmpDst m_label;
+    };
+
+    // Call:
+    //
+    // A Call object is a reference to a call instruction that has been planted
+    // into the code buffer - it is typically used to link the call, setting the
+    // relative offset such that when executed it will call to the desired
+    // destination.
+    class Call {
+        template<class TemplateAssemblerType>
+        friend class AbstractMacroAssembler;
+
+    public:
+        enum Flags {
+            None = 0x0,
+            Linkable = 0x1,
+            Near = 0x2,
+            LinkableNear = 0x3,
+        };
+
+        Call()
+            : m_flags(None)
+        {
+        }
+        
+        Call(JmpSrc jmp, Flags flags)
+            : m_jmp(jmp)
+            , m_flags(flags)
+        {
+        }
+
+        bool isFlagSet(Flags flag)
+        {
+            return m_flags & flag;
+        }
+
+        static Call fromTailJump(Jump jump)
+        {
+            return Call(jump.m_jmp, Linkable);
+        }
+
+        JmpSrc m_jmp;
+
+    private:
+        Flags m_flags;
+    };
+
+    // Jump:
+    //
+    // A jump object is a reference to a jump instruction that has been planted
+    // into the code buffer - it is typically used to link the jump, setting the
+    // relative offset such that when executed it will jump to the desired
+    // destination.
+    class Jump {
+        template<class TemplateAssemblerType>
+        friend class AbstractMacroAssembler;
+        friend class Call;
+        friend class LinkBuffer;
+    public:
+        Jump()
+        {
+        }
+        
+        Jump(JmpSrc jmp)    
+            : m_jmp(jmp)
+        {
+        }
+        
+        void link(AbstractMacroAssembler<AssemblerType>* masm)
+        {
+            masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label());
+        }
+        
+        void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
+        {
+            masm->m_assembler.linkJump(m_jmp, label.m_label);
+        }
+
+    private:
+        JmpSrc m_jmp;
+    };
+
+    // JumpList:
+    //
+    // A JumpList is a set of Jump objects.
+    // All jumps in the set will be linked to the same destination.
+    class JumpList {
+        friend class LinkBuffer;
+
+    public:
+        typedef Vector<Jump, 16> JumpVector;
+
+        void link(AbstractMacroAssembler<AssemblerType>* masm)
+        {
+            size_t size = m_jumps.size();
+            for (size_t i = 0; i < size; ++i)
+                m_jumps[i].link(masm);
+            m_jumps.clear();
+        }
+        
+        void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm)
+        {
+            size_t size = m_jumps.size();
+            for (size_t i = 0; i < size; ++i)
+                m_jumps[i].linkTo(label, masm);
+            m_jumps.clear();
+        }
+        
+        void append(Jump jump)
+        {
+            m_jumps.append(jump);
+        }
+        
+        void append(JumpList& other)
+        {
+            m_jumps.append(other.m_jumps.begin(), other.m_jumps.size());
+        }
+
+        bool empty()
+        {
+            return !m_jumps.size();
+        }
+        
+        const JumpVector& jumps() { return m_jumps; }
+
+    private:
+        JumpVector m_jumps;
+    };
+
+
+    // Section 3: Misc admin methods
+
+    static CodePtr trampolineAt(CodeRef ref, Label label)
+    {
+        return CodePtr(AssemblerType::getRelocatedAddress(ref.m_code.dataLocation(), label.m_label));
+    }
+
+    size_t size()
+    {
+        return m_assembler.size();
+    }
+
+    Label label()
+    {
+        return Label(this);
+    }
+    
+    Label align()
+    {
+        m_assembler.align(16);
+        return Label(this);
+    }
+
+    ptrdiff_t differenceBetween(Label from, Jump to)
+    {
+        return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+    }
+
+    ptrdiff_t differenceBetween(Label from, Call to)
+    {
+        return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+    }
+
+    ptrdiff_t differenceBetween(Label from, Label to)
+    {
+        return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
+    }
+
+    ptrdiff_t differenceBetween(Label from, DataLabelPtr to)
+    {
+        return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
+    }
+
+    ptrdiff_t differenceBetween(Label from, DataLabel32 to)
+    {
+        return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
+    }
+
+    ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
+    {
+        return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+    }
+
+    ptrdiff_t differenceBetween(DataLabelPtr from, DataLabelPtr to)
+    {
+        return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
+    }
+
+    ptrdiff_t differenceBetween(DataLabelPtr from, Call to)
+    {
+        return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
+    }
+
+protected:
+    AssemblerType m_assembler;
+
+    friend class LinkBuffer;
+    friend class RepatchBuffer;
+
+    static void linkJump(void* code, Jump jump, CodeLocationLabel target)
+    {
+        AssemblerType::linkJump(code, jump.m_jmp, target.dataLocation());
+    }
+
+    static void linkPointer(void* code, typename AssemblerType::JmpDst label, void* value)
+    {
+        AssemblerType::linkPointer(code, label, value);
+    }
+
+    static void* getLinkerAddress(void* code, typename AssemblerType::JmpSrc label)
+    {
+        return AssemblerType::getRelocatedAddress(code, label);
+    }
+
+    static void* getLinkerAddress(void* code, typename AssemblerType::JmpDst label)
+    {
+        return AssemblerType::getRelocatedAddress(code, label);
+    }
+
+    static unsigned getLinkerCallReturnOffset(Call call)
+    {
+        return AssemblerType::getCallReturnOffset(call.m_jmp);
+    }
+
+    static void repatchJump(CodeLocationJump jump, CodeLocationLabel destination)
+    {
+        AssemblerType::relinkJump(jump.dataLocation(), destination.dataLocation());
+    }
+
+    static void repatchNearCall(CodeLocationNearCall nearCall, CodeLocationLabel destination)
+    {
+        AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress());
+    }
+
+    static void repatchInt32(CodeLocationDataLabel32 dataLabel32, int32_t value)
+    {
+        AssemblerType::repatchInt32(dataLabel32.dataLocation(), value);
+    }
+
+    static void repatchPointer(CodeLocationDataLabelPtr dataLabelPtr, void* value)
+    {
+        AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value);
+    }
+
+    static void repatchLoadPtrToLEA(CodeLocationInstruction instruction)
+    {
+        AssemblerType::repatchLoadPtrToLEA(instruction.dataLocation());
+    }
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // AbstractMacroAssembler_h
index e1f53d8247ced129843fdaf533a62f2b1cede2e7..073906a526439e7f58fff1e29364d81cca30eb5e 100644 (file)
@@ -95,12 +95,14 @@ namespace JSC {
 
         void putIntUnchecked(int value)
         {
+            ASSERT(!(m_size > m_capacity - 4));
             *reinterpret_cast<int*>(&m_buffer[m_size]) = value;
             m_size += 4;
         }
 
         void putInt64Unchecked(int64_t value)
         {
+            ASSERT(!(m_size > m_capacity - 8));
             *reinterpret_cast<int64_t*>(&m_buffer[m_size]) = value;
             m_size += 8;
         }
@@ -132,13 +134,24 @@ namespace JSC {
             if (!result)
                 return 0;
 
+            ExecutableAllocator::makeWritable(result, m_size);
+
             return memcpy(result, m_buffer, m_size);
         }
 
-    private:
-        void grow()
+    protected:
+        void append(const char* data, int size)
+        {
+            if (m_size > m_capacity - size)
+                grow(size);
+
+            memcpy(m_buffer + m_size, data, size);
+            m_size += size;
+        }
+
+        void grow(int extraCapacity = 0)
         {
-            m_capacity += m_capacity / 2;
+            m_capacity += m_capacity / 2 + extraCapacity;
 
             if (m_buffer == m_inlineBuffer) {
                 char* newBuffer = static_cast<char*>(fastMalloc(m_capacity));
diff --git a/assembler/AssemblerBufferWithConstantPool.h b/assembler/AssemblerBufferWithConstantPool.h
new file mode 100644 (file)
index 0000000..f15b7f3
--- /dev/null
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2009 University of Szeged
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AssemblerBufferWithConstantPool_h
+#define AssemblerBufferWithConstantPool_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER)
+
+#include "AssemblerBuffer.h"
+#include <wtf/SegmentedVector.h>
+
+namespace JSC {
+
+/*
+    On a constant pool 4 or 8 bytes data can be stored. The values can be
+    constants or addresses. The addresses should be 32 or 64 bits. The constants
+    should be double-precisions float or integer numbers which are hard to be
+    encoded as few machine instructions.
+
+    TODO: The pool is desinged to handle both 32 and 64 bits values, but
+    currently only the 4 bytes constants are implemented and tested.
+
+    The AssemblerBuffer can contain multiple constant pools. Each pool is inserted
+    into the instruction stream - protected by a jump instruction from the
+    execution flow.
+
+    The flush mechanism is called when no space remain to insert the next instruction
+    into the pool. Three values are used to determine when the constant pool itself
+    have to be inserted into the instruction stream (Assembler Buffer):
+
+    - maxPoolSize: size of the constant pool in bytes, this value cannot be
+        larger than the maximum offset of a PC relative memory load
+
+    - barrierSize: size of jump instruction in bytes which protects the
+        constant pool from execution
+
+    - maxInstructionSize: maximum length of a machine instruction in bytes
+
+    There are some callbacks which solve the target architecture specific
+    address handling:
+
+    - TYPE patchConstantPoolLoad(TYPE load, int value):
+        patch the 'load' instruction with the index of the constant in the
+        constant pool and return the patched instruction.
+
+    - void patchConstantPoolLoad(void* loadAddr, void* constPoolAddr):
+        patch the a PC relative load instruction at 'loadAddr' address with the
+        final relative offset. The offset can be computed with help of
+        'constPoolAddr' (the address of the constant pool) and index of the
+        constant (which is stored previously in the load instruction itself).
+
+    - TYPE placeConstantPoolBarrier(int size):
+        return with a constant pool barrier instruction which jumps over the
+        constant pool.
+
+    The 'put*WithConstant*' functions should be used to place a data into the
+    constant pool.
+*/
+
+template <int maxPoolSize, int barrierSize, int maxInstructionSize, class AssemblerType>
+class AssemblerBufferWithConstantPool: public AssemblerBuffer {
+    typedef WTF::SegmentedVector<uint32_t, 512> LoadOffsets;
+public:
+    enum {
+        UniqueConst,
+        ReusableConst,
+        UnusedEntry,
+    };
+
+    AssemblerBufferWithConstantPool()
+        : AssemblerBuffer()
+        , m_numConsts(0)
+        , m_maxDistance(maxPoolSize)
+        , m_lastConstDelta(0)
+    {
+        m_pool = static_cast<uint32_t*>(fastMalloc(maxPoolSize));
+        m_mask = static_cast<char*>(fastMalloc(maxPoolSize / sizeof(uint32_t)));
+    }
+
+    ~AssemblerBufferWithConstantPool()
+    {
+        fastFree(m_mask);
+        fastFree(m_pool);
+    }
+
+    void ensureSpace(int space)
+    {
+        flushIfNoSpaceFor(space);
+        AssemblerBuffer::ensureSpace(space);
+    }
+
+    void ensureSpace(int insnSpace, int constSpace)
+    {
+        flushIfNoSpaceFor(insnSpace, constSpace);
+        AssemblerBuffer::ensureSpace(insnSpace);
+    }
+
+    bool isAligned(int alignment)
+    {
+        flushIfNoSpaceFor(alignment);
+        return AssemblerBuffer::isAligned(alignment);
+    }
+
+    void putByteUnchecked(int value)
+    {
+        AssemblerBuffer::putByteUnchecked(value);
+        correctDeltas(1);
+    }
+
+    void putByte(int value)
+    {
+        flushIfNoSpaceFor(1);
+        AssemblerBuffer::putByte(value);
+        correctDeltas(1);
+    }
+
+    void putShortUnchecked(int value)
+    {
+        AssemblerBuffer::putShortUnchecked(value);
+        correctDeltas(2);
+    }
+
+    void putShort(int value)
+    {
+        flushIfNoSpaceFor(2);
+        AssemblerBuffer::putShort(value);
+        correctDeltas(2);
+    }
+
+    void putIntUnchecked(int value)
+    {
+        AssemblerBuffer::putIntUnchecked(value);
+        correctDeltas(4);
+    }
+
+    void putInt(int value)
+    {
+        flushIfNoSpaceFor(4);
+        AssemblerBuffer::putInt(value);
+        correctDeltas(4);
+    }
+
+    void putInt64Unchecked(int64_t value)
+    {
+        AssemblerBuffer::putInt64Unchecked(value);
+        correctDeltas(8);
+    }
+
+    int size()
+    {
+        flushIfNoSpaceFor(maxInstructionSize, sizeof(uint64_t));
+        return AssemblerBuffer::size();
+    }
+
+    void* executableCopy(ExecutablePool* allocator)
+    {
+        flushConstantPool(false);
+        return AssemblerBuffer::executableCopy(allocator);
+    }
+
+    void putIntWithConstantInt(uint32_t insn, uint32_t constant, bool isReusable = false)
+    {
+        flushIfNoSpaceFor(4, 4);
+
+        m_loadOffsets.append(AssemblerBuffer::size());
+        if (isReusable)
+            for (int i = 0; i < m_numConsts; ++i) {
+                if (m_mask[i] == ReusableConst && m_pool[i] == constant) {
+                    AssemblerBuffer::putInt(AssemblerType::patchConstantPoolLoad(insn, i));
+                    correctDeltas(4);
+                    return;
+                }
+            }
+
+        m_pool[m_numConsts] = constant;
+        m_mask[m_numConsts] = static_cast<char>(isReusable ? ReusableConst : UniqueConst);
+
+        AssemblerBuffer::putInt(AssemblerType::patchConstantPoolLoad(insn, m_numConsts));
+        ++m_numConsts;
+
+        correctDeltas(4, 4);
+    }
+
+    // This flushing mechanism can be called after any unconditional jumps.
+    void flushWithoutBarrier()
+    {
+        // Flush if constant pool is more than 60% full to avoid overuse of this function.
+        if (5 * m_numConsts > 3 * maxPoolSize / sizeof(uint32_t))
+            flushConstantPool(false);
+    }
+
+    uint32_t* poolAddress()
+    {
+        return m_pool;
+    }
+
+private:
+    void correctDeltas(int insnSize)
+    {
+        m_maxDistance -= insnSize;
+        m_lastConstDelta -= insnSize;
+        if (m_lastConstDelta < 0)
+            m_lastConstDelta = 0;
+    }
+
+    void correctDeltas(int insnSize, int constSize)
+    {
+        correctDeltas(insnSize);
+
+        m_maxDistance -= m_lastConstDelta;
+        m_lastConstDelta = constSize;
+    }
+
+    void flushConstantPool(bool useBarrier = true)
+    {
+        if (m_numConsts == 0)
+            return;
+        int alignPool = (AssemblerBuffer::size() + (useBarrier ? barrierSize : 0)) & (sizeof(uint64_t) - 1);
+
+        if (alignPool)
+            alignPool = sizeof(uint64_t) - alignPool;
+
+        // Callback to protect the constant pool from execution
+        if (useBarrier)
+            AssemblerBuffer::putInt(AssemblerType::placeConstantPoolBarrier(m_numConsts * sizeof(uint32_t) + alignPool));
+
+        if (alignPool) {
+            if (alignPool & 1)
+                AssemblerBuffer::putByte(AssemblerType::padForAlign8);
+            if (alignPool & 2)
+                AssemblerBuffer::putShort(AssemblerType::padForAlign16);
+            if (alignPool & 4)
+                AssemblerBuffer::putInt(AssemblerType::padForAlign32);
+        }
+
+        int constPoolOffset = AssemblerBuffer::size();
+        append(reinterpret_cast<char*>(m_pool), m_numConsts * sizeof(uint32_t));
+
+        // Patch each PC relative load
+        for (LoadOffsets::Iterator iter = m_loadOffsets.begin(); iter != m_loadOffsets.end(); ++iter) {
+            void* loadAddr = reinterpret_cast<void*>(m_buffer + *iter);
+            AssemblerType::patchConstantPoolLoad(loadAddr, reinterpret_cast<void*>(m_buffer + constPoolOffset));
+        }
+
+        m_loadOffsets.clear();
+        m_numConsts = 0;
+        m_maxDistance = maxPoolSize;
+    }
+
+    void flushIfNoSpaceFor(int nextInsnSize)
+    {
+        if (m_numConsts == 0)
+            return;
+        if ((m_maxDistance < nextInsnSize + m_lastConstDelta + barrierSize + (int)sizeof(uint32_t)))
+            flushConstantPool();
+    }
+
+    void flushIfNoSpaceFor(int nextInsnSize, int nextConstSize)
+    {
+        if (m_numConsts == 0)
+            return;
+        if ((m_maxDistance < nextInsnSize + m_lastConstDelta + barrierSize + (int)sizeof(uint32_t)) ||
+            (m_numConsts + nextConstSize / sizeof(uint32_t) >= maxPoolSize))
+            flushConstantPool();
+    }
+
+    uint32_t* m_pool;
+    char* m_mask;
+    LoadOffsets m_loadOffsets;
+
+    int m_numConsts;
+    int m_maxDistance;
+    int m_lastConstDelta;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // AssemblerBufferWithConstantPool_h
diff --git a/assembler/CodeLocation.h b/assembler/CodeLocation.h
new file mode 100644 (file)
index 0000000..b910b6f
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CodeLocation_h
+#define CodeLocation_h
+
+#include <wtf/Platform.h>
+
+#include <MacroAssemblerCodeRef.h>
+
+#if ENABLE(ASSEMBLER)
+
+namespace JSC {
+
+class CodeLocationInstruction;
+class CodeLocationLabel;
+class CodeLocationJump;
+class CodeLocationCall;
+class CodeLocationNearCall;
+class CodeLocationDataLabel32;
+class CodeLocationDataLabelPtr;
+
+// The CodeLocation* types are all pretty much do-nothing wrappers around
+// CodePtr (or MacroAssemblerCodePtr, to give it its full name).  These
+// classes only exist to provide type-safety when linking and patching code.
+//
+// The one new piece of functionallity introduced by these classes is the
+// ability to create (or put another way, to re-discover) another CodeLocation
+// at an offset from one you already know.  When patching code to optimize it
+// we often want to patch a number of instructions that are short, fixed
+// offsets apart.  To reduce memory overhead we will only retain a pointer to
+// one of the instructions, and we will use the *AtOffset methods provided by
+// CodeLocationCommon to find the other points in the code to modify.
+class CodeLocationCommon : public MacroAssemblerCodePtr {
+public:
+    CodeLocationInstruction instructionAtOffset(int offset);
+    CodeLocationLabel labelAtOffset(int offset);
+    CodeLocationJump jumpAtOffset(int offset);
+    CodeLocationCall callAtOffset(int offset);
+    CodeLocationNearCall nearCallAtOffset(int offset);
+    CodeLocationDataLabelPtr dataLabelPtrAtOffset(int offset);
+    CodeLocationDataLabel32 dataLabel32AtOffset(int offset);
+
+protected:
+    CodeLocationCommon()
+    {
+    }
+
+    CodeLocationCommon(MacroAssemblerCodePtr location)
+        : MacroAssemblerCodePtr(location)
+    {
+    }
+};
+
+class CodeLocationInstruction : public CodeLocationCommon {
+public:
+    CodeLocationInstruction() {}
+    explicit CodeLocationInstruction(MacroAssemblerCodePtr location)
+        : CodeLocationCommon(location) {}
+    explicit CodeLocationInstruction(void* location)
+        : CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
+};
+
+class CodeLocationLabel : public CodeLocationCommon {
+public:
+    CodeLocationLabel() {}
+    explicit CodeLocationLabel(MacroAssemblerCodePtr location)
+        : CodeLocationCommon(location) {}
+    explicit CodeLocationLabel(void* location)
+        : CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
+};
+
+class CodeLocationJump : public CodeLocationCommon {
+public:
+    CodeLocationJump() {}
+    explicit CodeLocationJump(MacroAssemblerCodePtr location)
+        : CodeLocationCommon(location) {}
+    explicit CodeLocationJump(void* location)
+        : CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
+};
+
+class CodeLocationCall : public CodeLocationCommon {
+public:
+    CodeLocationCall() {}
+    explicit CodeLocationCall(MacroAssemblerCodePtr location)
+        : CodeLocationCommon(location) {}
+    explicit CodeLocationCall(void* location)
+        : CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
+};
+
+class CodeLocationNearCall : public CodeLocationCommon {
+public:
+    CodeLocationNearCall() {}
+    explicit CodeLocationNearCall(MacroAssemblerCodePtr location)
+        : CodeLocationCommon(location) {}
+    explicit CodeLocationNearCall(void* location)
+        : CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
+};
+
+class CodeLocationDataLabel32 : public CodeLocationCommon {
+public:
+    CodeLocationDataLabel32() {}
+    explicit CodeLocationDataLabel32(MacroAssemblerCodePtr location)
+        : CodeLocationCommon(location) {}
+    explicit CodeLocationDataLabel32(void* location)
+        : CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
+};
+
+class CodeLocationDataLabelPtr : public CodeLocationCommon {
+public:
+    CodeLocationDataLabelPtr() {}
+    explicit CodeLocationDataLabelPtr(MacroAssemblerCodePtr location)
+        : CodeLocationCommon(location) {}
+    explicit CodeLocationDataLabelPtr(void* location)
+        : CodeLocationCommon(MacroAssemblerCodePtr(location)) {}
+};
+
+inline CodeLocationInstruction CodeLocationCommon::instructionAtOffset(int offset)
+{
+    ASSERT_VALID_CODE_OFFSET(offset);
+    return CodeLocationInstruction(reinterpret_cast<char*>(dataLocation()) + offset);
+}
+
+inline CodeLocationLabel CodeLocationCommon::labelAtOffset(int offset)
+{
+    ASSERT_VALID_CODE_OFFSET(offset);
+    return CodeLocationLabel(reinterpret_cast<char*>(dataLocation()) + offset);
+}
+
+inline CodeLocationJump CodeLocationCommon::jumpAtOffset(int offset)
+{
+    ASSERT_VALID_CODE_OFFSET(offset);
+    return CodeLocationJump(reinterpret_cast<char*>(dataLocation()) + offset);
+}
+
+inline CodeLocationCall CodeLocationCommon::callAtOffset(int offset)
+{
+    ASSERT_VALID_CODE_OFFSET(offset);
+    return CodeLocationCall(reinterpret_cast<char*>(dataLocation()) + offset);
+}
+
+inline CodeLocationNearCall CodeLocationCommon::nearCallAtOffset(int offset)
+{
+    ASSERT_VALID_CODE_OFFSET(offset);
+    return CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset);
+}
+
+inline CodeLocationDataLabelPtr CodeLocationCommon::dataLabelPtrAtOffset(int offset)
+{
+    ASSERT_VALID_CODE_OFFSET(offset);
+    return CodeLocationDataLabelPtr(reinterpret_cast<char*>(dataLocation()) + offset);
+}
+
+inline CodeLocationDataLabel32 CodeLocationCommon::dataLabel32AtOffset(int offset)
+{
+    ASSERT_VALID_CODE_OFFSET(offset);
+    return CodeLocationDataLabel32(reinterpret_cast<char*>(dataLocation()) + offset);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // CodeLocation_h
diff --git a/assembler/LinkBuffer.h b/assembler/LinkBuffer.h
new file mode 100644 (file)
index 0000000..6d08117
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef LinkBuffer_h
+#define LinkBuffer_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER)
+
+#include <MacroAssembler.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+// LinkBuffer:
+//
+// This class assists in linking code generated by the macro assembler, once code generation
+// has been completed, and the code has been copied to is final location in memory.  At this
+// time pointers to labels within the code may be resolved, and relative offsets to external
+// addresses may be fixed.
+//
+// Specifically:
+//   * Jump objects may be linked to external targets,
+//   * The address of Jump objects may taken, such that it can later be relinked.
+//   * The return address of a Call may be acquired.
+//   * The address of a Label pointing into the code may be resolved.
+//   * The value referenced by a DataLabel may be set.
+//
+class LinkBuffer : public Noncopyable {
+    typedef MacroAssemblerCodeRef CodeRef;
+    typedef MacroAssembler::Label Label;
+    typedef MacroAssembler::Jump Jump;
+    typedef MacroAssembler::JumpList JumpList;
+    typedef MacroAssembler::Call Call;
+    typedef MacroAssembler::DataLabel32 DataLabel32;
+    typedef MacroAssembler::DataLabelPtr DataLabelPtr;
+
+public:
+    // Note: Initialization sequence is significant, since executablePool is a PassRefPtr.
+    //       First, executablePool is copied into m_executablePool, then the initialization of
+    //       m_code uses m_executablePool, *not* executablePool, since this is no longer valid.
+    LinkBuffer(MacroAssembler* masm, PassRefPtr<ExecutablePool> executablePool)
+        : m_executablePool(executablePool)
+        , m_code(masm->m_assembler.executableCopy(m_executablePool.get()))
+        , m_size(masm->m_assembler.size())
+#ifndef NDEBUG
+        , m_completed(false)
+#endif
+    {
+    }
+
+    ~LinkBuffer()
+    {
+        ASSERT(m_completed);
+    }
+
+    // These methods are used to link or set values at code generation time.
+
+    void link(Call call, FunctionPtr function)
+    {
+        ASSERT(call.isFlagSet(Call::Linkable));
+        MacroAssembler::linkCall(code(), call, function);
+    }
+    
+    void link(Jump jump, CodeLocationLabel label)
+    {
+        MacroAssembler::linkJump(code(), jump, label);
+    }
+
+    void link(JumpList list, CodeLocationLabel label)
+    {
+        for (unsigned i = 0; i < list.m_jumps.size(); ++i)
+            MacroAssembler::linkJump(code(), list.m_jumps[i], label);
+    }
+
+    void patch(DataLabelPtr label, void* value)
+    {
+        MacroAssembler::linkPointer(code(), label.m_label, value);
+    }
+
+    void patch(DataLabelPtr label, CodeLocationLabel value)
+    {
+        MacroAssembler::linkPointer(code(), label.m_label, value.executableAddress());
+    }
+
+    // These methods are used to obtain handles to allow the code to be relinked / repatched later.
+
+    CodeLocationCall locationOf(Call call)
+    {
+        ASSERT(call.isFlagSet(Call::Linkable));
+        ASSERT(!call.isFlagSet(Call::Near));
+        return CodeLocationCall(MacroAssembler::getLinkerAddress(code(), call.m_jmp));
+    }
+
+    CodeLocationNearCall locationOfNearCall(Call call)
+    {
+        ASSERT(call.isFlagSet(Call::Linkable));
+        ASSERT(call.isFlagSet(Call::Near));
+        return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), call.m_jmp));
+    }
+
+    CodeLocationLabel locationOf(Label label)
+    {
+        return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), label.m_label));
+    }
+
+    CodeLocationDataLabelPtr locationOf(DataLabelPtr label)
+    {
+        return CodeLocationDataLabelPtr(MacroAssembler::getLinkerAddress(code(), label.m_label));
+    }
+
+    CodeLocationDataLabel32 locationOf(DataLabel32 label)
+    {
+        return CodeLocationDataLabel32(MacroAssembler::getLinkerAddress(code(), label.m_label));
+    }
+
+    // This method obtains the return address of the call, given as an offset from
+    // the start of the code.
+    unsigned returnAddressOffset(Call call)
+    {
+        return MacroAssembler::getLinkerCallReturnOffset(call);
+    }
+
+    // Upon completion of all patching either 'finalizeCode()' or 'finalizeCodeAddendum()' should be called
+    // once to complete generation of the code.  'finalizeCode()' is suited to situations
+    // where the executable pool must also be retained, the lighter-weight 'finalizeCodeAddendum()' is
+    // suited to adding to an existing allocation.
+    CodeRef finalizeCode()
+    {
+        performFinalization();
+
+        return CodeRef(m_code, m_executablePool, m_size);
+    }
+    CodeLocationLabel finalizeCodeAddendum()
+    {
+        performFinalization();
+
+        return CodeLocationLabel(code());
+    }
+
+private:
+    // Keep this private! - the underlying code should only be obtained externally via 
+    // finalizeCode() or finalizeCodeAddendum().
+    void* code()
+    {
+        return m_code;
+    }
+
+    void performFinalization()
+    {
+#ifndef NDEBUG
+        ASSERT(!m_completed);
+        m_completed = true;
+#endif
+
+        ExecutableAllocator::makeExecutable(code(), m_size);
+        ExecutableAllocator::cacheFlush(code(), m_size);
+    }
+
+    RefPtr<ExecutablePool> m_executablePool;
+    void* m_code;
+    size_t m_size;
+#ifndef NDEBUG
+    bool m_completed;
+#endif
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // LinkBuffer_h
index 9d24653444b5bbd9b853e637c4b00850ef072db6..43d27e7e1079243b9c39b981b6fbb2f6745c75c9 100644 (file)
 
 #if ENABLE(ASSEMBLER)
 
-#include "X86Assembler.h"
+#if PLATFORM_ARM_ARCH(7)
+#include "MacroAssemblerARMv7.h"
+namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; };
 
-namespace JSC {
+#elif PLATFORM(X86)
+#include "MacroAssemblerX86.h"
+namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; };
 
-class MacroAssembler {
-protected:
-    X86Assembler m_assembler;
+#elif PLATFORM(X86_64)
+#include "MacroAssemblerX86_64.h"
+namespace JSC { typedef MacroAssemblerX86_64 MacroAssemblerBase; };
 
-#if PLATFORM(X86_64)
-    static const X86::RegisterID scratchRegister = X86::r11;
+#else
+#error "The MacroAssembler is not supported on this platform."
 #endif
 
+
+namespace JSC {
+
+class MacroAssembler : public MacroAssemblerBase {
 public:
-    typedef X86::RegisterID RegisterID;
-
-    // Note: do not rely on values in this enum, these will change (to 0..3).
-    enum Scale {
-        TimesOne = 1,
-        TimesTwo = 2,
-        TimesFour = 4,
-        TimesEight = 8,
-#if PLATFORM(X86)
-        ScalePtr = TimesFour
-#endif
+
+    using MacroAssemblerBase::pop;
+    using MacroAssemblerBase::jump;
+    using MacroAssemblerBase::branch32;
+    using MacroAssemblerBase::branch16;
 #if PLATFORM(X86_64)
-        ScalePtr = TimesEight
+    using MacroAssemblerBase::branchPtr;
+    using MacroAssemblerBase::branchTestPtr;
 #endif
-    };
 
-    MacroAssembler()
+
+    // Platform agnostic onvenience functions,
+    // described in terms of other macro assembly methods.
+    void pop()
     {
+        addPtr(Imm32(sizeof(void*)), stackPointerRegister);
     }
     
-    size_t size() { return m_assembler.size(); }
-    void* copyCode(ExecutablePool* allocator)
+    void peek(RegisterID dest, int index = 0)
     {
-        return m_assembler.executableCopy(allocator);
+        loadPtr(Address(stackPointerRegister, (index * sizeof(void*))), dest);
     }
 
-
-    // Address:
-    //
-    // Describes a simple base-offset address.
-    struct Address {
-        explicit Address(RegisterID base, int32_t offset = 0)
-            : base(base)
-            , offset(offset)
-        {
-        }
-
-        RegisterID base;
-        int32_t offset;
-    };
-
-    // ImplicitAddress:
-    //
-    // This class is used for explicit 'load' and 'store' operations
-    // (as opposed to situations in which a memory operand is provided
-    // to a generic operation, such as an integer arithmetic instruction).
-    //
-    // In the case of a load (or store) operation we want to permit
-    // addresses to be implicitly constructed, e.g. the two calls:
-    //
-    //     load32(Address(addrReg), destReg);
-    //     load32(addrReg, destReg);
-    //
-    // Are equivalent, and the explicit wrapping of the Address in the former
-    // is unnecessary.
-    struct ImplicitAddress {
-        ImplicitAddress(RegisterID base)
-            : base(base)
-            , offset(0)
-        {
-        }
-
-        ImplicitAddress(Address address)
-            : base(address.base)
-            , offset(address.offset)
-        {
-        }
-
-        RegisterID base;
-        int32_t offset;
-    };
-
-    // BaseIndex:
-    //
-    // Describes a complex addressing mode.
-    struct BaseIndex {
-        BaseIndex(RegisterID base, RegisterID index, Scale scale, int32_t offset = 0)
-            : base(base)
-            , index(index)
-            , scale(scale)
-            , offset(offset)
-        {
-        }
-
-        RegisterID base;
-        RegisterID index;
-        Scale scale;
-        int32_t offset;
-    };
-
-    // AbsoluteAddress:
-    //
-    // Describes an memory operand given by a pointer.  For regular load & store
-    // operations an unwrapped void* will be used, rather than using this.
-    struct AbsoluteAddress {
-        explicit AbsoluteAddress(void* ptr)
-            : m_ptr(ptr)
-        {
-        }
-
-        void* m_ptr;
-    };
-
-
-    class Jump;
-    class PatchBuffer;
-
-    // DataLabelPtr:
-    //
-    // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
-    // patched after the code has been generated.
-    class DataLabelPtr {
-        friend class MacroAssembler;
-        friend class PatchBuffer;
-
-    public:
-        DataLabelPtr()
-        {
-        }
-
-        DataLabelPtr(MacroAssembler* masm)
-            : m_label(masm->m_assembler.label())
-        {
-        }
-
-        static void patch(void* address, void* value)
-        {
-            X86Assembler::patchPointer(reinterpret_cast<intptr_t>(address), reinterpret_cast<intptr_t>(value));
-        }
-        
-    private:
-        X86Assembler::JmpDst m_label;
-    };
-
-    // DataLabel32:
-    //
-    // A DataLabelPtr is used to refer to a location in the code containing a pointer to be
-    // patched after the code has been generated.
-    class DataLabel32 {
-        friend class MacroAssembler;
-        friend class PatchBuffer;
-
-    public:
-        DataLabel32()
-        {
-        }
-
-        DataLabel32(MacroAssembler* masm)
-            : m_label(masm->m_assembler.label())
-        {
-        }
-
-        static void patch(void* address, int32_t value)
-        {
-            X86Assembler::patchImmediate(reinterpret_cast<intptr_t>(address), value);
-        }
-
-    private:
-        X86Assembler::JmpDst m_label;
-    };
-
-    // Label:
-    //
-    // A Label records a point in the generated instruction stream, typically such that
-    // it may be used as a destination for a jump.
-    class Label {
-        friend class Jump;
-        friend class MacroAssembler;
-        friend class PatchBuffer;
-
-    public:
-        Label()
-        {
-        }
-
-        Label(MacroAssembler* masm)
-            : m_label(masm->m_assembler.label())
-        {
-        }
-        
-        // FIXME: transitionary method, while we replace JmpSrces with Jumps.
-        operator X86Assembler::JmpDst()
-        {
-            return m_label;
-        }
-
-    private:
-        X86Assembler::JmpDst m_label;
-    };
-
-
-    // Jump:
-    //
-    // A jump object is a reference to a jump instruction that has been planted
-    // into the code buffer - it is typically used to link the jump, setting the
-    // relative offset such that when executed it will jump to the desired
-    // destination.
-    //
-    // Jump objects retain a pointer to the assembler for syntactic purposes -
-    // to allow the jump object to be able to link itself, e.g.:
-    //
-    //     Jump forwardsBranch = jne32(Imm32(0), reg1);
-    //     // ...
-    //     forwardsBranch.link();
-    //
-    // Jumps may also be linked to a Label.
-    class Jump {
-        friend class PatchBuffer;
-        friend class MacroAssembler;
-
-    public:
-        Jump()
-        {
-        }
-        
-        // FIXME: transitionary method, while we replace JmpSrces with Jumps.
-        Jump(X86Assembler::JmpSrc jmp)
-            : m_jmp(jmp)
-        {
-        }
-        
-        void link(MacroAssembler* masm)
-        {
-            masm->m_assembler.link(m_jmp, masm->m_assembler.label());
-        }
-        
-        void linkTo(Label label, MacroAssembler* masm)
-        {
-            masm->m_assembler.link(m_jmp, label.m_label);
-        }
-        
-        // FIXME: transitionary method, while we replace JmpSrces with Jumps.
-        operator X86Assembler::JmpSrc()
-        {
-            return m_jmp;
-        }
-
-        static void patch(void* address, void* destination)
-        {
-            X86Assembler::patchBranchOffset(reinterpret_cast<intptr_t>(address), destination);
-        }
-
-    private:
-        X86Assembler::JmpSrc m_jmp;
-    };
-
-    // JumpList:
-    //
-    // A JumpList is a set of Jump objects.
-    // All jumps in the set will be linked to the same destination.
-    class JumpList {
-        friend class PatchBuffer;
-
-    public:
-        void link(MacroAssembler* masm)
-        {
-            size_t size = m_jumps.size();
-            for (size_t i = 0; i < size; ++i)
-                m_jumps[i].link(masm);
-            m_jumps.clear();
-        }
-        
-        void linkTo(Label label, MacroAssembler* masm)
-        {
-            size_t size = m_jumps.size();
-            for (size_t i = 0; i < size; ++i)
-                m_jumps[i].linkTo(label, masm);
-            m_jumps.clear();
-        }
-        
-        void append(Jump jump)
-        {
-            m_jumps.append(jump);
-        }
-        
-        void append(JumpList& other)
-        {
-            m_jumps.append(other.m_jumps.begin(), other.m_jumps.size());
-        }
-
-        bool empty()
-        {
-            return !m_jumps.size();
-        }
-
-    private:
-        Vector<Jump, 16> m_jumps;
-    };
-
-
-    // PatchBuffer:
-    //
-    // This class assists in linking code generated by the macro assembler, once code generation
-    // has been completed, and the code has been copied to is final location in memory.  At this
-    // time pointers to labels within the code may be resolved, and relative offsets to external
-    // addresses may be fixed.
-    //
-    // Specifically:
-    //   * Jump objects may be linked to external targets,
-    //   * The address of Jump objects may taken, such that it can later be relinked.
-    //   * The return address of a Jump object representing a call may be acquired.
-    //   * The address of a Label pointing into the code may be resolved.
-    //   * The value referenced by a DataLabel may be fixed.
-    //
-    // FIXME: distinguish between Calls & Jumps (make a specific call to obtain the return
-    // address of calls, as opposed to a point that can be used to later relink a Jump -
-    // possibly wrap the later up in an object that can do just that).
-    class PatchBuffer {
-    public:
-        PatchBuffer(void* code)
-            : m_code(code)
-        {
-        }
-
-        void link(Jump jump, void* target)
-        {
-            X86Assembler::link(m_code, jump.m_jmp, target);
-        }
-
-        void link(JumpList list, void* target)
-        {
-            for (unsigned i = 0; i < list.m_jumps.size(); ++i)
-                X86Assembler::link(m_code, list.m_jumps[i], target);
-        }
-
-        void* addressOf(Jump jump)
-        {
-            return X86Assembler::getRelocatedAddress(m_code, jump.m_jmp);
-        }
-
-        void* addressOf(Label label)
-        {
-            return X86Assembler::getRelocatedAddress(m_code, label.m_label);
-        }
-
-        void* addressOf(DataLabelPtr label)
-        {
-            return X86Assembler::getRelocatedAddress(m_code, label.m_label);
-        }
-
-        void* addressOf(DataLabel32 label)
-        {
-            return X86Assembler::getRelocatedAddress(m_code, label.m_label);
-        }
-
-        void setPtr(DataLabelPtr label, void* value)
-        {
-            X86Assembler::patchAddress(m_code, label.m_label, value);
-        }
-
-    private:
-        void* m_code;
-    };
-
-    // ImmPtr:
-    //
-    // A pointer sized immediate operand to an instruction - this is wrapped
-    // in a class requiring explicit construction in order to differentiate
-    // from pointers used as absolute addresses to memory operations
-    struct ImmPtr {
-        explicit ImmPtr(void* value)
-            : m_value(value)
-        {
-        }
-
-        intptr_t asIntptr()
-        {
-            return reinterpret_cast<intptr_t>(m_value);
-        }
-
-        void* m_value;
-    };
-
-
-    // Imm32:
-    //
-    // A 32bit immediate operand to an instruction - this is wrapped in a
-    // class requiring explicit construction in order to prevent RegisterIDs
-    // (which are implemented as an enum) from accidentally being passed as
-    // immediate values.
-    struct Imm32 {
-        explicit Imm32(int32_t value)
-            : m_value(value)
-        {
-        }
-
-#if PLATFORM(X86)
-        explicit Imm32(ImmPtr ptr)
-            : m_value(ptr.asIntptr())
-        {
-        }
-#endif
-
-        int32_t m_value;
-    };
-
-    // Integer arithmetic operations:
-    //
-    // Operations are typically two operand - operation(source, srcDst)
-    // For many operations the source may be an Imm32, the srcDst operand
-    // may often be a memory location (explictly described using an Address
-    // object).
-
-    void addPtr(RegisterID src, RegisterID dest)
+    void poke(RegisterID src, int index = 0)
     {
-#if PLATFORM(X86_64)
-        m_assembler.addq_rr(src, dest);
-#else
-        add32(src, dest);
-#endif
+        storePtr(src, Address(stackPointerRegister, (index * sizeof(void*))));
     }
 
-    void addPtr(Imm32 imm, RegisterID srcDest)
+    void poke(Imm32 value, int index = 0)
     {
-#if PLATFORM(X86_64)
-        m_assembler.addq_ir(imm.m_value, srcDest);
-#else
-        add32(imm, srcDest);
-#endif
+        store32(value, Address(stackPointerRegister, (index * sizeof(void*))));
     }
 
-    void addPtr(ImmPtr imm, RegisterID dest)
+    void poke(ImmPtr imm, int index = 0)
     {
-#if PLATFORM(X86_64)
-        move(imm, scratchRegister);
-        m_assembler.addq_rr(scratchRegister, dest);
-#else
-        add32(Imm32(imm), dest);
-#endif
+        storePtr(imm, Address(stackPointerRegister, (index * sizeof(void*))));
     }
 
-    void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
-    {
-        m_assembler.leal_mr(imm.m_value, src, dest);
-    }
 
-    void add32(RegisterID src, RegisterID dest)
+    // Backwards banches, these are currently all implemented using existing forwards branch mechanisms.
+    void branchPtr(Condition cond, RegisterID op1, ImmPtr imm, Label target)
     {
-        m_assembler.addl_rr(src, dest);
+        branchPtr(cond, op1, imm).linkTo(target, this);
     }
 
-    void add32(Imm32 imm, Address address)
+    void branch32(Condition cond, RegisterID op1, RegisterID op2, Label target)
     {
-        m_assembler.addl_im(imm.m_value, address.offset, address.base);
+        branch32(cond, op1, op2).linkTo(target, this);
     }
 
-    void add32(Imm32 imm, RegisterID dest)
+    void branch32(Condition cond, RegisterID op1, Imm32 imm, Label target)
     {
-        m_assembler.addl_ir(imm.m_value, dest);
+        branch32(cond, op1, imm).linkTo(target, this);
     }
-    
-    void add32(Imm32 imm, AbsoluteAddress address)
+
+    void branch32(Condition cond, RegisterID left, Address right, Label target)
     {
-#if PLATFORM(X86_64)
-        move(ImmPtr(address.m_ptr), scratchRegister);
-        add32(imm, Address(scratchRegister));
-#else
-        m_assembler.addl_im(imm.m_value, address.m_ptr);
-#endif
+        branch32(cond, left, right).linkTo(target, this);
     }
-    
-    void add32(Address src, RegisterID dest)
+
+    void branch16(Condition cond, BaseIndex left, RegisterID right, Label target)
     {
-        m_assembler.addl_mr(src.offset, src.base, dest);
+        branch16(cond, left, right).linkTo(target, this);
     }
     
-    void andPtr(RegisterID src, RegisterID dest)
+    void branchTestPtr(Condition cond, RegisterID reg, Label target)
     {
-#if PLATFORM(X86_64)
-        m_assembler.andq_rr(src, dest);
-#else
-        and32(src, dest);
-#endif
+        branchTestPtr(cond, reg).linkTo(target, this);
     }
 
-    void andPtr(Imm32 imm, RegisterID srcDest)
+    void jump(Label target)
     {
-#if PLATFORM(X86_64)
-        m_assembler.andq_ir(imm.m_value, srcDest);
-#else
-        and32(imm, srcDest);
-#endif
+        jump().linkTo(target, this);
     }
 
-    void and32(RegisterID src, RegisterID dest)
-    {
-        m_assembler.andl_rr(src, dest);
-    }
 
-    void and32(Imm32 imm, RegisterID dest)
+    // Ptr methods
+    // On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents.
+#if !PLATFORM(X86_64)
+    void addPtr(RegisterID src, RegisterID dest)
     {
-        m_assembler.andl_ir(imm.m_value, dest);
+        add32(src, dest);
     }
 
-    void lshift32(Imm32 imm, RegisterID dest)
-    {
-        m_assembler.shll_i8r(imm.m_value, dest);
-    }
-    
-    void lshift32(RegisterID shift_amount, RegisterID dest)
+    void addPtr(Imm32 imm, RegisterID srcDest)
     {
-        // On x86 we can only shift by ecx; if asked to shift by another register we'll
-        // need rejig the shift amount into ecx first, and restore the registers afterwards.
-        if (shift_amount != X86::ecx) {
-            swap(shift_amount, X86::ecx);
-
-            // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
-            if (dest == shift_amount)
-                m_assembler.shll_CLr(X86::ecx);
-            // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
-            else if (dest == X86::ecx)
-                m_assembler.shll_CLr(shift_amount);
-            // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
-            else
-                m_assembler.shll_CLr(dest);
-        
-            swap(shift_amount, X86::ecx);
-        } else
-            m_assembler.shll_CLr(dest);
+        add32(imm, srcDest);
     }
-    
-    // Take the value from dividend, divide it by divisor, and put the remainder in remainder.
-    // For now, this operation has specific register requirements, and the three register must
-    // be unique.  It is unfortunate to expose this in the MacroAssembler interface, however
-    // given the complexity to fix, the fact that it is not uncommmon  for processors to have
-    // specific register requirements on this operation (e.g. Mips result in 'hi'), or to not
-    // support a hardware divide at all, it may not be 
-    void mod32(RegisterID divisor, RegisterID dividend, RegisterID remainder)
-    {
-#ifdef NDEBUG
-#pragma unused(dividend,remainder)
-#else
-        ASSERT((dividend == X86::eax) && (remainder == X86::edx));
-        ASSERT((dividend != divisor) && (remainder != divisor));
-#endif
 
-        m_assembler.cdq();
-        m_assembler.idivl_r(divisor);
+    void addPtr(ImmPtr imm, RegisterID dest)
+    {
+        add32(Imm32(imm), dest);
     }
 
-    void mul32(RegisterID src, RegisterID dest)
+    void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
     {
-        m_assembler.imull_rr(src, dest);
+        add32(imm, src, dest);
     }
-    
-    void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+
+    void andPtr(RegisterID src, RegisterID dest)
     {
-        m_assembler.imull_i32r(src, imm.m_value, dest);
+        and32(src, dest);
     }
-    
-    void not32(RegisterID srcDest)
+
+    void andPtr(Imm32 imm, RegisterID srcDest)
     {
-        m_assembler.notl_r(srcDest);
+        and32(imm, srcDest);
     }
-    
+
     void orPtr(RegisterID src, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.orq_rr(src, dest);
-#else
         or32(src, dest);
-#endif
     }
 
     void orPtr(ImmPtr imm, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        move(imm, scratchRegister);
-        m_assembler.orq_rr(scratchRegister, dest);
-#else
         or32(Imm32(imm), dest);
-#endif
     }
 
     void orPtr(Imm32 imm, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.orq_ir(imm.m_value, dest);
-#else
         or32(imm, dest);
-#endif
-    }
-
-    void or32(RegisterID src, RegisterID dest)
-    {
-        m_assembler.orl_rr(src, dest);
-    }
-
-    void or32(Imm32 imm, RegisterID dest)
-    {
-        m_assembler.orl_ir(imm.m_value, dest);
     }
 
     void rshiftPtr(RegisterID shift_amount, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        // On x86 we can only shift by ecx; if asked to shift by another register we'll
-        // need rejig the shift amount into ecx first, and restore the registers afterwards.
-        if (shift_amount != X86::ecx) {
-            swap(shift_amount, X86::ecx);
-
-            // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
-            if (dest == shift_amount)
-                m_assembler.sarq_CLr(X86::ecx);
-            // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
-            else if (dest == X86::ecx)
-                m_assembler.sarq_CLr(shift_amount);
-            // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
-            else
-                m_assembler.sarq_CLr(dest);
-        
-            swap(shift_amount, X86::ecx);
-        } else
-            m_assembler.sarq_CLr(dest);
-#else
         rshift32(shift_amount, dest);
-#endif
     }
 
     void rshiftPtr(Imm32 imm, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.sarq_i8r(imm.m_value, dest);
-#else
         rshift32(imm, dest);
-#endif
-    }
-
-    void rshift32(RegisterID shift_amount, RegisterID dest)
-    {
-        // On x86 we can only shift by ecx; if asked to shift by another register we'll
-        // need rejig the shift amount into ecx first, and restore the registers afterwards.
-        if (shift_amount != X86::ecx) {
-            swap(shift_amount, X86::ecx);
-
-            // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
-            if (dest == shift_amount)
-                m_assembler.sarl_CLr(X86::ecx);
-            // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
-            else if (dest == X86::ecx)
-                m_assembler.sarl_CLr(shift_amount);
-            // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
-            else
-                m_assembler.sarl_CLr(dest);
-        
-            swap(shift_amount, X86::ecx);
-        } else
-            m_assembler.sarl_CLr(dest);
-    }
-
-    void rshift32(Imm32 imm, RegisterID dest)
-    {
-        m_assembler.sarl_i8r(imm.m_value, dest);
     }
 
     void subPtr(RegisterID src, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.subq_rr(src, dest);
-#else
         sub32(src, dest);
-#endif
     }
     
     void subPtr(Imm32 imm, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.subq_ir(imm.m_value, dest);
-#else
         sub32(imm, dest);
-#endif
     }
     
     void subPtr(ImmPtr imm, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        move(imm, scratchRegister);
-        m_assembler.subq_rr(scratchRegister, dest);
-#else
         sub32(Imm32(imm), dest);
-#endif
-    }
-
-    void sub32(RegisterID src, RegisterID dest)
-    {
-        m_assembler.subl_rr(src, dest);
-    }
-    
-    void sub32(Imm32 imm, RegisterID dest)
-    {
-        m_assembler.subl_ir(imm.m_value, dest);
-    }
-    
-    void sub32(Imm32 imm, Address address)
-    {
-        m_assembler.subl_im(imm.m_value, address.offset, address.base);
-    }
-
-    void sub32(Imm32 imm, AbsoluteAddress address)
-    {
-#if PLATFORM(X86_64)
-        move(ImmPtr(address.m_ptr), scratchRegister);
-        sub32(imm, Address(scratchRegister));
-#else
-        m_assembler.subl_im(imm.m_value, address.m_ptr);
-#endif
-    }
-
-    void sub32(Address src, RegisterID dest)
-    {
-        m_assembler.subl_mr(src.offset, src.base, dest);
     }
 
     void xorPtr(RegisterID src, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.xorq_rr(src, dest);
-#else
         xor32(src, dest);
-#endif
     }
 
     void xorPtr(Imm32 imm, RegisterID srcDest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.xorq_ir(imm.m_value, srcDest);
-#else
         xor32(imm, srcDest);
-#endif
-    }
-
-    void xor32(RegisterID src, RegisterID dest)
-    {
-        m_assembler.xorl_rr(src, dest);
-    }
-
-    void xor32(Imm32 imm, RegisterID srcDest)
-    {
-        m_assembler.xorl_ir(imm.m_value, srcDest);
     }
-    
 
-    // Memory access operations:
-    //
-    // Loads are of the form load(address, destination) and stores of the form
-    // store(source, address).  The source for a store may be an Imm32.  Address
-    // operand objects to loads and store will be implicitly constructed if a
-    // register is passed.
 
     void loadPtr(ImplicitAddress address, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.movq_mr(address.offset, address.base, dest);
-#else
         load32(address, dest);
-#endif
-    }
-
-    DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.movq_mr_disp32(address.offset, address.base, dest);
-        return DataLabel32(this);
-#else
-        m_assembler.movl_mr_disp32(address.offset, address.base, dest);
-        return DataLabel32(this);
-#endif
     }
 
     void loadPtr(BaseIndex address, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest);
-#else
         load32(address, dest);
-#endif
     }
 
     void loadPtr(void* address, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        if (dest == X86::eax)
-            m_assembler.movq_mEAX(address);
-        else {
-            move(X86::eax, dest);
-            m_assembler.movq_mEAX(address);
-            swap(X86::eax, dest);
-        }
-#else
         load32(address, dest);
-#endif
-    }
-
-    void load32(ImplicitAddress address, RegisterID dest)
-    {
-        m_assembler.movl_mr(address.offset, address.base, dest);
-    }
-
-    void load32(BaseIndex address, RegisterID dest)
-    {
-        m_assembler.movl_mr(address.offset, address.base, address.index, address.scale, dest);
     }
 
-    void load32(void* address, RegisterID dest)
+    DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        if (dest == X86::eax)
-            m_assembler.movl_mEAX(address);
-        else {
-            move(X86::eax, dest);
-            m_assembler.movl_mEAX(address);
-            swap(X86::eax, dest);
-        }
-#else
-        m_assembler.movl_mr(address, dest);
-#endif
+        return load32WithAddressOffsetPatch(address, dest);
     }
 
-    void load16(BaseIndex address, RegisterID dest)
+    void setPtr(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
     {
-        m_assembler.movzwl_mr(address.offset, address.base, address.index, address.scale, dest);
+        set32(cond, left, right, dest);
     }
 
     void storePtr(RegisterID src, ImplicitAddress address)
     {
-#if PLATFORM(X86_64)
-        m_assembler.movq_rm(src, address.offset, address.base);
-#else
         store32(src, address);
-#endif
     }
 
-    DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
+    void storePtr(RegisterID src, BaseIndex address)
     {
-#if PLATFORM(X86_64)
-        m_assembler.movq_rm_disp32(src, address.offset, address.base);
-        return DataLabel32(this);
-#else
-        m_assembler.movl_rm_disp32(src, address.offset, address.base);
-        return DataLabel32(this);
-#endif
+        store32(src, address);
     }
 
-    void storePtr(RegisterID src, BaseIndex address)
+    void storePtr(RegisterID src, void* address)
     {
-#if PLATFORM(X86_64)
-        m_assembler.movq_rm(src, address.offset, address.base, address.index, address.scale);
-#else
         store32(src, address);
-#endif
     }
 
     void storePtr(ImmPtr imm, ImplicitAddress address)
     {
-#if PLATFORM(X86_64)
-        move(imm, scratchRegister);
-        storePtr(scratchRegister, address);
-#else
-        m_assembler.movl_i32m(imm.asIntptr(), address.offset, address.base);
-#endif
+        store32(Imm32(imm), address);
     }
 
-#if !PLATFORM(X86_64)
     void storePtr(ImmPtr imm, void* address)
     {
         store32(Imm32(imm), address);
     }
-#endif
-
-    DataLabelPtr storePtrWithPatch(Address address)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.movq_i64r(0, scratchRegister);
-        DataLabelPtr label(this);
-        storePtr(scratchRegister, address);
-        return label;
-#else
-        m_assembler.movl_i32m(0, address.offset, address.base);
-        return DataLabelPtr(this);
-#endif
-    }
 
-    void store32(RegisterID src, ImplicitAddress address)
+    DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
     {
-        m_assembler.movl_rm(src, address.offset, address.base);
+        return store32WithAddressOffsetPatch(src, address);
     }
 
-    void store32(RegisterID src, BaseIndex address)
-    {
-        m_assembler.movl_rm(src, address.offset, address.base, address.index, address.scale);
-    }
 
-    void store32(Imm32 imm, ImplicitAddress address)
+    Jump branchPtr(Condition cond, RegisterID left, RegisterID right)
     {
-        m_assembler.movl_i32m(imm.m_value, address.offset, address.base);
-    }
-    
-    void store32(Imm32 imm, void* address)
-    {
-#if PLATFORM(X86_64)
-        move(X86::eax, scratchRegister);
-        move(imm, X86::eax);
-        m_assembler.movl_EAXm(address);
-        move(scratchRegister, X86::eax);
-#else
-        m_assembler.movl_i32m(imm.m_value, address);
-#endif
+        return branch32(cond, left, right);
     }
 
-
-    // Stack manipulation operations:
-    //
-    // The ABI is assumed to provide a stack abstraction to memory,
-    // containing machine word sized units of data.  Push and pop
-    // operations add and remove a single register sized unit of data
-    // to or from the stack.  Peek and poke operations read or write
-    // values on the stack, without moving the current stack position.
-    
-    void pop(RegisterID dest)
+    Jump branchPtr(Condition cond, RegisterID left, ImmPtr right)
     {
-        m_assembler.pop_r(dest);
+        return branch32(cond, left, Imm32(right));
     }
 
-    void push(RegisterID src)
+    Jump branchPtr(Condition cond, RegisterID left, Address right)
     {
-        m_assembler.push_r(src);
+        return branch32(cond, left, right);
     }
 
-    void push(Address address)
+    Jump branchPtr(Condition cond, Address left, RegisterID right)
     {
-        m_assembler.push_m(address.offset, address.base);
+        return branch32(cond, left, right);
     }
 
-    void push(Imm32 imm)
+    Jump branchPtr(Condition cond, AbsoluteAddress left, RegisterID right)
     {
-        m_assembler.push_i32(imm.m_value);
+        return branch32(cond, left, right);
     }
 
-    void pop()
-    {
-        addPtr(Imm32(sizeof(void*)), X86::esp);
-    }
-    
-    void peek(RegisterID dest, int index = 0)
+    Jump branchPtr(Condition cond, Address left, ImmPtr right)
     {
-        loadPtr(Address(X86::esp, (index * sizeof(void *))), dest);
+        return branch32(cond, left, Imm32(right));
     }
 
-    void poke(RegisterID src, int index = 0)
+    Jump branchPtr(Condition cond, AbsoluteAddress left, ImmPtr right)
     {
-        storePtr(src, Address(X86::esp, (index * sizeof(void *))));
+        return branch32(cond, left, Imm32(right));
     }
 
-    void poke(Imm32 value, int index = 0)
+    Jump branchTestPtr(Condition cond, RegisterID reg, RegisterID mask)
     {
-        store32(value, Address(X86::esp, (index * sizeof(void *))));
+        return branchTest32(cond, reg, mask);
     }
 
-    void poke(ImmPtr imm, int index = 0)
+    Jump branchTestPtr(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
     {
-        storePtr(imm, Address(X86::esp, (index * sizeof(void *))));
+        return branchTest32(cond, reg, mask);
     }
 
-    // Register move operations:
-    //
-    // Move values in registers.
-
-    void move(Imm32 imm, RegisterID dest)
+    Jump branchTestPtr(Condition cond, Address address, Imm32 mask = Imm32(-1))
     {
-        // Note: on 64-bit the Imm32 value is zero extended into the register, it
-        // may be useful to have a separate version that sign extends the value?
-        if (!imm.m_value)
-            m_assembler.xorl_rr(dest, dest);
-        else
-            m_assembler.movl_i32r(imm.m_value, dest);
+        return branchTest32(cond, address, mask);
     }
 
-    void move(RegisterID src, RegisterID dest)
+    Jump branchTestPtr(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
     {
-        // Note: on 64-bit this is is a full register move; perhaps it would be
-        // useful to have separate move32 & movePtr, with move32 zero extending?
-#if PLATFORM(X86_64)
-        m_assembler.movq_rr(src, dest);
-#else
-        m_assembler.movl_rr(src, dest);
-#endif
+        return branchTest32(cond, address, mask);
     }
 
-    void move(ImmPtr imm, RegisterID dest)
-    {
-#if PLATFORM(X86_64)
-        if (CAN_SIGN_EXTEND_U32_64(imm.asIntptr()))
-            m_assembler.movl_i32r(static_cast<int32_t>(imm.asIntptr()), dest);
-        else
-            m_assembler.movq_i64r(imm.asIntptr(), dest);
-#else
-        m_assembler.movl_i32r(imm.asIntptr(), dest);
-#endif
-    }
 
-    void swap(RegisterID reg1, RegisterID reg2)
+    Jump branchAddPtr(Condition cond, RegisterID src, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.xchgq_rr(reg1, reg2);
-#else
-        m_assembler.xchgl_rr(reg1, reg2);
-#endif
+        return branchAdd32(cond, src, dest);
     }
 
-    void signExtend32ToPtr(RegisterID src, RegisterID dest)
+    Jump branchSubPtr(Condition cond, Imm32 imm, RegisterID dest)
     {
-#if PLATFORM(X86_64)
-        m_assembler.movsxd_rr(src, dest);
-#else
-        if (src != dest)
-            move(src, dest);
-#endif
+        return branchSub32(cond, imm, dest);
     }
-
-    void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.movl_rr(src, dest);
-#else
-        if (src != dest)
-            move(src, dest);
 #endif
-    }
-
-
-    // Forwards / external control flow operations:
-    //
-    // This set of jump and conditional branch operations return a Jump
-    // object which may linked at a later point, allow forwards jump,
-    // or jumps that will require external linkage (after the code has been
-    // relocated).
-    //
-    // For branches, signed <, >, <= and >= are denoted as l, g, le, and ge
-    // respecitvely, for unsigned comparisons the names b, a, be, and ae are
-    // used (representing the names 'below' and 'above').
-    //
-    // Operands to the comparision are provided in the expected order, e.g.
-    // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
-    // treated as a signed 32bit value, is less than or equal to 5.
-    //
-    // jz and jnz test whether the first operand is equal to zero, and take
-    // an optional second operand of a mask under which to perform the test.
-
-private:
-    void compareImm32ForBranch(RegisterID left, int32_t right)
-    {
-        m_assembler.cmpl_ir(right, left);
-    }
-
-    void compareImm32ForBranchEquality(RegisterID reg, int32_t imm)
-    {
-        if (!imm)
-            m_assembler.testl_rr(reg, reg);
-        else
-            m_assembler.cmpl_ir(imm, reg);
-    }
-
-    void compareImm32ForBranchEquality(Address address, int32_t imm)
-    {
-        m_assembler.cmpl_im(imm, address.offset, address.base);
-    }
-
-    void testImm32(RegisterID reg, Imm32 mask)
-    {
-        // if we are only interested in the low seven bits, this can be tested with a testb
-        if (mask.m_value == -1)
-            m_assembler.testl_rr(reg, reg);
-        else if ((mask.m_value & ~0x7f) == 0)
-            m_assembler.testb_i8r(mask.m_value, reg);
-        else
-            m_assembler.testl_i32r(mask.m_value, reg);
-    }
-
-    void testImm32(Address address, Imm32 mask)
-    {
-        if (mask.m_value == -1)
-            m_assembler.cmpl_im(0, address.offset, address.base);
-        else
-            m_assembler.testl_i32m(mask.m_value, address.offset, address.base);
-    }
 
-    void testImm32(BaseIndex address, Imm32 mask)
-    {
-        if (mask.m_value == -1)
-            m_assembler.cmpl_im(0, address.offset, address.base, address.index, address.scale);
-        else
-            m_assembler.testl_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
-    }
-
-#if PLATFORM(X86_64)
-    void compareImm64ForBranch(RegisterID left, int32_t right)
-    {
-        m_assembler.cmpq_ir(right, left);
-    }
-
-    void compareImm64ForBranchEquality(RegisterID reg, int32_t imm)
-    {
-        if (!imm)
-            m_assembler.testq_rr(reg, reg);
-        else
-            m_assembler.cmpq_ir(imm, reg);
-    }
-
-    void testImm64(RegisterID reg, Imm32 mask)
-    {
-        // if we are only interested in the low seven bits, this can be tested with a testb
-        if (mask.m_value == -1)
-            m_assembler.testq_rr(reg, reg);
-        else if ((mask.m_value & ~0x7f) == 0)
-            m_assembler.testb_i8r(mask.m_value, reg);
-        else
-            m_assembler.testq_i32r(mask.m_value, reg);
-    }
-
-    void testImm64(Address address, Imm32 mask)
-    {
-        if (mask.m_value == -1)
-            m_assembler.cmpq_im(0, address.offset, address.base);
-        else
-            m_assembler.testq_i32m(mask.m_value, address.offset, address.base);
-    }
-
-    void testImm64(BaseIndex address, Imm32 mask)
-    {
-        if (mask.m_value == -1)
-            m_assembler.cmpq_im(0, address.offset, address.base, address.index, address.scale);
-        else
-            m_assembler.testq_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
-    }
-#endif
-
-public:
-    Jump ja32(RegisterID left, Imm32 right)
-    {
-        compareImm32ForBranch(left, right.m_value);
-        return Jump(m_assembler.ja());
-    }
-    
-    Jump jaePtr(RegisterID left, RegisterID right)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.cmpq_rr(right, left);
-        return Jump(m_assembler.jae());
-#else
-        return jae32(left, right);
-#endif
-    }
-
-    Jump jaePtr(RegisterID reg, ImmPtr ptr)
-    {
-#if PLATFORM(X86_64)
-        intptr_t imm = ptr.asIntptr();
-        if (CAN_SIGN_EXTEND_32_64(imm)) {
-            compareImm64ForBranch(reg, imm);
-            return Jump(m_assembler.jae());
-        } else {
-            move(ptr, scratchRegister);
-            return jaePtr(reg, scratchRegister);
-        }
-#else
-        return jae32(reg, Imm32(ptr));
-#endif
-    }
-
-    Jump jae32(RegisterID left, RegisterID right)
-    {
-        m_assembler.cmpl_rr(right, left);
-        return Jump(m_assembler.jae());
-    }
-
-    Jump jae32(RegisterID left, Imm32 right)
-    {
-        compareImm32ForBranch(left, right.m_value);
-        return Jump(m_assembler.jae());
-    }
-    
-    Jump jae32(RegisterID left, Address right)
-    {
-        m_assembler.cmpl_mr(right.offset, right.base, left);
-        return Jump(m_assembler.jae());
-    }
-    
-    Jump jae32(Address left, RegisterID right)
-    {
-        m_assembler.cmpl_rm(right, left.offset, left.base);
-        return Jump(m_assembler.jae());
-    }
-    
-    Jump jbPtr(RegisterID left, RegisterID right)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.cmpq_rr(right, left);
-        return Jump(m_assembler.jb());
-#else
-        return jb32(left, right);
-#endif
-    }
-
-    Jump jbPtr(RegisterID reg, ImmPtr ptr)
-    {
-#if PLATFORM(X86_64)
-        intptr_t imm = ptr.asIntptr();
-        if (CAN_SIGN_EXTEND_32_64(imm)) {
-            compareImm64ForBranch(reg, imm);
-            return Jump(m_assembler.jb());
-        } else {
-            move(ptr, scratchRegister);
-            return jbPtr(reg, scratchRegister);
-        }
-#else
-        return jb32(reg, Imm32(ptr));
-#endif
-    }
-
-    Jump jb32(RegisterID left, RegisterID right)
-    {
-        m_assembler.cmpl_rr(right, left);
-        return Jump(m_assembler.jb());
-    }
-
-    Jump jb32(RegisterID left, Imm32 right)
-    {
-        compareImm32ForBranch(left, right.m_value);
-        return Jump(m_assembler.jb());
-    }
-    
-    Jump jb32(RegisterID left, Address right)
-    {
-        m_assembler.cmpl_mr(right.offset, right.base, left);
-        return Jump(m_assembler.jb());
-    }
-    
-    Jump jePtr(RegisterID op1, RegisterID op2)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.cmpq_rr(op1, op2);
-        return Jump(m_assembler.je());
-#else
-        return je32(op1, op2);
-#endif
-    }
-
-    Jump jePtr(RegisterID reg, Address address)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.cmpq_rm(reg, address.offset, address.base);
-#else
-        m_assembler.cmpl_rm(reg, address.offset, address.base);
-#endif
-        return Jump(m_assembler.je());
-    }
-
-    Jump jePtr(RegisterID reg, ImmPtr ptr)
-    {
-#if PLATFORM(X86_64)
-        intptr_t imm = ptr.asIntptr();
-        if (CAN_SIGN_EXTEND_32_64(imm)) {
-            compareImm64ForBranchEquality(reg, imm);
-            return Jump(m_assembler.je());
-        } else {
-            move(ptr, scratchRegister);
-            return jePtr(scratchRegister, reg);
-        }
-#else
-        return je32(reg, Imm32(ptr));
-#endif
-    }
-
-    Jump jePtr(Address address, ImmPtr imm)
-    {
-#if PLATFORM(X86_64)
-        move(imm, scratchRegister);
-        return jePtr(scratchRegister, address);
-#else
-        return je32(address, Imm32(imm));
-#endif
-    }
-
-    Jump je32(RegisterID op1, RegisterID op2)
-    {
-        m_assembler.cmpl_rr(op1, op2);
-        return Jump(m_assembler.je());
-    }
-    
-    Jump je32(Address op1, RegisterID op2)
-    {
-        m_assembler.cmpl_mr(op1.offset, op1.base, op2);
-        return Jump(m_assembler.je());
-    }
-    
-    Jump je32(RegisterID reg, Imm32 imm)
-    {
-        compareImm32ForBranchEquality(reg, imm.m_value);
-        return Jump(m_assembler.je());
-    }
-
-    Jump je32(Address address, Imm32 imm)
-    {
-        compareImm32ForBranchEquality(address, imm.m_value);
-        return Jump(m_assembler.je());
-    }
-    
-    Jump je16(RegisterID op1, BaseIndex op2)
-    {
-        m_assembler.cmpw_rm(op1, op2.offset, op2.base, op2.index, op2.scale);
-        return Jump(m_assembler.je());
-    }
-    
-    Jump jg32(RegisterID left, RegisterID right)
-    {
-        m_assembler.cmpl_rr(right, left);
-        return Jump(m_assembler.jg());
-    }
-
-    Jump jg32(RegisterID reg, Address address)
-    {
-        m_assembler.cmpl_mr(address.offset, address.base, reg);
-        return Jump(m_assembler.jg());
-    }
-
-    Jump jgePtr(RegisterID left, RegisterID right)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.cmpq_rr(right, left);
-        return Jump(m_assembler.jge());
-#else
-        return jge32(left, right);
-#endif
-    }
-
-    Jump jgePtr(RegisterID reg, ImmPtr ptr)
-    {
-#if PLATFORM(X86_64)
-        intptr_t imm = ptr.asIntptr();
-        if (CAN_SIGN_EXTEND_32_64(imm)) {
-            compareImm64ForBranch(reg, imm);
-            return Jump(m_assembler.jge());
-        } else {
-            move(ptr, scratchRegister);
-            return jgePtr(reg, scratchRegister);
-        }
-#else
-        return jge32(reg, Imm32(ptr));
-#endif
-    }
-
-    Jump jge32(RegisterID left, RegisterID right)
-    {
-        m_assembler.cmpl_rr(right, left);
-        return Jump(m_assembler.jge());
-    }
-
-    Jump jge32(RegisterID left, Imm32 right)
-    {
-        compareImm32ForBranch(left, right.m_value);
-        return Jump(m_assembler.jge());
-    }
-
-    Jump jlPtr(RegisterID left, RegisterID right)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.cmpq_rr(right, left);
-        return Jump(m_assembler.jl());
-#else
-        return jl32(left, right);
-#endif
-    }
-
-    Jump jlPtr(RegisterID reg, ImmPtr ptr)
-    {
-#if PLATFORM(X86_64)
-        intptr_t imm = ptr.asIntptr();
-        if (CAN_SIGN_EXTEND_32_64(imm)) {
-            compareImm64ForBranch(reg, imm);
-            return Jump(m_assembler.jl());
-        } else {
-            move(ptr, scratchRegister);
-            return jlPtr(reg, scratchRegister);
-        }
-#else
-        return jl32(reg, Imm32(ptr));
-#endif
-    }
-
-    Jump jl32(RegisterID left, RegisterID right)
-    {
-        m_assembler.cmpl_rr(right, left);
-        return Jump(m_assembler.jl());
-    }
-    
-    Jump jl32(RegisterID left, Imm32 right)
-    {
-        compareImm32ForBranch(left, right.m_value);
-        return Jump(m_assembler.jl());
-    }
-
-    Jump jlePtr(RegisterID left, RegisterID right)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.cmpq_rr(right, left);
-        return Jump(m_assembler.jle());
-#else
-        return jle32(left, right);
-#endif
-    }
-
-    Jump jlePtr(RegisterID reg, ImmPtr ptr)
-    {
-#if PLATFORM(X86_64)
-        intptr_t imm = ptr.asIntptr();
-        if (CAN_SIGN_EXTEND_32_64(imm)) {
-            compareImm64ForBranch(reg, imm);
-            return Jump(m_assembler.jle());
-        } else {
-            move(ptr, scratchRegister);
-            return jlePtr(reg, scratchRegister);
-        }
-#else
-        return jle32(reg, Imm32(ptr));
-#endif
-    }
-
-    Jump jle32(RegisterID left, RegisterID right)
-    {
-        m_assembler.cmpl_rr(right, left);
-        return Jump(m_assembler.jle());
-    }
-    
-    Jump jle32(RegisterID left, Imm32 right)
-    {
-        compareImm32ForBranch(left, right.m_value);
-        return Jump(m_assembler.jle());
-    }
-
-    Jump jnePtr(RegisterID op1, RegisterID op2)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.cmpq_rr(op1, op2);
-        return Jump(m_assembler.jne());
-#else
-        return jne32(op1, op2);
-#endif
-    }
-
-    Jump jnePtr(RegisterID reg, Address address)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.cmpq_rm(reg, address.offset, address.base);
-#else
-        m_assembler.cmpl_rm(reg, address.offset, address.base);
-#endif
-        return Jump(m_assembler.jne());
-    }
-
-    Jump jnePtr(RegisterID reg, AbsoluteAddress address)
-    {
-#if PLATFORM(X86_64)
-        move(ImmPtr(address.m_ptr), scratchRegister);
-        return jnePtr(reg, Address(scratchRegister));
-#else
-        m_assembler.cmpl_rm(reg, address.m_ptr);
-        return Jump(m_assembler.jne());
-#endif
-    }
-
-    Jump jnePtr(RegisterID reg, ImmPtr ptr)
-    {
-#if PLATFORM(X86_64)
-        intptr_t imm = ptr.asIntptr();
-        if (CAN_SIGN_EXTEND_32_64(imm)) {
-            compareImm64ForBranchEquality(reg, imm);
-            return Jump(m_assembler.jne());
-        } else {
-            move(ptr, scratchRegister);
-            return jnePtr(scratchRegister, reg);
-        }
-#else
-        return jne32(reg, Imm32(ptr));
-#endif
-    }
-
-    Jump jnePtr(Address address, ImmPtr imm)
-    {
-#if PLATFORM(X86_64)
-        move(imm, scratchRegister);
-        return jnePtr(scratchRegister, address);
-#else
-        return jne32(address, Imm32(imm));
-#endif
-    }
-
-#if !PLATFORM(X86_64)
-    Jump jnePtr(AbsoluteAddress address, ImmPtr imm)
-    {
-        m_assembler.cmpl_im(imm.asIntptr(), address.m_ptr);
-        return Jump(m_assembler.jne());
-    }
-#endif
-
-    Jump jnePtrWithPatch(RegisterID reg, DataLabelPtr& dataLabel, ImmPtr initialValue = ImmPtr(0))
-    {
-#if PLATFORM(X86_64)
-        m_assembler.movq_i64r(initialValue.asIntptr(), scratchRegister);
-        dataLabel = DataLabelPtr(this);
-        return jnePtr(scratchRegister, reg);
-#else
-        m_assembler.cmpl_ir_force32(initialValue.asIntptr(), reg);
-        dataLabel = DataLabelPtr(this);
-        return Jump(m_assembler.jne());
-#endif
-    }
-
-    Jump jnePtrWithPatch(Address address, DataLabelPtr& dataLabel, ImmPtr initialValue = ImmPtr(0))
-    {
-#if PLATFORM(X86_64)
-        m_assembler.movq_i64r(initialValue.asIntptr(), scratchRegister);
-        dataLabel = DataLabelPtr(this);
-        return jnePtr(scratchRegister, address);
-#else
-        m_assembler.cmpl_im_force32(initialValue.asIntptr(), address.offset, address.base);
-        dataLabel = DataLabelPtr(this);
-        return Jump(m_assembler.jne());
-#endif
-    }
-
-    Jump jne32(RegisterID op1, RegisterID op2)
-    {
-        m_assembler.cmpl_rr(op1, op2);
-        return Jump(m_assembler.jne());
-    }
-
-    Jump jne32(RegisterID reg, Imm32 imm)
-    {
-        compareImm32ForBranchEquality(reg, imm.m_value);
-        return Jump(m_assembler.jne());
-    }
-
-    Jump jne32(Address address, Imm32 imm)
-    {
-        compareImm32ForBranchEquality(address, imm.m_value);
-        return Jump(m_assembler.jne());
-    }
-    
-    Jump jne32(Address address, RegisterID reg)
-    {
-        m_assembler.cmpl_rm(reg, address.offset, address.base);
-        return Jump(m_assembler.jne());
-    }
-    
-    Jump jnzPtr(RegisterID reg, RegisterID mask)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.testq_rr(reg, mask);
-        return Jump(m_assembler.jne());
-#else
-        return jnz32(reg, mask);
-#endif
-    }
-
-    Jump jnzPtr(RegisterID reg, Imm32 mask = Imm32(-1))
-    {
-#if PLATFORM(X86_64)
-        testImm64(reg, mask);
-        return Jump(m_assembler.jne());
-#else
-        return jnz32(reg, mask);
-#endif
-    }
-
-    Jump jnzPtr(RegisterID reg, ImmPtr mask)
-    {
-#if PLATFORM(X86_64)
-        move(mask, scratchRegister);
-        m_assembler.testq_rr(scratchRegister, reg);
-        return Jump(m_assembler.jne());
-#else
-        return jnz32(reg, Imm32(mask));
-#endif
-    }
-
-    Jump jnzPtr(Address address, Imm32 mask = Imm32(-1))
-    {
-#if PLATFORM(X86_64)
-        testImm64(address, mask);
-        return Jump(m_assembler.jne());
-#else
-        return jnz32(address, mask);
-#endif
-    }
-
-    Jump jnz32(RegisterID reg, RegisterID mask)
-    {
-        m_assembler.testl_rr(reg, mask);
-        return Jump(m_assembler.jne());
-    }
-
-    Jump jnz32(RegisterID reg, Imm32 mask = Imm32(-1))
-    {
-        testImm32(reg, mask);
-        return Jump(m_assembler.jne());
-    }
-
-    Jump jnz32(Address address, Imm32 mask = Imm32(-1))
-    {
-        testImm32(address, mask);
-        return Jump(m_assembler.jne());
-    }
-
-    Jump jzPtr(RegisterID reg, RegisterID mask)
-    {
-#if PLATFORM(X86_64)
-        m_assembler.testq_rr(reg, mask);
-        return Jump(m_assembler.je());
-#else
-        return jz32(reg, mask);
-#endif
-    }
-
-    Jump jzPtr(RegisterID reg, Imm32 mask = Imm32(-1))
-    {
-#if PLATFORM(X86_64)
-        testImm64(reg, mask);
-        return Jump(m_assembler.je());
-#else
-        return jz32(reg, mask);
-#endif
-    }
-
-    Jump jzPtr(RegisterID reg, ImmPtr mask)
-    {
-#if PLATFORM(X86_64)
-        move(mask, scratchRegister);
-        m_assembler.testq_rr(scratchRegister, reg);
-        return Jump(m_assembler.je());
-#else
-        return jz32(reg, Imm32(mask));
-#endif
-    }
-
-    Jump jzPtr(Address address, Imm32 mask = Imm32(-1))
-    {
-#if PLATFORM(X86_64)
-        testImm64(address, mask);
-        return Jump(m_assembler.je());
-#else
-        return jz32(address, mask);
-#endif
-    }
-
-    Jump jzPtr(BaseIndex address, Imm32 mask = Imm32(-1))
-    {
-#if PLATFORM(X86_64)
-        testImm64(address, mask);
-        return Jump(m_assembler.je());
-#else
-        return jz32(address, mask);
-#endif
-    }
-
-    Jump jz32(RegisterID reg, RegisterID mask)
-    {
-        m_assembler.testl_rr(reg, mask);
-        return Jump(m_assembler.je());
-    }
-
-    Jump jz32(RegisterID reg, Imm32 mask = Imm32(-1))
-    {
-        testImm32(reg, mask);
-        return Jump(m_assembler.je());
-    }
-
-    Jump jz32(Address address, Imm32 mask = Imm32(-1))
-    {
-        testImm32(address, mask);
-        return Jump(m_assembler.je());
-    }
-
-    Jump jz32(BaseIndex address, Imm32 mask = Imm32(-1))
-    {
-        testImm32(address, mask);
-        return Jump(m_assembler.je());
-    }
-
-    Jump jump()
-    {
-        return Jump(m_assembler.jmp());
-    }
-
-
-    // Backwards, local control flow operations:
-    //
-    // These operations provide a shorter notation for local
-    // backwards branches, which may be both more convenient
-    // for the user, and for the programmer, and for the
-    // assembler (allowing shorter values to be used in
-    // relative offsets).
-    //
-    // The code sequence:
-    //
-    //     Label topOfLoop(this);
-    //     // ...
-    //     jne32(reg1, reg2, topOfLoop);
-    //
-    // Is equivalent to the longer, potentially less efficient form:
-    //
-    //     Label topOfLoop(this);
-    //     // ...
-    //     jne32(reg1, reg2).linkTo(topOfLoop);
-
-    void jae32(RegisterID left, Address right, Label target)
-    {
-        jae32(left, right).linkTo(target, this);
-    }
-
-    void je32(RegisterID op1, Imm32 imm, Label target)
-    {
-        je32(op1, imm).linkTo(target, this);
-    }
-
-    void je16(RegisterID op1, BaseIndex op2, Label target)
-    {
-        je16(op1, op2).linkTo(target, this);
-    }
-    
-    void jl32(RegisterID left, Imm32 right, Label target)
-    {
-        jl32(left, right).linkTo(target, this);
-    }
-    
-    void jle32(RegisterID left, RegisterID right, Label target)
-    {
-        jle32(left, right).linkTo(target, this);
-    }
-    
-    void jnePtr(RegisterID op1, ImmPtr imm, Label target)
-    {
-        jnePtr(op1, imm).linkTo(target, this);
-    }
-
-    void jne32(RegisterID op1, RegisterID op2, Label target)
-    {
-        jne32(op1, op2).linkTo(target, this);
-    }
-
-    void jne32(RegisterID op1, Imm32 imm, Label target)
-    {
-        jne32(op1, imm).linkTo(target, this);
-    }
-
-    void jzPtr(RegisterID reg, Label target)
-    {
-        jzPtr(reg).linkTo(target, this);
-    }
-
-    void jump(Label target)
-    {
-        m_assembler.link(m_assembler.jmp(), target.m_label);
-    }
-
-    void jump(RegisterID target)
-    {
-        m_assembler.jmp_r(target);
-    }
-
-    // Address is a memory location containing the address to jump to
-    void jump(Address address)
-    {
-        m_assembler.jmp_m(address.offset, address.base);
-    }
-
-
-    // Arithmetic control flow operations:
-    //
-    // This set of conditional branch operations branch based
-    // on the result of an arithmetic operation.  The operation
-    // is performed as normal, storing the result.
-    //
-    // * jz operations branch if the result is zero.
-    // * jo operations branch if the (signed) arithmetic
-    //   operation caused an overflow to occur.
-
-    Jump jnzSubPtr(Imm32 imm, RegisterID dest)
-    {
-        subPtr(imm, dest);
-        return Jump(m_assembler.jne());
-    }
-    
-    Jump jnzSub32(Imm32 imm, RegisterID dest)
-    {
-        sub32(imm, dest);
-        return Jump(m_assembler.jne());
-    }
-    
-    Jump joAddPtr(RegisterID src, RegisterID dest)
-    {
-        addPtr(src, dest);
-        return Jump(m_assembler.jo());
-    }
-    
-    Jump joAdd32(RegisterID src, RegisterID dest)
-    {
-        add32(src, dest);
-        return Jump(m_assembler.jo());
-    }
-    
-    Jump joAdd32(Imm32 imm, RegisterID dest)
-    {
-        add32(imm, dest);
-        return Jump(m_assembler.jo());
-    }
-    
-    Jump joMul32(RegisterID src, RegisterID dest)
-    {
-        mul32(src, dest);
-        return Jump(m_assembler.jo());
-    }
-    
-    Jump joMul32(Imm32 imm, RegisterID src, RegisterID dest)
-    {
-        mul32(imm, src, dest);
-        return Jump(m_assembler.jo());
-    }
-    
-    Jump joSub32(RegisterID src, RegisterID dest)
-    {
-        sub32(src, dest);
-        return Jump(m_assembler.jo());
-    }
-    
-    Jump joSub32(Imm32 imm, RegisterID dest)
-    {
-        sub32(imm, dest);
-        return Jump(m_assembler.jo());
-    }
-    
-    Jump jzSubPtr(Imm32 imm, RegisterID dest)
-    {
-        subPtr(imm, dest);
-        return Jump(m_assembler.je());
-    }
-    
-    Jump jzSub32(Imm32 imm, RegisterID dest)
-    {
-        sub32(imm, dest);
-        return Jump(m_assembler.je());
-    }
-    
-
-    // Miscellaneous operations:
-
-    void breakpoint()
-    {
-        m_assembler.int3();
-    }
-
-    Jump call()
-    {
-        return Jump(m_assembler.call());
-    }
-
-    // FIXME: why does this return a Jump object? - it can't be linked.
-    // This may be to get a reference to the return address of the call.
-    //
-    // This should probably be handled by a separate label type to a regular
-    // jump.  Todo: add a CallLabel type, for the regular call - can be linked
-    // like a jump (possibly a subclass of jump?, or possibly casts to a Jump).
-    // Also add a CallReturnLabel type for this to return (just a more JmpDsty
-    // form of label, can get the void* after the code has been linked, but can't
-    // try to link it like a Jump object), and let the CallLabel be cast into a
-    // CallReturnLabel.
-    Jump call(RegisterID target)
-    {
-        return Jump(m_assembler.call(target));
-    }
-
-    Label label()
-    {
-        return Label(this);
-    }
-    
-    Label align()
-    {
-        m_assembler.align(16);
-        return Label(this);
-    }
-
-    ptrdiff_t differenceBetween(Label from, Jump to)
-    {
-        return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
-    }
-
-    ptrdiff_t differenceBetween(Label from, Label to)
-    {
-        return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_label);
-    }
-
-    ptrdiff_t differenceBetween(Label from, DataLabelPtr to)
-    {
-        return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_label);
-    }
-
-    ptrdiff_t differenceBetween(Label from, DataLabel32 to)
-    {
-        return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_label);
-    }
-
-    ptrdiff_t differenceBetween(DataLabelPtr from, Jump to)
-    {
-        return X86Assembler::getDifferenceBetweenLabels(from.m_label, to.m_jmp);
-    }
-
-    void ret()
-    {
-        m_assembler.ret();
-    }
-
-    void sete32(RegisterID src, RegisterID srcDest)
-    {
-        m_assembler.cmpl_rr(srcDest, src);
-        m_assembler.sete_r(srcDest);
-        m_assembler.movzbl_rr(srcDest, srcDest);
-    }
-
-    void sete32(Imm32 imm, RegisterID srcDest)
-    {
-        compareImm32ForBranchEquality(srcDest, imm.m_value);
-        m_assembler.sete_r(srcDest);
-        m_assembler.movzbl_rr(srcDest, srcDest);
-    }
-
-    void setne32(RegisterID src, RegisterID srcDest)
-    {
-        m_assembler.cmpl_rr(srcDest, src);
-        m_assembler.setne_r(srcDest);
-        m_assembler.movzbl_rr(srcDest, srcDest);
-    }
-
-    void setne32(Imm32 imm, RegisterID srcDest)
-    {
-        compareImm32ForBranchEquality(srcDest, imm.m_value);
-        m_assembler.setne_r(srcDest);
-        m_assembler.movzbl_rr(srcDest, srcDest);
-    }
-
-    // FIXME:
-    // The mask should be optional... paerhaps the argument order should be
-    // dest-src, operations always have a dest? ... possibly not true, considering
-    // asm ops like test, or pseudo ops like pop().
-    void setnz32(Address address, Imm32 mask, RegisterID dest)
-    {
-        testImm32(address, mask);
-        m_assembler.setnz_r(dest);
-        m_assembler.movzbl_rr(dest, dest);
-    }
-
-    void setz32(Address address, Imm32 mask, RegisterID dest)
-    {
-        testImm32(address, mask);
-        m_assembler.setz_r(dest);
-        m_assembler.movzbl_rr(dest, dest);
-    }
 };
 
 } // namespace JSC
diff --git a/assembler/MacroAssemblerARMv7.h b/assembler/MacroAssemblerARMv7.h
new file mode 100644 (file)
index 0000000..f7a8402
--- /dev/null
@@ -0,0 +1,1082 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef MacroAssemblerARMv7_h
+#define MacroAssemblerARMv7_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER)
+
+#include "ARMv7Assembler.h"
+#include "AbstractMacroAssembler.h"
+
+namespace JSC {
+
+class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> {
+    // FIXME: switch dataTempRegister & addressTempRegister, or possibly use r7?
+    //        - dTR is likely used more than aTR, and we'll get better instruction
+    //        encoding if it's in the low 8 registers.
+    static const ARM::RegisterID dataTempRegister = ARM::ip;
+    static const RegisterID addressTempRegister = ARM::r3;
+    static const FPRegisterID fpTempRegister = ARM::d7;
+
+    struct ArmAddress {
+        enum AddressType {
+            HasOffset,
+            HasIndex,
+        } type;
+        RegisterID base;
+        union {
+            int32_t offset;
+            struct {
+                RegisterID index;
+                Scale scale;
+            };
+        } u;
+        
+        explicit ArmAddress(RegisterID base, int32_t offset = 0)
+            : type(HasOffset)
+            , base(base)
+        {
+            u.offset = offset;
+        }
+        
+        explicit ArmAddress(RegisterID base, RegisterID index, Scale scale = TimesOne)
+            : type(HasIndex)
+            , base(base)
+        {
+            u.index = index;
+            u.scale = scale;
+        }
+    };
+    
+public:
+
+    static const Scale ScalePtr = TimesFour;
+
+    enum Condition {
+        Equal = ARMv7Assembler::ConditionEQ,
+        NotEqual = ARMv7Assembler::ConditionNE,
+        Above = ARMv7Assembler::ConditionHI,
+        AboveOrEqual = ARMv7Assembler::ConditionHS,
+        Below = ARMv7Assembler::ConditionLO,
+        BelowOrEqual = ARMv7Assembler::ConditionLS,
+        GreaterThan = ARMv7Assembler::ConditionGT,
+        GreaterThanOrEqual = ARMv7Assembler::ConditionGE,
+        LessThan = ARMv7Assembler::ConditionLT,
+        LessThanOrEqual = ARMv7Assembler::ConditionLE,
+        Overflow = ARMv7Assembler::ConditionVS,
+        Signed = ARMv7Assembler::ConditionMI,
+        Zero = ARMv7Assembler::ConditionEQ,
+        NonZero = ARMv7Assembler::ConditionNE
+    };
+
+    enum DoubleCondition {
+        DoubleEqual = ARMv7Assembler::ConditionEQ,
+        DoubleGreaterThan = ARMv7Assembler::ConditionGT,
+        DoubleGreaterThanOrEqual = ARMv7Assembler::ConditionGE,
+        DoubleLessThan = ARMv7Assembler::ConditionLO,
+        DoubleLessThanOrEqual = ARMv7Assembler::ConditionLS,
+    };
+
+    static const RegisterID stackPointerRegister = ARM::sp;
+    static const RegisterID linkRegister = ARM::lr;
+
+    // Integer arithmetic operations:
+    //
+    // Operations are typically two operand - operation(source, srcDst)
+    // For many operations the source may be an Imm32, the srcDst operand
+    // may often be a memory location (explictly described using an Address
+    // object).
+
+    void add32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.add(dest, dest, src);
+    }
+
+    void add32(Imm32 imm, RegisterID dest)
+    {
+        add32(imm, dest, dest);
+    }
+
+    void add32(Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.add(dest, src, armImm);
+        else {
+            move(imm, dataTempRegister);
+            m_assembler.add(dest, src, dataTempRegister);
+        }
+    }
+
+    void add32(Imm32 imm, Address address)
+    {
+        load32(address, dataTempRegister);
+
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.add(dataTempRegister, dataTempRegister, armImm);
+        else {
+            // Hrrrm, since dataTempRegister holds the data loaded,
+            // use addressTempRegister to hold the immediate.
+            move(imm, addressTempRegister);
+            m_assembler.add(dataTempRegister, dataTempRegister, addressTempRegister);
+        }
+
+        store32(dataTempRegister, address);
+    }
+
+    void add32(Address src, RegisterID dest)
+    {
+        load32(src, dataTempRegister);
+        add32(dataTempRegister, dest);
+    }
+
+    void add32(Imm32 imm, AbsoluteAddress address)
+    {
+        load32(address.m_ptr, dataTempRegister);
+
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.add(dataTempRegister, dataTempRegister, armImm);
+        else {
+            // Hrrrm, since dataTempRegister holds the data loaded,
+            // use addressTempRegister to hold the immediate.
+            move(imm, addressTempRegister);
+            m_assembler.add(dataTempRegister, dataTempRegister, addressTempRegister);
+        }
+
+        store32(dataTempRegister, address.m_ptr);
+    }
+
+    void and32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.ARM_and(dest, dest, src);
+    }
+
+    void and32(Imm32 imm, RegisterID dest)
+    {
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.ARM_and(dest, dest, armImm);
+        else {
+            move(imm, dataTempRegister);
+            m_assembler.ARM_and(dest, dest, dataTempRegister);
+        }
+    }
+
+    void lshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.lsl(dest, dest, imm.m_value);
+    }
+
+    void lshift32(RegisterID shift_amount, RegisterID dest)
+    {
+        m_assembler.lsl(dest, dest, shift_amount);
+    }
+
+    void mul32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.smull(dest, dataTempRegister, dest, src);
+    }
+
+    void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        move(imm, dataTempRegister);
+        m_assembler.smull(dest, dataTempRegister, src, dataTempRegister);
+    }
+
+    void not32(RegisterID srcDest)
+    {
+        m_assembler.mvn(srcDest, srcDest);
+    }
+
+    void or32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.orr(dest, dest, src);
+    }
+
+    void or32(Imm32 imm, RegisterID dest)
+    {
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.orr(dest, dest, armImm);
+        else {
+            move(imm, dataTempRegister);
+            m_assembler.orr(dest, dest, dataTempRegister);
+        }
+    }
+
+    void rshift32(RegisterID shift_amount, RegisterID dest)
+    {
+        m_assembler.asr(dest, dest, shift_amount);
+    }
+
+    void rshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.asr(dest, dest, imm.m_value);
+    }
+
+    void sub32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.sub(dest, dest, src);
+    }
+
+    void sub32(Imm32 imm, RegisterID dest)
+    {
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.sub(dest, dest, armImm);
+        else {
+            move(imm, dataTempRegister);
+            m_assembler.sub(dest, dest, dataTempRegister);
+        }
+    }
+
+    void sub32(Imm32 imm, Address address)
+    {
+        load32(address, dataTempRegister);
+
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.sub(dataTempRegister, dataTempRegister, armImm);
+        else {
+            // Hrrrm, since dataTempRegister holds the data loaded,
+            // use addressTempRegister to hold the immediate.
+            move(imm, addressTempRegister);
+            m_assembler.sub(dataTempRegister, dataTempRegister, addressTempRegister);
+        }
+
+        store32(dataTempRegister, address);
+    }
+
+    void sub32(Address src, RegisterID dest)
+    {
+        load32(src, dataTempRegister);
+        sub32(dataTempRegister, dest);
+    }
+
+    void sub32(Imm32 imm, AbsoluteAddress address)
+    {
+        load32(address.m_ptr, dataTempRegister);
+
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.sub(dataTempRegister, dataTempRegister, armImm);
+        else {
+            // Hrrrm, since dataTempRegister holds the data loaded,
+            // use addressTempRegister to hold the immediate.
+            move(imm, addressTempRegister);
+            m_assembler.sub(dataTempRegister, dataTempRegister, addressTempRegister);
+        }
+
+        store32(dataTempRegister, address.m_ptr);
+    }
+
+    void xor32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.eor(dest, dest, src);
+    }
+
+    void xor32(Imm32 imm, RegisterID dest)
+    {
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.eor(dest, dest, armImm);
+        else {
+            move(imm, dataTempRegister);
+            m_assembler.eor(dest, dest, dataTempRegister);
+        }
+    }
+    
+
+    // Memory access operations:
+    //
+    // Loads are of the form load(address, destination) and stores of the form
+    // store(source, address).  The source for a store may be an Imm32.  Address
+    // operand objects to loads and store will be implicitly constructed if a
+    // register is passed.
+
+private:
+    void load32(ArmAddress address, RegisterID dest)
+    {
+        if (address.type == ArmAddress::HasIndex)
+            m_assembler.ldr(dest, address.base, address.u.index, address.u.scale);
+        else if (address.u.offset >= 0) {
+            ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.u.offset);
+            ASSERT(armImm.isValid());
+            m_assembler.ldr(dest, address.base, armImm);
+        } else {
+            ASSERT(address.u.offset >= -255);
+            m_assembler.ldr(dest, address.base, address.u.offset, true, false);
+        }
+    }
+
+    void load16(ArmAddress address, RegisterID dest)
+    {
+        if (address.type == ArmAddress::HasIndex)
+            m_assembler.ldrh(dest, address.base, address.u.index, address.u.scale);
+        else if (address.u.offset >= 0) {
+            ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.u.offset);
+            ASSERT(armImm.isValid());
+            m_assembler.ldrh(dest, address.base, armImm);
+        } else {
+            ASSERT(address.u.offset >= -255);
+            m_assembler.ldrh(dest, address.base, address.u.offset, true, false);
+        }
+    }
+
+    void store32(RegisterID src, ArmAddress address)
+    {
+        if (address.type == ArmAddress::HasIndex)
+            m_assembler.str(src, address.base, address.u.index, address.u.scale);
+        else if (address.u.offset >= 0) {
+            ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.u.offset);
+            ASSERT(armImm.isValid());
+            m_assembler.str(src, address.base, armImm);
+        } else {
+            ASSERT(address.u.offset >= -255);
+            m_assembler.str(src, address.base, address.u.offset, true, false);
+        }
+    }
+
+public:
+    void load32(ImplicitAddress address, RegisterID dest)
+    {
+        load32(setupArmAddress(address), dest);
+    }
+
+    void load32(BaseIndex address, RegisterID dest)
+    {
+        load32(setupArmAddress(address), dest);
+    }
+
+    void load32(void* address, RegisterID dest)
+    {
+        move(ImmPtr(address), addressTempRegister);
+        m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
+    }
+
+    DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
+    {
+        DataLabel32 label = moveWithPatch(Imm32(address.offset), dataTempRegister);
+        load32(ArmAddress(address.base, dataTempRegister), dest);
+        return label;
+    }
+
+    Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
+    {
+        Label label(this);
+        moveFixedWidthEncoding(Imm32(address.offset), dataTempRegister);
+        load32(ArmAddress(address.base, dataTempRegister), dest);
+        return label;
+    }
+
+    void load16(BaseIndex address, RegisterID dest)
+    {
+        m_assembler.ldrh(dest, makeBaseIndexBase(address), address.index, address.scale);
+    }
+
+    DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
+    {
+        DataLabel32 label = moveWithPatch(Imm32(address.offset), dataTempRegister);
+        store32(src, ArmAddress(address.base, dataTempRegister));
+        return label;
+    }
+
+    void store32(RegisterID src, ImplicitAddress address)
+    {
+        store32(src, setupArmAddress(address));
+    }
+
+    void store32(RegisterID src, BaseIndex address)
+    {
+        store32(src, setupArmAddress(address));
+    }
+
+    void store32(Imm32 imm, ImplicitAddress address)
+    {
+        move(imm, dataTempRegister);
+        store32(dataTempRegister, setupArmAddress(address));
+    }
+
+    void store32(RegisterID src, void* address)
+    {
+        move(ImmPtr(address), addressTempRegister);
+        m_assembler.str(src, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
+    }
+
+    void store32(Imm32 imm, void* address)
+    {
+        move(imm, dataTempRegister);
+        store32(dataTempRegister, address);
+    }
+
+
+    // Floating-point operations:
+
+    bool supportsFloatingPoint() const { return true; }
+    // On x86(_64) the MacroAssembler provides an interface to truncate a double to an integer.
+    // If a value is not representable as an integer, and possibly for some values that are,
+    // (on x86 INT_MIN, since this is indistinguishable from results for out-of-range/NaN input)
+    // a branch will  be taken.  It is not clear whether this interface will be well suited to
+    // other platforms.  On ARMv7 the hardware truncation operation produces multiple possible
+    // failure values (saturates to INT_MIN & INT_MAX, NaN reulsts in a value of 0).  This is a
+    // temporary solution while we work out what this interface should be.  Either we need to
+    // decide to make this interface work on all platforms, rework the interface to make it more
+    // generic, or decide that the MacroAssembler cannot practically be used to abstracted these
+    // operations, and make clients go directly to the m_assembler to plant truncation instructions.
+    // In short, FIXME:.
+    bool supportsFloatingPointTruncate() const { return false; }
+
+    void loadDouble(ImplicitAddress address, FPRegisterID dest)
+    {
+        RegisterID base = address.base;
+        int32_t offset = address.offset;
+
+        // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
+        if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) {
+            add32(Imm32(offset), base, addressTempRegister);
+            base = addressTempRegister;
+            offset = 0;
+        }
+        
+        m_assembler.vldr(dest, base, offset);
+    }
+
+    void storeDouble(FPRegisterID src, ImplicitAddress address)
+    {
+        RegisterID base = address.base;
+        int32_t offset = address.offset;
+
+        // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
+        if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) {
+            add32(Imm32(offset), base, addressTempRegister);
+            base = addressTempRegister;
+            offset = 0;
+        }
+        
+        m_assembler.vstr(src, base, offset);
+    }
+
+    void addDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.vadd_F64(dest, dest, src);
+    }
+
+    void addDouble(Address src, FPRegisterID dest)
+    {
+        loadDouble(src, fpTempRegister);
+        addDouble(fpTempRegister, dest);
+    }
+
+    void subDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.vsub_F64(dest, dest, src);
+    }
+
+    void subDouble(Address src, FPRegisterID dest)
+    {
+        loadDouble(src, fpTempRegister);
+        subDouble(fpTempRegister, dest);
+    }
+
+    void mulDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.vmul_F64(dest, dest, src);
+    }
+
+    void mulDouble(Address src, FPRegisterID dest)
+    {
+        loadDouble(src, fpTempRegister);
+        mulDouble(fpTempRegister, dest);
+    }
+
+    void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
+    {
+        m_assembler.vmov(fpTempRegister, src);
+        m_assembler.vcvt_F64_S32(dest, fpTempRegister);
+    }
+
+    Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
+    {
+        m_assembler.vcmp_F64(left, right);
+        m_assembler.vmrs_APSR_nzcv_FPSCR();
+        return makeBranch(cond);
+    }
+
+    Jump branchTruncateDoubleToInt32(FPRegisterID, RegisterID)
+    {
+        ASSERT_NOT_REACHED();
+    }
+
+
+    // Stack manipulation operations:
+    //
+    // The ABI is assumed to provide a stack abstraction to memory,
+    // containing machine word sized units of data.  Push and pop
+    // operations add and remove a single register sized unit of data
+    // to or from the stack.  Peek and poke operations read or write
+    // values on the stack, without moving the current stack position.
+    
+    void pop(RegisterID dest)
+    {
+        // store postindexed with writeback
+        m_assembler.ldr(dest, ARM::sp, sizeof(void*), false, true);
+    }
+
+    void push(RegisterID src)
+    {
+        // store preindexed with writeback
+        m_assembler.str(src, ARM::sp, -sizeof(void*), true, true);
+    }
+
+    void push(Address address)
+    {
+        load32(address, dataTempRegister);
+        push(dataTempRegister);
+    }
+
+    void push(Imm32 imm)
+    {
+        move(imm, dataTempRegister);
+        push(dataTempRegister);
+    }
+
+    // Register move operations:
+    //
+    // Move values in registers.
+
+    void move(Imm32 imm, RegisterID dest)
+    {
+        uint32_t value = imm.m_value;
+
+        if (imm.m_isPointer)
+            moveFixedWidthEncoding(imm, dest);
+        else {
+            ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(value);
+
+            if (armImm.isValid())
+                m_assembler.mov(dest, armImm);
+            else if ((armImm = ARMThumbImmediate::makeEncodedImm(~value)).isValid())
+                m_assembler.mvn(dest, armImm);
+            else {
+                m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(value));
+                if (value & 0xffff0000)
+                    m_assembler.movt(dest, ARMThumbImmediate::makeUInt16(value >> 16));
+            }
+        }
+    }
+
+    void move(RegisterID src, RegisterID dest)
+    {
+        m_assembler.mov(dest, src);
+    }
+
+    void move(ImmPtr imm, RegisterID dest)
+    {
+        move(Imm32(imm), dest);
+    }
+
+    void swap(RegisterID reg1, RegisterID reg2)
+    {
+        move(reg1, dataTempRegister);
+        move(reg2, reg1);
+        move(dataTempRegister, reg2);
+    }
+
+    void signExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        if (src != dest)
+            move(src, dest);
+    }
+
+    void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        if (src != dest)
+            move(src, dest);
+    }
+
+
+    // Forwards / external control flow operations:
+    //
+    // This set of jump and conditional branch operations return a Jump
+    // object which may linked at a later point, allow forwards jump,
+    // or jumps that will require external linkage (after the code has been
+    // relocated).
+    //
+    // For branches, signed <, >, <= and >= are denoted as l, g, le, and ge
+    // respecitvely, for unsigned comparisons the names b, a, be, and ae are
+    // used (representing the names 'below' and 'above').
+    //
+    // Operands to the comparision are provided in the expected order, e.g.
+    // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
+    // treated as a signed 32bit value, is less than or equal to 5.
+    //
+    // jz and jnz test whether the first operand is equal to zero, and take
+    // an optional second operand of a mask under which to perform the test.
+private:
+
+    // Should we be using TEQ for equal/not-equal?
+    void compare32(RegisterID left, Imm32 right)
+    {
+        int32_t imm = right.m_value;
+        if (!imm)
+            m_assembler.tst(left, left);
+        else {
+            ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm);
+            if (armImm.isValid())
+                m_assembler.cmp(left, armImm);
+            if ((armImm = ARMThumbImmediate::makeEncodedImm(-imm)).isValid())
+                m_assembler.cmn(left, armImm);
+            else {
+                move(Imm32(imm), dataTempRegister);
+                m_assembler.cmp(left, dataTempRegister);
+            }
+        }
+    }
+
+    void test32(RegisterID reg, Imm32 mask)
+    {
+        int32_t imm = mask.m_value;
+
+        if (imm == -1)
+            m_assembler.tst(reg, reg);
+        else {
+            ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm);
+            if (armImm.isValid())
+                m_assembler.tst(reg, armImm);
+            else {
+                move(mask, dataTempRegister);
+                m_assembler.tst(reg, dataTempRegister);
+            }
+        }
+    }
+
+public:
+    Jump branch32(Condition cond, RegisterID left, RegisterID right)
+    {
+        m_assembler.cmp(left, right);
+        return Jump(makeBranch(cond));
+    }
+
+    Jump branch32(Condition cond, RegisterID left, Imm32 right)
+    {
+        compare32(left, right);
+        return Jump(makeBranch(cond));
+    }
+
+    Jump branch32(Condition cond, RegisterID left, Address right)
+    {
+        load32(right, dataTempRegister);
+        return branch32(cond, left, dataTempRegister);
+    }
+
+    Jump branch32(Condition cond, Address left, RegisterID right)
+    {
+        load32(left, dataTempRegister);
+        return branch32(cond, dataTempRegister, right);
+    }
+
+    Jump branch32(Condition cond, Address left, Imm32 right)
+    {
+        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
+        load32(left, addressTempRegister);
+        return branch32(cond, addressTempRegister, right);
+    }
+
+    Jump branch32(Condition cond, BaseIndex left, Imm32 right)
+    {
+        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
+        load32(left, addressTempRegister);
+        return branch32(cond, addressTempRegister, right);
+    }
+
+    Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right)
+    {
+        load32(left.m_ptr, dataTempRegister);
+        return branch32(cond, dataTempRegister, right);
+    }
+
+    Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right)
+    {
+        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
+        load32(left.m_ptr, addressTempRegister);
+        return branch32(cond, addressTempRegister, right);
+    }
+
+    Jump branch16(Condition cond, BaseIndex left, RegisterID right)
+    {
+        load16(left, dataTempRegister);
+        m_assembler.lsl(addressTempRegister, right, 16);
+        m_assembler.lsl(dataTempRegister, dataTempRegister, 16);
+        return branch32(cond, dataTempRegister, addressTempRegister);
+    }
+
+    Jump branch16(Condition cond, BaseIndex left, Imm32 right)
+    {
+        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
+        load16(left, addressTempRegister);
+        m_assembler.lsl(addressTempRegister, addressTempRegister, 16);
+        return branch32(cond, addressTempRegister, Imm32(right.m_value << 16));
+    }
+
+    Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        m_assembler.tst(reg, mask);
+        return Jump(makeBranch(cond));
+    }
+
+    Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        test32(reg, mask);
+        return Jump(makeBranch(cond));
+    }
+
+    Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
+        load32(address, addressTempRegister);
+        return branchTest32(cond, addressTempRegister, mask);
+    }
+
+    Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
+        load32(address, addressTempRegister);
+        return branchTest32(cond, addressTempRegister, mask);
+    }
+
+    Jump jump()
+    {
+        return Jump(makeJump());
+    }
+
+    void jump(RegisterID target)
+    {
+        m_assembler.bx(target);
+    }
+
+    // Address is a memory location containing the address to jump to
+    void jump(Address address)
+    {
+        load32(address, dataTempRegister);
+        m_assembler.bx(dataTempRegister);
+    }
+
+
+    // Arithmetic control flow operations:
+    //
+    // This set of conditional branch operations branch based
+    // on the result of an arithmetic operation.  The operation
+    // is performed as normal, storing the result.
+    //
+    // * jz operations branch if the result is zero.
+    // * jo operations branch if the (signed) arithmetic
+    //   operation caused an overflow to occur.
+    
+    Jump branchAdd32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        m_assembler.add_S(dest, dest, src);
+        return Jump(makeBranch(cond));
+    }
+
+    Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.add_S(dest, dest, armImm);
+        else {
+            move(imm, dataTempRegister);
+            m_assembler.add_S(dest, dest, dataTempRegister);
+        }
+        return Jump(makeBranch(cond));
+    }
+
+    Jump branchMul32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT(cond == Overflow);
+        m_assembler.smull(dest, dataTempRegister, dest, src);
+        m_assembler.asr(addressTempRegister, dest, 31);
+        return branch32(NotEqual, addressTempRegister, dataTempRegister);
+    }
+
+    Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        ASSERT(cond == Overflow);
+        move(imm, dataTempRegister);
+        m_assembler.smull(dest, dataTempRegister, src, dataTempRegister);
+        m_assembler.asr(addressTempRegister, dest, 31);
+        return branch32(NotEqual, addressTempRegister, dataTempRegister);
+    }
+
+    Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        m_assembler.sub_S(dest, dest, src);
+        return Jump(makeBranch(cond));
+    }
+
+    Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
+        if (armImm.isValid())
+            m_assembler.sub_S(dest, dest, armImm);
+        else {
+            move(imm, dataTempRegister);
+            m_assembler.sub_S(dest, dest, dataTempRegister);
+        }
+        return Jump(makeBranch(cond));
+    }
+    
+
+    // Miscellaneous operations:
+
+    void breakpoint()
+    {
+        m_assembler.bkpt();
+    }
+
+    Call nearCall()
+    {
+        moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+        return Call(m_assembler.blx(dataTempRegister), Call::LinkableNear);
+    }
+
+    Call call()
+    {
+        moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+        return Call(m_assembler.blx(dataTempRegister), Call::Linkable);
+    }
+
+    Call call(RegisterID target)
+    {
+        return Call(m_assembler.blx(target), Call::None);
+    }
+
+    Call call(Address address)
+    {
+        load32(address, dataTempRegister);
+        return Call(m_assembler.blx(dataTempRegister), Call::None);
+    }
+
+    void ret()
+    {
+        m_assembler.bx(linkRegister);
+    }
+
+    void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
+    {
+        m_assembler.cmp(left, right);
+        m_assembler.it(armV7Condition(cond), false);
+        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
+        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
+    }
+
+    void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+    {
+        compare32(left, right);
+        m_assembler.it(armV7Condition(cond), false);
+        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
+        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
+    }
+
+    // FIXME:
+    // The mask should be optional... paerhaps the argument order should be
+    // dest-src, operations always have a dest? ... possibly not true, considering
+    // asm ops like test, or pseudo ops like pop().
+    void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
+    {
+        load32(address, dataTempRegister);
+        test32(dataTempRegister, mask);
+        m_assembler.it(armV7Condition(cond), false);
+        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
+        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
+    }
+
+
+    DataLabel32 moveWithPatch(Imm32 imm, RegisterID dst)
+    {
+        moveFixedWidthEncoding(imm, dst);
+        return DataLabel32(this);
+    }
+
+    DataLabelPtr moveWithPatch(ImmPtr imm, RegisterID dst)
+    {
+        moveFixedWidthEncoding(Imm32(imm), dst);
+        return DataLabelPtr(this);
+    }
+
+    Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        dataLabel = moveWithPatch(initialRightValue, dataTempRegister);
+        return branch32(cond, left, dataTempRegister);
+    }
+
+    Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        load32(left, addressTempRegister);
+        dataLabel = moveWithPatch(initialRightValue, dataTempRegister);
+        return branch32(cond, addressTempRegister, dataTempRegister);
+    }
+
+    DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+    {
+        DataLabelPtr label = moveWithPatch(initialValue, dataTempRegister);
+        store32(dataTempRegister, address);
+        return label;
+    }
+    DataLabelPtr storePtrWithPatch(ImplicitAddress address) { return storePtrWithPatch(ImmPtr(0), address); }
+
+
+    Call tailRecursiveCall()
+    {
+        // Like a normal call, but don't link.
+        moveFixedWidthEncoding(Imm32(0), dataTempRegister);
+        return Call(m_assembler.bx(dataTempRegister), Call::Linkable);
+    }
+
+    Call makeTailRecursiveCall(Jump oldJump)
+    {
+        oldJump.link(this);
+        return tailRecursiveCall();
+    }
+
+
+protected:
+    ARMv7Assembler::JmpSrc makeJump()
+    {
+        return m_assembler.b();
+    }
+
+    ARMv7Assembler::JmpSrc makeBranch(ARMv7Assembler::Condition cond)
+    {
+        m_assembler.it(cond);
+        return m_assembler.b();
+    }
+    ARMv7Assembler::JmpSrc makeBranch(Condition cond) { return makeBranch(armV7Condition(cond)); }
+    ARMv7Assembler::JmpSrc makeBranch(DoubleCondition cond) { return makeBranch(armV7Condition(cond)); }
+
+    ArmAddress setupArmAddress(BaseIndex address)
+    {
+        if (address.offset) {
+            ARMThumbImmediate imm = ARMThumbImmediate::makeUInt12OrEncodedImm(address.offset);
+            if (imm.isValid())
+                m_assembler.add(addressTempRegister, address.base, imm);
+            else {
+                move(Imm32(address.offset), addressTempRegister);
+                m_assembler.add(addressTempRegister, addressTempRegister, address.base);
+            }
+
+            return ArmAddress(addressTempRegister, address.index, address.scale);
+        } else
+            return ArmAddress(address.base, address.index, address.scale);
+    }
+
+    ArmAddress setupArmAddress(Address address)
+    {
+        if ((address.offset >= -0xff) && (address.offset <= 0xfff))
+            return ArmAddress(address.base, address.offset);
+
+        move(Imm32(address.offset), addressTempRegister);
+        return ArmAddress(address.base, addressTempRegister);
+    }
+
+    ArmAddress setupArmAddress(ImplicitAddress address)
+    {
+        if ((address.offset >= -0xff) && (address.offset <= 0xfff))
+            return ArmAddress(address.base, address.offset);
+
+        move(Imm32(address.offset), addressTempRegister);
+        return ArmAddress(address.base, addressTempRegister);
+    }
+
+    RegisterID makeBaseIndexBase(BaseIndex address)
+    {
+        if (!address.offset)
+            return address.base;
+
+        ARMThumbImmediate imm = ARMThumbImmediate::makeUInt12OrEncodedImm(address.offset);
+        if (imm.isValid())
+            m_assembler.add(addressTempRegister, address.base, imm);
+        else {
+            move(Imm32(address.offset), addressTempRegister);
+            m_assembler.add(addressTempRegister, addressTempRegister, address.base);
+        }
+
+        return addressTempRegister;
+    }
+
+    DataLabel32 moveFixedWidthEncoding(Imm32 imm, RegisterID dst)
+    {
+        uint32_t value = imm.m_value;
+        m_assembler.movT3(dst, ARMThumbImmediate::makeUInt16(value & 0xffff));
+        m_assembler.movt(dst, ARMThumbImmediate::makeUInt16(value >> 16));
+    }
+
+    ARMv7Assembler::Condition armV7Condition(Condition cond)
+    {
+        return static_cast<ARMv7Assembler::Condition>(cond);
+    }
+
+    ARMv7Assembler::Condition armV7Condition(DoubleCondition cond)
+    {
+        return static_cast<ARMv7Assembler::Condition>(cond);
+    }
+
+private:
+    friend class LinkBuffer;
+    friend class RepatchBuffer;
+
+    static void linkCall(void* code, Call call, FunctionPtr function)
+    {
+        ARMv7Assembler::linkCall(code, call.m_jmp, function.value());
+    }
+
+    static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
+    {
+        ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
+    }
+
+    static void repatchCall(CodeLocationCall call, FunctionPtr destination)
+    {
+        ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
+    }
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // MacroAssemblerARMv7_h
diff --git a/assembler/MacroAssemblerCodeRef.h b/assembler/MacroAssemblerCodeRef.h
new file mode 100644 (file)
index 0000000..341a7ff
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef MacroAssemblerCodeRef_h
+#define MacroAssemblerCodeRef_h
+
+#include <wtf/Platform.h>
+
+#include "ExecutableAllocator.h"
+#include "PassRefPtr.h"
+#include "RefPtr.h"
+#include "UnusedParam.h"
+
+#if ENABLE(ASSEMBLER)
+
+// ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
+// instruction address on the platform (for example, check any alignment requirements).
+#if PLATFORM_ARM_ARCH(7)
+// ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded
+// into the processor are decorated with the bottom bit set, indicating that this is
+// thumb code (as oposed to 32-bit traditional ARM).  The first test checks for both
+// decorated and undectorated null, and the second test ensures that the pointer is
+// decorated.
+#define ASSERT_VALID_CODE_POINTER(ptr) \
+    ASSERT(reinterpret_cast<intptr_t>(ptr) & ~1); \
+    ASSERT(reinterpret_cast<intptr_t>(ptr) & 1)
+#define ASSERT_VALID_CODE_OFFSET(offset) \
+    ASSERT(!(offset & 1)) // Must be multiple of 2.
+#else
+#define ASSERT_VALID_CODE_POINTER(ptr) \
+    ASSERT(ptr)
+#define ASSERT_VALID_CODE_OFFSET(offset) // Anything goes!
+#endif
+
+namespace JSC {
+
+// FunctionPtr:
+//
+// FunctionPtr should be used to wrap pointers to C/C++ functions in JSC
+// (particularly, the stub functions).
+class FunctionPtr {
+public:
+    FunctionPtr()
+        : m_value(0)
+    {
+    }
+
+    template<typename FunctionType>
+    explicit FunctionPtr(FunctionType* value)
+        : m_value(reinterpret_cast<void*>(value))
+    {
+        ASSERT_VALID_CODE_POINTER(m_value);
+    }
+
+    void* value() const { return m_value; }
+    void* executableAddress() const { return m_value; }
+
+
+private:
+    void* m_value;
+};
+
+// ReturnAddressPtr:
+//
+// ReturnAddressPtr should be used to wrap return addresses generated by processor
+// 'call' instructions exectued in JIT code.  We use return addresses to look up
+// exception and optimization information, and to repatch the call instruction
+// that is the source of the return address.
+class ReturnAddressPtr {
+public:
+    ReturnAddressPtr()
+        : m_value(0)
+    {
+    }
+
+    explicit ReturnAddressPtr(void* value)
+        : m_value(value)
+    {
+        ASSERT_VALID_CODE_POINTER(m_value);
+    }
+
+    explicit ReturnAddressPtr(FunctionPtr function)
+        : m_value(function.value())
+    {
+        ASSERT_VALID_CODE_POINTER(m_value);
+    }
+
+    void* value() const { return m_value; }
+
+private:
+    void* m_value;
+};
+
+// MacroAssemblerCodePtr:
+//
+// MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code.
+class MacroAssemblerCodePtr {
+public:
+    MacroAssemblerCodePtr()
+        : m_value(0)
+    {
+    }
+
+    explicit MacroAssemblerCodePtr(void* value)
+#if PLATFORM_ARM_ARCH(7)
+        // Decorate the pointer as a thumb code pointer.
+        : m_value(reinterpret_cast<char*>(value) + 1)
+#else
+        : m_value(value)
+#endif
+    {
+        ASSERT_VALID_CODE_POINTER(m_value);
+    }
+
+    explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
+        : m_value(ra.value())
+    {
+        ASSERT_VALID_CODE_POINTER(m_value);
+    }
+
+    void* executableAddress() const { return m_value; }
+#if PLATFORM_ARM_ARCH(7)
+    // To use this pointer as a data address remove the decoration.
+    void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
+#else
+    void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
+#endif
+
+    bool operator!()
+    {
+        return !m_value;
+    }
+
+private:
+    void* m_value;
+};
+
+// MacroAssemblerCodeRef:
+//
+// A reference to a section of JIT generated code.  A CodeRef consists of a
+// pointer to the code, and a ref pointer to the pool from within which it
+// was allocated.
+class MacroAssemblerCodeRef {
+public:
+    MacroAssemblerCodeRef()
+        : m_size(0)
+    {
+    }
+
+    MacroAssemblerCodeRef(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size)
+        : m_code(code)
+        , m_executablePool(executablePool)
+        , m_size(size)
+    {
+    }
+
+    MacroAssemblerCodePtr m_code;
+    RefPtr<ExecutablePool> m_executablePool;
+    size_t m_size;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // MacroAssemblerCodeRef_h
diff --git a/assembler/MacroAssemblerX86.h b/assembler/MacroAssemblerX86.h
new file mode 100644 (file)
index 0000000..6e96240
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef MacroAssemblerX86_h
+#define MacroAssemblerX86_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER) && PLATFORM(X86)
+
+#include "MacroAssemblerX86Common.h"
+
+namespace JSC {
+
+class MacroAssemblerX86 : public MacroAssemblerX86Common {
+public:
+    MacroAssemblerX86()
+        : m_isSSE2Present(isSSE2Present())
+    {
+    }
+
+    static const Scale ScalePtr = TimesFour;
+
+    using MacroAssemblerX86Common::add32;
+    using MacroAssemblerX86Common::and32;
+    using MacroAssemblerX86Common::sub32;
+    using MacroAssemblerX86Common::or32;
+    using MacroAssemblerX86Common::load32;
+    using MacroAssemblerX86Common::store32;
+    using MacroAssemblerX86Common::branch32;
+    using MacroAssemblerX86Common::call;
+    using MacroAssemblerX86Common::loadDouble;
+    using MacroAssemblerX86Common::convertInt32ToDouble;
+
+    void add32(Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        m_assembler.leal_mr(imm.m_value, src, dest);
+    }
+
+    void add32(Imm32 imm, AbsoluteAddress address)
+    {
+        m_assembler.addl_im(imm.m_value, address.m_ptr);
+    }
+    
+    void addWithCarry32(Imm32 imm, AbsoluteAddress address)
+    {
+        m_assembler.adcl_im(imm.m_value, address.m_ptr);
+    }
+    
+    void and32(Imm32 imm, AbsoluteAddress address)
+    {
+        m_assembler.andl_im(imm.m_value, address.m_ptr);
+    }
+    
+    void or32(Imm32 imm, AbsoluteAddress address)
+    {
+        m_assembler.orl_im(imm.m_value, address.m_ptr);
+    }
+
+    void sub32(Imm32 imm, AbsoluteAddress address)
+    {
+        m_assembler.subl_im(imm.m_value, address.m_ptr);
+    }
+
+    void load32(void* address, RegisterID dest)
+    {
+        m_assembler.movl_mr(address, dest);
+    }
+
+    void loadDouble(void* address, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.movsd_mr(address, dest);
+    }
+
+    void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
+    {
+        m_assembler.cvtsi2sd_mr(src.m_ptr, dest);
+    }
+
+    void store32(Imm32 imm, void* address)
+    {
+        m_assembler.movl_i32m(imm.m_value, address);
+    }
+
+    void store32(RegisterID src, void* address)
+    {
+        m_assembler.movl_rm(src, address);
+    }
+
+    Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right)
+    {
+        m_assembler.cmpl_rm(right, left.m_ptr);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right)
+    {
+        m_assembler.cmpl_im(right.m_value, left.m_ptr);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Call call()
+    {
+        return Call(m_assembler.call(), Call::Linkable);
+    }
+
+    Call tailRecursiveCall()
+    {
+        return Call::fromTailJump(jump());
+    }
+
+    Call makeTailRecursiveCall(Jump oldJump)
+    {
+        return Call::fromTailJump(oldJump);
+    }
+
+
+    DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
+    {
+        m_assembler.movl_i32r(initialValue.asIntptr(), dest);
+        return DataLabelPtr(this);
+    }
+
+    Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        m_assembler.cmpl_ir_force32(initialRightValue.asIntptr(), left);
+        dataLabel = DataLabelPtr(this);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        m_assembler.cmpl_im_force32(initialRightValue.asIntptr(), left.offset, left.base);
+        dataLabel = DataLabelPtr(this);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+    {
+        m_assembler.movl_i32m(initialValue.asIntptr(), address.offset, address.base);
+        return DataLabelPtr(this);
+    }
+
+    Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
+    {
+        Label label(this);
+        load32(address, dest);
+        return label;
+    }
+
+    bool supportsFloatingPoint() const { return m_isSSE2Present; }
+    // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
+    bool supportsFloatingPointTruncate() const { return m_isSSE2Present; }
+
+private:
+    const bool m_isSSE2Present;
+
+    friend class LinkBuffer;
+    friend class RepatchBuffer;
+
+    static void linkCall(void* code, Call call, FunctionPtr function)
+    {
+        X86Assembler::linkCall(code, call.m_jmp, function.value());
+    }
+
+    static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
+    {
+        X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
+    }
+
+    static void repatchCall(CodeLocationCall call, FunctionPtr destination)
+    {
+        X86Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
+    }
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // MacroAssemblerX86_h
diff --git a/assembler/MacroAssemblerX86Common.h b/assembler/MacroAssemblerX86Common.h
new file mode 100644 (file)
index 0000000..c9e3569
--- /dev/null
@@ -0,0 +1,964 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef MacroAssemblerX86Common_h
+#define MacroAssemblerX86Common_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER)
+
+#include "X86Assembler.h"
+#include "AbstractMacroAssembler.h"
+
+namespace JSC {
+
+class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
+public:
+
+    enum Condition {
+        Equal = X86Assembler::ConditionE,
+        NotEqual = X86Assembler::ConditionNE,
+        Above = X86Assembler::ConditionA,
+        AboveOrEqual = X86Assembler::ConditionAE,
+        Below = X86Assembler::ConditionB,
+        BelowOrEqual = X86Assembler::ConditionBE,
+        GreaterThan = X86Assembler::ConditionG,
+        GreaterThanOrEqual = X86Assembler::ConditionGE,
+        LessThan = X86Assembler::ConditionL,
+        LessThanOrEqual = X86Assembler::ConditionLE,
+        Overflow = X86Assembler::ConditionO,
+        Signed = X86Assembler::ConditionS,
+        Zero = X86Assembler::ConditionE,
+        NonZero = X86Assembler::ConditionNE
+    };
+
+    enum DoubleCondition {
+        DoubleEqual = X86Assembler::ConditionE,
+        DoubleNotEqual = X86Assembler::ConditionNE,
+        DoubleGreaterThan = X86Assembler::ConditionA,
+        DoubleGreaterThanOrEqual = X86Assembler::ConditionAE,
+        DoubleLessThan = X86Assembler::ConditionB,
+        DoubleLessThanOrEqual = X86Assembler::ConditionBE,
+    };
+
+    static const RegisterID stackPointerRegister = X86::esp;
+
+    // Integer arithmetic operations:
+    //
+    // Operations are typically two operand - operation(source, srcDst)
+    // For many operations the source may be an Imm32, the srcDst operand
+    // may often be a memory location (explictly described using an Address
+    // object).
+
+    void add32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.addl_rr(src, dest);
+    }
+
+    void add32(Imm32 imm, Address address)
+    {
+        m_assembler.addl_im(imm.m_value, address.offset, address.base);
+    }
+
+    void add32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.addl_ir(imm.m_value, dest);
+    }
+    
+    void add32(Address src, RegisterID dest)
+    {
+        m_assembler.addl_mr(src.offset, src.base, dest);
+    }
+
+    void add32(RegisterID src, Address dest)
+    {
+        m_assembler.addl_rm(src, dest.offset, dest.base);
+    }
+    
+    void and32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.andl_rr(src, dest);
+    }
+
+    void and32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.andl_ir(imm.m_value, dest);
+    }
+
+    void and32(RegisterID src, Address dest)
+    {
+        m_assembler.andl_rm(src, dest.offset, dest.base);
+    }
+
+    void and32(Address src, RegisterID dest)
+    {
+        m_assembler.andl_mr(src.offset, src.base, dest);
+    }
+
+    void and32(Imm32 imm, Address address)
+    {
+        m_assembler.andl_im(imm.m_value, address.offset, address.base);
+    }
+
+    void lshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.shll_i8r(imm.m_value, dest);
+    }
+    
+    void lshift32(RegisterID shift_amount, RegisterID dest)
+    {
+        // On x86 we can only shift by ecx; if asked to shift by another register we'll
+        // need rejig the shift amount into ecx first, and restore the registers afterwards.
+        if (shift_amount != X86::ecx) {
+            swap(shift_amount, X86::ecx);
+
+            // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
+            if (dest == shift_amount)
+                m_assembler.shll_CLr(X86::ecx);
+            // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
+            else if (dest == X86::ecx)
+                m_assembler.shll_CLr(shift_amount);
+            // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
+            else
+                m_assembler.shll_CLr(dest);
+        
+            swap(shift_amount, X86::ecx);
+        } else
+            m_assembler.shll_CLr(dest);
+    }
+    
+    void mul32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.imull_rr(src, dest);
+    }
+
+    void mul32(Address src, RegisterID dest)
+    {
+        m_assembler.imull_mr(src.offset, src.base, dest);
+    }
+    
+    void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        m_assembler.imull_i32r(src, imm.m_value, dest);
+    }
+
+    void neg32(RegisterID srcDest)
+    {
+        m_assembler.negl_r(srcDest);
+    }
+
+    void neg32(Address srcDest)
+    {
+        m_assembler.negl_m(srcDest.offset, srcDest.base);
+    }
+
+    void not32(RegisterID srcDest)
+    {
+        m_assembler.notl_r(srcDest);
+    }
+
+    void not32(Address srcDest)
+    {
+        m_assembler.notl_m(srcDest.offset, srcDest.base);
+    }
+    
+    void or32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.orl_rr(src, dest);
+    }
+
+    void or32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.orl_ir(imm.m_value, dest);
+    }
+
+    void or32(RegisterID src, Address dest)
+    {
+        m_assembler.orl_rm(src, dest.offset, dest.base);
+    }
+
+    void or32(Address src, RegisterID dest)
+    {
+        m_assembler.orl_mr(src.offset, src.base, dest);
+    }
+
+    void or32(Imm32 imm, Address address)
+    {
+        m_assembler.orl_im(imm.m_value, address.offset, address.base);
+    }
+
+    void rshift32(RegisterID shift_amount, RegisterID dest)
+    {
+        // On x86 we can only shift by ecx; if asked to shift by another register we'll
+        // need rejig the shift amount into ecx first, and restore the registers afterwards.
+        if (shift_amount != X86::ecx) {
+            swap(shift_amount, X86::ecx);
+
+            // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
+            if (dest == shift_amount)
+                m_assembler.sarl_CLr(X86::ecx);
+            // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
+            else if (dest == X86::ecx)
+                m_assembler.sarl_CLr(shift_amount);
+            // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
+            else
+                m_assembler.sarl_CLr(dest);
+        
+            swap(shift_amount, X86::ecx);
+        } else
+            m_assembler.sarl_CLr(dest);
+    }
+
+    void rshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.sarl_i8r(imm.m_value, dest);
+    }
+
+    void sub32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.subl_rr(src, dest);
+    }
+    
+    void sub32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.subl_ir(imm.m_value, dest);
+    }
+    
+    void sub32(Imm32 imm, Address address)
+    {
+        m_assembler.subl_im(imm.m_value, address.offset, address.base);
+    }
+
+    void sub32(Address src, RegisterID dest)
+    {
+        m_assembler.subl_mr(src.offset, src.base, dest);
+    }
+
+    void sub32(RegisterID src, Address dest)
+    {
+        m_assembler.subl_rm(src, dest.offset, dest.base);
+    }
+
+
+    void xor32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.xorl_rr(src, dest);
+    }
+
+    void xor32(Imm32 imm, Address dest)
+    {
+        m_assembler.xorl_im(imm.m_value, dest.offset, dest.base);
+    }
+
+    void xor32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.xorl_ir(imm.m_value, dest);
+    }
+
+    void xor32(RegisterID src, Address dest)
+    {
+        m_assembler.xorl_rm(src, dest.offset, dest.base);
+    }
+
+    void xor32(Address src, RegisterID dest)
+    {
+        m_assembler.xorl_mr(src.offset, src.base, dest);
+    }
+    
+
+    // Memory access operations:
+    //
+    // Loads are of the form load(address, destination) and stores of the form
+    // store(source, address).  The source for a store may be an Imm32.  Address
+    // operand objects to loads and store will be implicitly constructed if a
+    // register is passed.
+
+    void load32(ImplicitAddress address, RegisterID dest)
+    {
+        m_assembler.movl_mr(address.offset, address.base, dest);
+    }
+
+    void load32(BaseIndex address, RegisterID dest)
+    {
+        m_assembler.movl_mr(address.offset, address.base, address.index, address.scale, dest);
+    }
+
+    DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
+    {
+        m_assembler.movl_mr_disp32(address.offset, address.base, dest);
+        return DataLabel32(this);
+    }
+
+    void load16(BaseIndex address, RegisterID dest)
+    {
+        m_assembler.movzwl_mr(address.offset, address.base, address.index, address.scale, dest);
+    }
+
+    DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
+    {
+        m_assembler.movl_rm_disp32(src, address.offset, address.base);
+        return DataLabel32(this);
+    }
+
+    void store32(RegisterID src, ImplicitAddress address)
+    {
+        m_assembler.movl_rm(src, address.offset, address.base);
+    }
+
+    void store32(RegisterID src, BaseIndex address)
+    {
+        m_assembler.movl_rm(src, address.offset, address.base, address.index, address.scale);
+    }
+
+    void store32(Imm32 imm, ImplicitAddress address)
+    {
+        m_assembler.movl_i32m(imm.m_value, address.offset, address.base);
+    }
+
+
+    // Floating-point operation:
+    //
+    // Presently only supports SSE, not x87 floating point.
+
+    void loadDouble(ImplicitAddress address, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.movsd_mr(address.offset, address.base, dest);
+    }
+
+    void storeDouble(FPRegisterID src, ImplicitAddress address)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.movsd_rm(src, address.offset, address.base);
+    }
+
+    void addDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.addsd_rr(src, dest);
+    }
+
+    void addDouble(Address src, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.addsd_mr(src.offset, src.base, dest);
+    }
+
+    void divDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.divsd_rr(src, dest);
+    }
+
+    void divDouble(Address src, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.divsd_mr(src.offset, src.base, dest);
+    }
+
+    void subDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.subsd_rr(src, dest);
+    }
+
+    void subDouble(Address src, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.subsd_mr(src.offset, src.base, dest);
+    }
+
+    void mulDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.mulsd_rr(src, dest);
+    }
+
+    void mulDouble(Address src, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.mulsd_mr(src.offset, src.base, dest);
+    }
+
+    void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.cvtsi2sd_rr(src, dest);
+    }
+
+    void convertInt32ToDouble(Address src, FPRegisterID dest)
+    {
+        m_assembler.cvtsi2sd_mr(src.offset, src.base, dest);
+    }
+
+    Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.ucomisd_rr(right, left);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchDouble(DoubleCondition cond, FPRegisterID left, Address right)
+    {
+        m_assembler.ucomisd_mr(right.offset, right.base, left);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    // Truncates 'src' to an integer, and places the resulting 'dest'.
+    // If the result is not representable as a 32 bit value, branch.
+    // May also branch for some values that are representable in 32 bits
+    // (specifically, in this case, INT_MIN).
+    Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.cvttsd2si_rr(src, dest);
+        return branch32(Equal, dest, Imm32(0x80000000));
+    }
+
+    void zeroDouble(FPRegisterID srcDest)
+    {
+        ASSERT(isSSE2Present());
+        m_assembler.xorpd_rr(srcDest, srcDest);
+    }
+
+
+    // Stack manipulation operations:
+    //
+    // The ABI is assumed to provide a stack abstraction to memory,
+    // containing machine word sized units of data.  Push and pop
+    // operations add and remove a single register sized unit of data
+    // to or from the stack.  Peek and poke operations read or write
+    // values on the stack, without moving the current stack position.
+    
+    void pop(RegisterID dest)
+    {
+        m_assembler.pop_r(dest);
+    }
+
+    void push(RegisterID src)
+    {
+        m_assembler.push_r(src);
+    }
+
+    void push(Address address)
+    {
+        m_assembler.push_m(address.offset, address.base);
+    }
+
+    void push(Imm32 imm)
+    {
+        m_assembler.push_i32(imm.m_value);
+    }
+
+
+    // Register move operations:
+    //
+    // Move values in registers.
+
+    void move(Imm32 imm, RegisterID dest)
+    {
+        // Note: on 64-bit the Imm32 value is zero extended into the register, it
+        // may be useful to have a separate version that sign extends the value?
+        if (!imm.m_value)
+            m_assembler.xorl_rr(dest, dest);
+        else
+            m_assembler.movl_i32r(imm.m_value, dest);
+    }
+
+#if PLATFORM(X86_64)
+    void move(RegisterID src, RegisterID dest)
+    {
+        // Note: on 64-bit this is is a full register move; perhaps it would be
+        // useful to have separate move32 & movePtr, with move32 zero extending?
+        if (src != dest)
+            m_assembler.movq_rr(src, dest);
+    }
+
+    void move(ImmPtr imm, RegisterID dest)
+    {
+        if (CAN_SIGN_EXTEND_U32_64(imm.asIntptr()))
+            m_assembler.movl_i32r(static_cast<int32_t>(imm.asIntptr()), dest);
+        else
+            m_assembler.movq_i64r(imm.asIntptr(), dest);
+    }
+
+    void swap(RegisterID reg1, RegisterID reg2)
+    {
+        m_assembler.xchgq_rr(reg1, reg2);
+    }
+
+    void signExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        m_assembler.movsxd_rr(src, dest);
+    }
+
+    void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        m_assembler.movl_rr(src, dest);
+    }
+#else
+    void move(RegisterID src, RegisterID dest)
+    {
+        if (src != dest)
+            m_assembler.movl_rr(src, dest);
+    }
+
+    void move(ImmPtr imm, RegisterID dest)
+    {
+        m_assembler.movl_i32r(imm.asIntptr(), dest);
+    }
+
+    void swap(RegisterID reg1, RegisterID reg2)
+    {
+        if (reg1 != reg2)
+            m_assembler.xchgl_rr(reg1, reg2);
+    }
+
+    void signExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        move(src, dest);
+    }
+
+    void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        move(src, dest);
+    }
+#endif
+
+
+    // Forwards / external control flow operations:
+    //
+    // This set of jump and conditional branch operations return a Jump
+    // object which may linked at a later point, allow forwards jump,
+    // or jumps that will require external linkage (after the code has been
+    // relocated).
+    //
+    // For branches, signed <, >, <= and >= are denoted as l, g, le, and ge
+    // respecitvely, for unsigned comparisons the names b, a, be, and ae are
+    // used (representing the names 'below' and 'above').
+    //
+    // Operands to the comparision are provided in the expected order, e.g.
+    // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
+    // treated as a signed 32bit value, is less than or equal to 5.
+    //
+    // jz and jnz test whether the first operand is equal to zero, and take
+    // an optional second operand of a mask under which to perform the test.
+
+public:
+    Jump branch32(Condition cond, RegisterID left, RegisterID right)
+    {
+        m_assembler.cmpl_rr(right, left);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branch32(Condition cond, RegisterID left, Imm32 right)
+    {
+        if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
+            m_assembler.testl_rr(left, left);
+        else
+            m_assembler.cmpl_ir(right.m_value, left);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+    
+    Jump branch32(Condition cond, RegisterID left, Address right)
+    {
+        m_assembler.cmpl_mr(right.offset, right.base, left);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+    
+    Jump branch32(Condition cond, Address left, RegisterID right)
+    {
+        m_assembler.cmpl_rm(right, left.offset, left.base);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branch32(Condition cond, Address left, Imm32 right)
+    {
+        m_assembler.cmpl_im(right.m_value, left.offset, left.base);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branch32(Condition cond, BaseIndex left, Imm32 right)
+    {
+        m_assembler.cmpl_im(right.m_value, left.offset, left.base, left.index, left.scale);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branch16(Condition cond, BaseIndex left, RegisterID right)
+    {
+        m_assembler.cmpw_rm(right, left.offset, left.base, left.index, left.scale);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branch16(Condition cond, BaseIndex left, Imm32 right)
+    {
+        ASSERT(!(right.m_value & 0xFFFF0000));
+
+        m_assembler.cmpw_im(right.m_value, left.offset, left.base, left.index, left.scale);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        m_assembler.testl_rr(reg, mask);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        // if we are only interested in the low seven bits, this can be tested with a testb
+        if (mask.m_value == -1)
+            m_assembler.testl_rr(reg, reg);
+        else if ((mask.m_value & ~0x7f) == 0)
+            m_assembler.testb_i8r(mask.m_value, reg);
+        else
+            m_assembler.testl_i32r(mask.m_value, reg);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        if (mask.m_value == -1)
+            m_assembler.cmpl_im(0, address.offset, address.base);
+        else
+            m_assembler.testl_i32m(mask.m_value, address.offset, address.base);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        if (mask.m_value == -1)
+            m_assembler.cmpl_im(0, address.offset, address.base, address.index, address.scale);
+        else
+            m_assembler.testl_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump jump()
+    {
+        return Jump(m_assembler.jmp());
+    }
+
+    void jump(RegisterID target)
+    {
+        m_assembler.jmp_r(target);
+    }
+
+    // Address is a memory location containing the address to jump to
+    void jump(Address address)
+    {
+        m_assembler.jmp_m(address.offset, address.base);
+    }
+
+
+    // Arithmetic control flow operations:
+    //
+    // This set of conditional branch operations branch based
+    // on the result of an arithmetic operation.  The operation
+    // is performed as normal, storing the result.
+    //
+    // * jz operations branch if the result is zero.
+    // * jo operations branch if the (signed) arithmetic
+    //   operation caused an overflow to occur.
+    
+    Jump branchAdd32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        add32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        add32(imm, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+    
+    Jump branchAdd32(Condition cond, Imm32 src, Address dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        add32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchAdd32(Condition cond, RegisterID src, Address dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        add32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchAdd32(Condition cond, Address src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        add32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchMul32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT(cond == Overflow);
+        mul32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchMul32(Condition cond, Address src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        mul32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+    
+    Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        ASSERT(cond == Overflow);
+        mul32(imm, src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+    
+    Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        sub32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+    
+    Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        sub32(imm, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchSub32(Condition cond, Imm32 imm, Address dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        sub32(imm, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchSub32(Condition cond, RegisterID src, Address dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        sub32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchSub32(Condition cond, Address src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        sub32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
+        or32(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+
+    // Miscellaneous operations:
+
+    void breakpoint()
+    {
+        m_assembler.int3();
+    }
+
+    Call nearCall()
+    {
+        return Call(m_assembler.call(), Call::LinkableNear);
+    }
+
+    Call call(RegisterID target)
+    {
+        return Call(m_assembler.call(target), Call::None);
+    }
+
+    void call(Address address)
+    {
+        m_assembler.call_m(address.offset, address.base);
+    }
+
+    void ret()
+    {
+        m_assembler.ret();
+    }
+
+    void set8(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
+    {
+        m_assembler.cmpl_rr(right, left);
+        m_assembler.setCC_r(x86Condition(cond), dest);
+    }
+
+    void set8(Condition cond, Address left, RegisterID right, RegisterID dest)
+    {
+        m_assembler.cmpl_mr(left.offset, left.base, right);
+        m_assembler.setCC_r(x86Condition(cond), dest);
+    }
+
+    void set8(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+    {
+        if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
+            m_assembler.testl_rr(left, left);
+        else
+            m_assembler.cmpl_ir(right.m_value, left);
+        m_assembler.setCC_r(x86Condition(cond), dest);
+    }
+
+    void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
+    {
+        m_assembler.cmpl_rr(right, left);
+        m_assembler.setCC_r(x86Condition(cond), dest);
+        m_assembler.movzbl_rr(dest, dest);
+    }
+
+    void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+    {
+        if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
+            m_assembler.testl_rr(left, left);
+        else
+            m_assembler.cmpl_ir(right.m_value, left);
+        m_assembler.setCC_r(x86Condition(cond), dest);
+        m_assembler.movzbl_rr(dest, dest);
+    }
+
+    // FIXME:
+    // The mask should be optional... paerhaps the argument order should be
+    // dest-src, operations always have a dest? ... possibly not true, considering
+    // asm ops like test, or pseudo ops like pop().
+
+    void setTest8(Condition cond, Address address, Imm32 mask, RegisterID dest)
+    {
+        if (mask.m_value == -1)
+            m_assembler.cmpl_im(0, address.offset, address.base);
+        else
+            m_assembler.testl_i32m(mask.m_value, address.offset, address.base);
+        m_assembler.setCC_r(x86Condition(cond), dest);
+    }
+
+    void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
+    {
+        if (mask.m_value == -1)
+            m_assembler.cmpl_im(0, address.offset, address.base);
+        else
+            m_assembler.testl_i32m(mask.m_value, address.offset, address.base);
+        m_assembler.setCC_r(x86Condition(cond), dest);
+        m_assembler.movzbl_rr(dest, dest);
+    }
+
+protected:
+    X86Assembler::Condition x86Condition(Condition cond)
+    {
+        return static_cast<X86Assembler::Condition>(cond);
+    }
+
+    X86Assembler::Condition x86Condition(DoubleCondition cond)
+    {
+        return static_cast<X86Assembler::Condition>(cond);
+    }
+
+private:
+    // Only MacroAssemblerX86 should be using the following method; SSE2 is always available on
+    // x86_64, and clients & subclasses of MacroAssembler should be using 'supportsFloatingPoint()'.
+    friend class MacroAssemblerX86;
+
+#if PLATFORM(X86)
+#if PLATFORM(MAC)
+
+    // All X86 Macs are guaranteed to support at least SSE2,
+    static bool isSSE2Present()
+    {
+        return true;
+    }
+
+#else // PLATFORM(MAC)
+
+    enum SSE2CheckState {
+        NotCheckedSSE2,
+        HasSSE2,
+        NoSSE2
+    };
+
+    static bool isSSE2Present()
+    {
+        if (s_sse2CheckState == NotCheckedSSE2) {
+            // Default the flags value to zero; if the compiler is
+            // not MSVC or GCC we will read this as SSE2 not present.
+            int flags = 0;
+#if COMPILER(MSVC)
+            _asm {
+                mov eax, 1 // cpuid function 1 gives us the standard feature set
+                cpuid;
+                mov flags, edx;
+            }
+#elif COMPILER(GCC)
+            asm (
+                 "movl $0x1, %%eax;"
+                 "pushl %%ebx;"
+                 "cpuid;"
+                 "popl %%ebx;"
+                 "movl %%edx, %0;"
+                 : "=g" (flags)
+                 :
+                 : "%eax", "%ecx", "%edx"
+                 );
+#endif
+            static const int SSE2FeatureBit = 1 << 26;
+            s_sse2CheckState = (flags & SSE2FeatureBit) ? HasSSE2 : NoSSE2;
+        }
+        // Only check once.
+        ASSERT(s_sse2CheckState != NotCheckedSSE2);
+
+        return s_sse2CheckState == HasSSE2;
+    }
+    
+    static SSE2CheckState s_sse2CheckState;
+
+#endif // PLATFORM(MAC)
+#elif !defined(NDEBUG) // PLATFORM(X86)
+
+    // On x86-64 we should never be checking for SSE2 in a non-debug build,
+    // but non debug add this method to keep the asserts above happy.
+    static bool isSSE2Present()
+    {
+        return true;
+    }
+
+#endif
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // MacroAssemblerX86Common_h
diff --git a/assembler/MacroAssemblerX86_64.h b/assembler/MacroAssemblerX86_64.h
new file mode 100644 (file)
index 0000000..e3d296c
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef MacroAssemblerX86_64_h
+#define MacroAssemblerX86_64_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER) && PLATFORM(X86_64)
+
+#include "MacroAssemblerX86Common.h"
+
+#define REPTACH_OFFSET_CALL_R11 3
+
+namespace JSC {
+
+class MacroAssemblerX86_64 : public MacroAssemblerX86Common {
+protected:
+    static const X86::RegisterID scratchRegister = X86::r11;
+
+public:
+    static const Scale ScalePtr = TimesEight;
+
+    using MacroAssemblerX86Common::add32;
+    using MacroAssemblerX86Common::and32;
+    using MacroAssemblerX86Common::or32;
+    using MacroAssemblerX86Common::sub32;
+    using MacroAssemblerX86Common::load32;
+    using MacroAssemblerX86Common::store32;
+    using MacroAssemblerX86Common::call;
+    using MacroAssemblerX86Common::loadDouble;
+    using MacroAssemblerX86Common::convertInt32ToDouble;
+
+    void add32(Imm32 imm, AbsoluteAddress address)
+    {
+        move(ImmPtr(address.m_ptr), scratchRegister);
+        add32(imm, Address(scratchRegister));
+    }
+    
+    void and32(Imm32 imm, AbsoluteAddress address)
+    {
+        move(ImmPtr(address.m_ptr), scratchRegister);
+        and32(imm, Address(scratchRegister));
+    }
+    
+    void or32(Imm32 imm, AbsoluteAddress address)
+    {
+        move(ImmPtr(address.m_ptr), scratchRegister);
+        or32(imm, Address(scratchRegister));
+    }
+
+    void sub32(Imm32 imm, AbsoluteAddress address)
+    {
+        move(ImmPtr(address.m_ptr), scratchRegister);
+        sub32(imm, Address(scratchRegister));
+    }
+
+    void load32(void* address, RegisterID dest)
+    {
+        if (dest == X86::eax)
+            m_assembler.movl_mEAX(address);
+        else {
+            move(X86::eax, dest);
+            m_assembler.movl_mEAX(address);
+            swap(X86::eax, dest);
+        }
+    }
+
+    void loadDouble(void* address, FPRegisterID dest)
+    {
+        move(ImmPtr(address), scratchRegister);
+        loadDouble(scratchRegister, dest);
+    }
+
+    void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
+    {
+        move(Imm32(*static_cast<int32_t*>(src.m_ptr)), scratchRegister);
+        m_assembler.cvtsi2sd_rr(scratchRegister, dest);
+    }
+
+    void store32(Imm32 imm, void* address)
+    {
+        move(X86::eax, scratchRegister);
+        move(imm, X86::eax);
+        m_assembler.movl_EAXm(address);
+        move(scratchRegister, X86::eax);
+    }
+
+    Call call()
+    {
+        DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+        Call result = Call(m_assembler.call(scratchRegister), Call::Linkable);
+        ASSERT(differenceBetween(label, result) == REPTACH_OFFSET_CALL_R11);
+        return result;
+    }
+
+    Call tailRecursiveCall()
+    {
+        DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+        Jump newJump = Jump(m_assembler.jmp_r(scratchRegister));
+        ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11);
+        return Call::fromTailJump(newJump);
+    }
+
+    Call makeTailRecursiveCall(Jump oldJump)
+    {
+        oldJump.link(this);
+        DataLabelPtr label = moveWithPatch(ImmPtr(0), scratchRegister);
+        Jump newJump = Jump(m_assembler.jmp_r(scratchRegister));
+        ASSERT(differenceBetween(label, newJump) == REPTACH_OFFSET_CALL_R11);
+        return Call::fromTailJump(newJump);
+    }
+
+
+    void addPtr(RegisterID src, RegisterID dest)
+    {
+        m_assembler.addq_rr(src, dest);
+    }
+
+    void addPtr(Imm32 imm, RegisterID srcDest)
+    {
+        m_assembler.addq_ir(imm.m_value, srcDest);
+    }
+
+    void addPtr(ImmPtr imm, RegisterID dest)
+    {
+        move(imm, scratchRegister);
+        m_assembler.addq_rr(scratchRegister, dest);
+    }
+
+    void addPtr(Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        m_assembler.leaq_mr(imm.m_value, src, dest);
+    }
+
+    void addPtr(Imm32 imm, Address address)
+    {
+        m_assembler.addq_im(imm.m_value, address.offset, address.base);
+    }
+
+    void addPtr(Imm32 imm, AbsoluteAddress address)
+    {
+        move(ImmPtr(address.m_ptr), scratchRegister);
+        addPtr(imm, Address(scratchRegister));
+    }
+    
+    void andPtr(RegisterID src, RegisterID dest)
+    {
+        m_assembler.andq_rr(src, dest);
+    }
+
+    void andPtr(Imm32 imm, RegisterID srcDest)
+    {
+        m_assembler.andq_ir(imm.m_value, srcDest);
+    }
+
+    void orPtr(RegisterID src, RegisterID dest)
+    {
+        m_assembler.orq_rr(src, dest);
+    }
+
+    void orPtr(ImmPtr imm, RegisterID dest)
+    {
+        move(imm, scratchRegister);
+        m_assembler.orq_rr(scratchRegister, dest);
+    }
+
+    void orPtr(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.orq_ir(imm.m_value, dest);
+    }
+
+    void rshiftPtr(RegisterID shift_amount, RegisterID dest)
+    {
+        // On x86 we can only shift by ecx; if asked to shift by another register we'll
+        // need rejig the shift amount into ecx first, and restore the registers afterwards.
+        if (shift_amount != X86::ecx) {
+            swap(shift_amount, X86::ecx);
+
+            // E.g. transform "shll %eax, %eax" -> "xchgl %eax, %ecx; shll %ecx, %ecx; xchgl %eax, %ecx"
+            if (dest == shift_amount)
+                m_assembler.sarq_CLr(X86::ecx);
+            // E.g. transform "shll %eax, %ecx" -> "xchgl %eax, %ecx; shll %ecx, %eax; xchgl %eax, %ecx"
+            else if (dest == X86::ecx)
+                m_assembler.sarq_CLr(shift_amount);
+            // E.g. transform "shll %eax, %ebx" -> "xchgl %eax, %ecx; shll %ecx, %ebx; xchgl %eax, %ecx"
+            else
+                m_assembler.sarq_CLr(dest);
+        
+            swap(shift_amount, X86::ecx);
+        } else
+            m_assembler.sarq_CLr(dest);
+    }
+
+    void rshiftPtr(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.sarq_i8r(imm.m_value, dest);
+    }
+
+    void subPtr(RegisterID src, RegisterID dest)
+    {
+        m_assembler.subq_rr(src, dest);
+    }
+    
+    void subPtr(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.subq_ir(imm.m_value, dest);
+    }
+    
+    void subPtr(ImmPtr imm, RegisterID dest)
+    {
+        move(imm, scratchRegister);
+        m_assembler.subq_rr(scratchRegister, dest);
+    }
+
+    void xorPtr(RegisterID src, RegisterID dest)
+    {
+        m_assembler.xorq_rr(src, dest);
+    }
+
+    void xorPtr(Imm32 imm, RegisterID srcDest)
+    {
+        m_assembler.xorq_ir(imm.m_value, srcDest);
+    }
+
+
+    void loadPtr(ImplicitAddress address, RegisterID dest)
+    {
+        m_assembler.movq_mr(address.offset, address.base, dest);
+    }
+
+    void loadPtr(BaseIndex address, RegisterID dest)
+    {
+        m_assembler.movq_mr(address.offset, address.base, address.index, address.scale, dest);
+    }
+
+    void loadPtr(void* address, RegisterID dest)
+    {
+        if (dest == X86::eax)
+            m_assembler.movq_mEAX(address);
+        else {
+            move(X86::eax, dest);
+            m_assembler.movq_mEAX(address);
+            swap(X86::eax, dest);
+        }
+    }
+
+    DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
+    {
+        m_assembler.movq_mr_disp32(address.offset, address.base, dest);
+        return DataLabel32(this);
+    }
+
+    void storePtr(RegisterID src, ImplicitAddress address)
+    {
+        m_assembler.movq_rm(src, address.offset, address.base);
+    }
+
+    void storePtr(RegisterID src, BaseIndex address)
+    {
+        m_assembler.movq_rm(src, address.offset, address.base, address.index, address.scale);
+    }
+    
+    void storePtr(RegisterID src, void* address)
+    {
+        if (src == X86::eax)
+            m_assembler.movq_EAXm(address);
+        else {
+            swap(X86::eax, src);
+            m_assembler.movq_EAXm(address);
+            swap(X86::eax, src);
+        }
+    }
+
+    void storePtr(ImmPtr imm, ImplicitAddress address)
+    {
+        intptr_t ptr = imm.asIntptr();
+        if (CAN_SIGN_EXTEND_32_64(ptr))
+            m_assembler.movq_i32m(static_cast<int>(ptr), address.offset, address.base);
+        else {
+            move(imm, scratchRegister);
+            storePtr(scratchRegister, address);
+        }
+    }
+
+    DataLabel32 storePtrWithAddressOffsetPatch(RegisterID src, Address address)
+    {
+        m_assembler.movq_rm_disp32(src, address.offset, address.base);
+        return DataLabel32(this);
+    }
+
+    void movePtrToDouble(RegisterID src, FPRegisterID dest)
+    {
+        m_assembler.movq_rr(src, dest);
+    }
+
+    void moveDoubleToPtr(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.movq_rr(src, dest);
+    }
+
+    void setPtr(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+    {
+        if (((cond == Equal) || (cond == NotEqual)) && !right.m_value)
+            m_assembler.testq_rr(left, left);
+        else
+            m_assembler.cmpq_ir(right.m_value, left);
+        m_assembler.setCC_r(x86Condition(cond), dest);
+        m_assembler.movzbl_rr(dest, dest);
+    }
+
+    Jump branchPtr(Condition cond, RegisterID left, RegisterID right)
+    {
+        m_assembler.cmpq_rr(right, left);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchPtr(Condition cond, RegisterID left, ImmPtr right)
+    {
+        intptr_t imm = right.asIntptr();
+        if (CAN_SIGN_EXTEND_32_64(imm)) {
+            if (!imm)
+                m_assembler.testq_rr(left, left);
+            else
+                m_assembler.cmpq_ir(imm, left);
+            return Jump(m_assembler.jCC(x86Condition(cond)));
+        } else {
+            move(right, scratchRegister);
+            return branchPtr(cond, left, scratchRegister);
+        }
+    }
+
+    Jump branchPtr(Condition cond, RegisterID left, Address right)
+    {
+        m_assembler.cmpq_mr(right.offset, right.base, left);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchPtr(Condition cond, AbsoluteAddress left, RegisterID right)
+    {
+        move(ImmPtr(left.m_ptr), scratchRegister);
+        return branchPtr(cond, Address(scratchRegister), right);
+    }
+
+    Jump branchPtr(Condition cond, Address left, RegisterID right)
+    {
+        m_assembler.cmpq_rm(right, left.offset, left.base);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchPtr(Condition cond, Address left, ImmPtr right)
+    {
+        move(right, scratchRegister);
+        return branchPtr(cond, left, scratchRegister);
+    }
+
+    Jump branchTestPtr(Condition cond, RegisterID reg, RegisterID mask)
+    {
+        m_assembler.testq_rr(reg, mask);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchTestPtr(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+    {
+        // if we are only interested in the low seven bits, this can be tested with a testb
+        if (mask.m_value == -1)
+            m_assembler.testq_rr(reg, reg);
+        else if ((mask.m_value & ~0x7f) == 0)
+            m_assembler.testb_i8r(mask.m_value, reg);
+        else
+            m_assembler.testq_i32r(mask.m_value, reg);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchTestPtr(Condition cond, Address address, Imm32 mask = Imm32(-1))
+    {
+        if (mask.m_value == -1)
+            m_assembler.cmpq_im(0, address.offset, address.base);
+        else
+            m_assembler.testq_i32m(mask.m_value, address.offset, address.base);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchTestPtr(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+    {
+        if (mask.m_value == -1)
+            m_assembler.cmpq_im(0, address.offset, address.base, address.index, address.scale);
+        else
+            m_assembler.testq_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+
+    Jump branchAddPtr(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        addPtr(src, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    Jump branchSubPtr(Condition cond, Imm32 imm, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        subPtr(imm, dest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
+    DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
+    {
+        m_assembler.movq_i64r(initialValue.asIntptr(), dest);
+        return DataLabelPtr(this);
+    }
+
+    Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        dataLabel = moveWithPatch(initialRightValue, scratchRegister);
+        return branchPtr(cond, left, scratchRegister);
+    }
+
+    Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        dataLabel = moveWithPatch(initialRightValue, scratchRegister);
+        return branchPtr(cond, left, scratchRegister);
+    }
+
+    DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+    {
+        DataLabelPtr label = moveWithPatch(initialValue, scratchRegister);
+        storePtr(scratchRegister, address);
+        return label;
+    }
+
+    Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
+    {
+        Label label(this);
+        loadPtr(address, dest);
+        return label;
+    }
+
+    bool supportsFloatingPoint() const { return true; }
+    // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
+    bool supportsFloatingPointTruncate() const { return true; }
+
+private:
+    friend class LinkBuffer;
+    friend class RepatchBuffer;
+
+    static void linkCall(void* code, Call call, FunctionPtr function)
+    {
+        if (!call.isFlagSet(Call::Near))
+            X86Assembler::linkPointer(code, X86Assembler::labelFor(call.m_jmp, -REPTACH_OFFSET_CALL_R11), function.value());
+        else
+            X86Assembler::linkCall(code, call.m_jmp, function.value());
+    }
+
+    static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
+    {
+        X86Assembler::repatchPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation(), destination.executableAddress());
+    }
+
+    static void repatchCall(CodeLocationCall call, FunctionPtr destination)
+    {
+        X86Assembler::repatchPointer(call.dataLabelPtrAtOffset(-REPTACH_OFFSET_CALL_R11).dataLocation(), destination.executableAddress());
+    }
+
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // MacroAssemblerX86_64_h
diff --git a/assembler/RepatchBuffer.h b/assembler/RepatchBuffer.h
new file mode 100644 (file)
index 0000000..89cbf06
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RepatchBuffer_h
+#define RepatchBuffer_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER)
+
+#include <MacroAssembler.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+// RepatchBuffer:
+//
+// This class is used to modify code after code generation has been completed,
+// and after the code has potentially already been executed.  This mechanism is
+// used to apply optimizations to the code.
+//
+class RepatchBuffer {
+    typedef MacroAssemblerCodePtr CodePtr;
+
+public:
+    RepatchBuffer(CodeBlock* codeBlock)
+    {
+        JITCode& code = codeBlock->getJITCode();
+        m_start = code.start();
+        m_size = code.size();
+
+        ExecutableAllocator::makeWritable(m_start, m_size);
+    }
+
+    ~RepatchBuffer()
+    {
+        ExecutableAllocator::makeExecutable(m_start, m_size);
+    }
+
+    void relink(CodeLocationJump jump, CodeLocationLabel destination)
+    {
+        MacroAssembler::repatchJump(jump, destination);
+    }
+
+    void relink(CodeLocationCall call, CodeLocationLabel destination)
+    {
+        MacroAssembler::repatchCall(call, destination);
+    }
+
+    void relink(CodeLocationCall call, FunctionPtr destination)
+    {
+        MacroAssembler::repatchCall(call, destination);
+    }
+
+    void relink(CodeLocationNearCall nearCall, CodePtr destination)
+    {
+        MacroAssembler::repatchNearCall(nearCall, CodeLocationLabel(destination));
+    }
+
+    void relink(CodeLocationNearCall nearCall, CodeLocationLabel destination)
+    {
+        MacroAssembler::repatchNearCall(nearCall, destination);
+    }
+
+    void repatch(CodeLocationDataLabel32 dataLabel32, int32_t value)
+    {
+        MacroAssembler::repatchInt32(dataLabel32, value);
+    }
+
+    void repatch(CodeLocationDataLabelPtr dataLabelPtr, void* value)
+    {
+        MacroAssembler::repatchPointer(dataLabelPtr, value);
+    }
+
+    void repatchLoadPtrToLEA(CodeLocationInstruction instruction)
+    {
+        MacroAssembler::repatchLoadPtrToLEA(instruction);
+    }
+
+    void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label)
+    {
+        relink(CodeLocationCall(CodePtr(returnAddress)), label);
+    }
+    
+    void relinkCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction)
+    {
+        relinkCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction));
+    }
+
+    void relinkCallerToFunction(ReturnAddressPtr returnAddress, FunctionPtr function)
+    {
+        relink(CodeLocationCall(CodePtr(returnAddress)), function);
+    }
+    
+    void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodeLocationLabel label)
+    {
+        relink(CodeLocationNearCall(CodePtr(returnAddress)), label);
+    }
+    
+    void relinkNearCallerToTrampoline(ReturnAddressPtr returnAddress, CodePtr newCalleeFunction)
+    {
+        relinkNearCallerToTrampoline(returnAddress, CodeLocationLabel(newCalleeFunction));
+    }
+
+private:
+    void* m_start;
+    size_t m_size;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER)
+
+#endif // RepatchBuffer_h
index de23e4563a13bf076f2a30b54b279db29659315a..b5b8808b91afc0a377f5f324912f0b92e34eedbf 100644 (file)
@@ -82,7 +82,31 @@ class X86Assembler {
 public:
     typedef X86::RegisterID RegisterID;
     typedef X86::XMMRegisterID XMMRegisterID;
+    typedef XMMRegisterID FPRegisterID;
 
+    typedef enum {
+        ConditionO,
+        ConditionNO,
+        ConditionB,
+        ConditionAE,
+        ConditionE,
+        ConditionNE,
+        ConditionBE,
+        ConditionA,
+        ConditionS,
+        ConditionNS,
+        ConditionP,
+        ConditionNP,
+        ConditionL,
+        ConditionGE,
+        ConditionLE,
+        ConditionG,
+
+        ConditionC  = ConditionB,
+        ConditionNC = ConditionAE,
+    } Condition;
+
+private:
     typedef enum {
         OP_ADD_EvGv                     = 0x01,
         OP_ADD_GvEv                     = 0x03,
@@ -90,10 +114,12 @@ public:
         OP_OR_GvEv                      = 0x0B,
         OP_2BYTE_ESCAPE                 = 0x0F,
         OP_AND_EvGv                     = 0x21,
+        OP_AND_GvEv                     = 0x23,
         OP_SUB_EvGv                     = 0x29,
         OP_SUB_GvEv                     = 0x2B,
         PRE_PREDICT_BRANCH_NOT_TAKEN    = 0x2E,
         OP_XOR_EvGv                     = 0x31,
+        OP_XOR_GvEv                     = 0x33,
         OP_CMP_EvGv                     = 0x39,
         OP_CMP_GvEv                     = 0x3B,
 #if PLATFORM(X86_64)
@@ -145,32 +171,32 @@ public:
         OP2_ADDSD_VsdWsd    = 0x58,
         OP2_MULSD_VsdWsd    = 0x59,
         OP2_SUBSD_VsdWsd    = 0x5C,
+        OP2_DIVSD_VsdWsd    = 0x5E,
+        OP2_XORPD_VpdWpd    = 0x57,
         OP2_MOVD_VdEd       = 0x6E,
         OP2_MOVD_EdVd       = 0x7E,
-        OP2_JO_rel32        = 0x80,
-        OP2_JB_rel32        = 0x82,
-        OP2_JAE_rel32       = 0x83,
-        OP2_JE_rel32        = 0x84,
-        OP2_JNE_rel32       = 0x85,
-        OP2_JBE_rel32       = 0x86,
-        OP2_JA_rel32        = 0x87,
-        OP2_JS_rel32        = 0x88,
-        OP2_JP_rel32        = 0x8A,
-        OP2_JL_rel32        = 0x8C,
-        OP2_JGE_rel32       = 0x8D,
-        OP2_JLE_rel32       = 0x8E,
-        OP2_JG_rel32        = 0x8F,
-        OP_SETE             = 0x94,
-        OP_SETNE            = 0x95,
+        OP2_JCC_rel32       = 0x80,
+        OP_SETCC            = 0x90,
         OP2_IMUL_GvEv       = 0xAF,
         OP2_MOVZX_GvEb      = 0xB6,
         OP2_MOVZX_GvEw      = 0xB7,
         OP2_PEXTRW_GdUdIb   = 0xC5,
     } TwoByteOpcodeID;
 
+    TwoByteOpcodeID jccRel32(Condition cond)
+    {
+        return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
+    }
+
+    TwoByteOpcodeID setccOpcode(Condition cond)
+    {
+        return (TwoByteOpcodeID)(OP_SETCC + cond);
+    }
+
     typedef enum {
         GROUP1_OP_ADD = 0,
         GROUP1_OP_OR  = 1,
+        GROUP1_OP_ADC = 2,
         GROUP1_OP_AND = 4,
         GROUP1_OP_SUB = 5,
         GROUP1_OP_XOR = 6,
@@ -183,6 +209,7 @@ public:
 
         GROUP3_OP_TEST = 0,
         GROUP3_OP_NOT  = 2,
+        GROUP3_OP_NEG  = 3,
         GROUP3_OP_IDIV = 7,
 
         GROUP5_OP_CALLN = 2,
@@ -192,9 +219,6 @@ public:
         GROUP11_MOV = 0,
     } GroupOpcodeID;
     
-    // Opaque label types
-    
-private:
     class X86InstructionFormatter;
 public:
 
@@ -222,16 +246,22 @@ public:
     public:
         JmpDst()
             : m_offset(-1)
+            , m_used(false)
         {
         }
 
+        bool isUsed() const { return m_used; }
+        void used() { m_used = true; }
     private:
         JmpDst(int offset)
             : m_offset(offset)
+            , m_used(false)
         {
+            ASSERT(m_offset == offset);
         }
 
-        int m_offset;
+        int m_offset : 31;
+        bool m_used : 1;
     };
 
     X86Assembler()
@@ -270,6 +300,19 @@ public:
 
     // Arithmetic operations:
 
+#if !PLATFORM(X86_64)
+    void adcl_im(int imm, void* addr)
+    {
+        if (CAN_SIGN_EXTEND_8_32(imm)) {
+            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
+            m_formatter.immediate8(imm);
+        } else {
+            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
+            m_formatter.immediate32(imm);
+        }
+    }
+#endif
+
     void addl_rr(RegisterID src, RegisterID dst)
     {
         m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
@@ -280,6 +323,11 @@ public:
         m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
     }
 
+    void addl_rm(RegisterID src, int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
+    }
+
     void addl_ir(int imm, RegisterID dst)
     {
         if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -318,6 +366,17 @@ public:
             m_formatter.immediate32(imm);
         }
     }
+
+    void addq_im(int imm, int offset, RegisterID base)
+    {
+        if (CAN_SIGN_EXTEND_8_32(imm)) {
+            m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
+            m_formatter.immediate8(imm);
+        } else {
+            m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
+            m_formatter.immediate32(imm);
+        }
+    }
 #else
     void addl_im(int imm, void* addr)
     {
@@ -336,6 +395,16 @@ public:
         m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
     }
 
+    void andl_mr(int offset, RegisterID base, RegisterID dst)
+    {
+        m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
+    }
+
+    void andl_rm(RegisterID src, int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
+    }
+
     void andl_ir(int imm, RegisterID dst)
     {
         if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -347,6 +416,17 @@ public:
         }
     }
 
+    void andl_im(int imm, int offset, RegisterID base)
+    {
+        if (CAN_SIGN_EXTEND_8_32(imm)) {
+            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
+            m_formatter.immediate8(imm);
+        } else {
+            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
+            m_formatter.immediate32(imm);
+        }
+    }
+
 #if PLATFORM(X86_64)
     void andq_rr(RegisterID src, RegisterID dst)
     {
@@ -363,13 +443,39 @@ public:
             m_formatter.immediate32(imm);
         }
     }
+#else
+    void andl_im(int imm, void* addr)
+    {
+        if (CAN_SIGN_EXTEND_8_32(imm)) {
+            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
+            m_formatter.immediate8(imm);
+        } else {
+            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
+            m_formatter.immediate32(imm);
+        }
+    }
 #endif
 
+    void negl_r(RegisterID dst)
+    {
+        m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
+    }
+
+    void negl_m(int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
+    }
+
     void notl_r(RegisterID dst)
     {
         m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
     }
 
+    void notl_m(int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
+    }
+
     void orl_rr(RegisterID src, RegisterID dst)
     {
         m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
@@ -380,6 +486,11 @@ public:
         m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
     }
 
+    void orl_rm(RegisterID src, int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
+    }
+
     void orl_ir(int imm, RegisterID dst)
     {
         if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -391,6 +502,17 @@ public:
         }
     }
 
+    void orl_im(int imm, int offset, RegisterID base)
+    {
+        if (CAN_SIGN_EXTEND_8_32(imm)) {
+            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
+            m_formatter.immediate8(imm);
+        } else {
+            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
+            m_formatter.immediate32(imm);
+        }
+    }
+
 #if PLATFORM(X86_64)
     void orq_rr(RegisterID src, RegisterID dst)
     {
@@ -407,6 +529,17 @@ public:
             m_formatter.immediate32(imm);
         }
     }
+#else
+    void orl_im(int imm, void* addr)
+    {
+        if (CAN_SIGN_EXTEND_8_32(imm)) {
+            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
+            m_formatter.immediate8(imm);
+        } else {
+            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
+            m_formatter.immediate32(imm);
+        }
+    }
 #endif
 
     void subl_rr(RegisterID src, RegisterID dst)
@@ -419,6 +552,11 @@ public:
         m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
     }
 
+    void subl_rm(RegisterID src, int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
+    }
+
     void subl_ir(int imm, RegisterID dst)
     {
         if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -475,6 +613,27 @@ public:
         m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
     }
 
+    void xorl_mr(int offset, RegisterID base, RegisterID dst)
+    {
+        m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
+    }
+
+    void xorl_rm(RegisterID src, int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
+    }
+
+    void xorl_im(int imm, int offset, RegisterID base)
+    {
+        if (CAN_SIGN_EXTEND_8_32(imm)) {
+            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
+            m_formatter.immediate8(imm);
+        } else {
+            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
+            m_formatter.immediate32(imm);
+        }
+    }
+
     void xorl_ir(int imm, RegisterID dst)
     {
         if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -555,7 +714,12 @@ public:
     {
         m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
     }
-    
+
+    void imull_mr(int offset, RegisterID base, RegisterID dst)
+    {
+        m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
+    }
+
     void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
     {
         m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
@@ -640,6 +804,11 @@ public:
         m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
     }
 
+    void cmpq_mr(int offset, RegisterID base, RegisterID src)
+    {
+        m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
+    }
+
     void cmpq_ir(int imm, RegisterID dst)
     {
         if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -696,6 +865,19 @@ public:
         m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
     }
 
+    void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
+    {
+        if (CAN_SIGN_EXTEND_8_32(imm)) {
+            m_formatter.prefix(PRE_OPERAND_SIZE);
+            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
+            m_formatter.immediate8(imm);
+        } else {
+            m_formatter.prefix(PRE_OPERAND_SIZE);
+            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
+            m_formatter.immediate16(imm);
+        }
+    }
+
     void testl_rr(RegisterID src, RegisterID dst)
     {
         m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
@@ -744,15 +926,26 @@ public:
     }
 #endif 
 
+    void testw_rr(RegisterID src, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_OPERAND_SIZE);
+        m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
+    }
+    
     void testb_i8r(int imm, RegisterID dst)
     {
         m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
         m_formatter.immediate8(imm);
     }
 
+    void setCC_r(Condition cond, RegisterID dst)
+    {
+        m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
+    }
+
     void sete_r(RegisterID dst)
     {
-        m_formatter.twoByteOp8(OP_SETE, (GroupOpcodeID)0, dst);
+        m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
     }
 
     void setz_r(RegisterID dst)
@@ -762,7 +955,7 @@ public:
 
     void setne_r(RegisterID dst)
     {
-        m_formatter.twoByteOp8(OP_SETNE, (GroupOpcodeID)0, dst);
+        m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
     }
 
     void setnz_r(RegisterID dst)
@@ -883,6 +1076,12 @@ public:
         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
     }
 
+    void movq_EAXm(void* addr)
+    {
+        m_formatter.oneByteOp64(OP_MOV_OvEAX);
+        m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
+    }
+
     void movq_mr(int offset, RegisterID base, RegisterID dst)
     {
         m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
@@ -898,6 +1097,12 @@ public:
         m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
     }
 
+    void movq_i32m(int imm, int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
+        m_formatter.immediate32(imm);
+    }
+
     void movq_i64r(int64_t imm, RegisterID dst)
     {
         m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
@@ -911,6 +1116,14 @@ public:
     
     
 #else
+    void movl_rm(RegisterID src, void* addr)
+    {
+        if (src == X86::eax)
+            movl_EAXm(addr);
+        else 
+            m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
+    }
+    
     void movl_mr(void* addr, RegisterID dst)
     {
         if (dst == X86::eax)
@@ -948,6 +1161,12 @@ public:
     {
         m_formatter.oneByteOp(OP_LEA, dst, base, offset);
     }
+#if PLATFORM(X86_64)
+    void leaq_mr(int offset, RegisterID base, RegisterID dst)
+    {
+        m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
+    }
+#endif
 
     // Flow control:
 
@@ -962,6 +1181,11 @@ public:
         m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
         return JmpSrc(m_formatter.size());
     }
+    
+    void call_m(int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
+    }
 
     JmpSrc jmp()
     {
@@ -969,9 +1193,13 @@ public:
         return m_formatter.immediateRel32();
     }
     
-    void jmp_r(RegisterID dst)
+    // Return a JmpSrc so we have a label to the jump, so we can use this
+    // To make a tail recursive call on x86-64.  The MacroAssembler
+    // really shouldn't wrap this as a Jump, since it can't be linked. :-/
+    JmpSrc jmp_r(RegisterID dst)
     {
         m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
+        return JmpSrc(m_formatter.size());
     }
     
     void jmp_m(int offset, RegisterID base)
@@ -981,7 +1209,7 @@ public:
 
     JmpSrc jne()
     {
-        m_formatter.twoByteOp(OP2_JNE_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionNE));
         return m_formatter.immediateRel32();
     }
     
@@ -992,73 +1220,84 @@ public:
 
     JmpSrc je()
     {
-        m_formatter.twoByteOp(OP2_JE_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionE));
         return m_formatter.immediateRel32();
     }
     
+    JmpSrc jz()
+    {
+        return je();
+    }
+
     JmpSrc jl()
     {
-        m_formatter.twoByteOp(OP2_JL_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionL));
         return m_formatter.immediateRel32();
     }
     
     JmpSrc jb()
     {
-        m_formatter.twoByteOp(OP2_JB_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionB));
         return m_formatter.immediateRel32();
     }
     
     JmpSrc jle()
     {
-        m_formatter.twoByteOp(OP2_JLE_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionLE));
         return m_formatter.immediateRel32();
     }
     
     JmpSrc jbe()
     {
-        m_formatter.twoByteOp(OP2_JBE_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionBE));
         return m_formatter.immediateRel32();
     }
     
     JmpSrc jge()
     {
-        m_formatter.twoByteOp(OP2_JGE_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionGE));
         return m_formatter.immediateRel32();
     }
 
     JmpSrc jg()
     {
-        m_formatter.twoByteOp(OP2_JG_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionG));
         return m_formatter.immediateRel32();
     }
 
     JmpSrc ja()
     {
-        m_formatter.twoByteOp(OP2_JA_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionA));
         return m_formatter.immediateRel32();
     }
     
     JmpSrc jae()
     {
-        m_formatter.twoByteOp(OP2_JAE_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionAE));
         return m_formatter.immediateRel32();
     }
     
     JmpSrc jo()
     {
-        m_formatter.twoByteOp(OP2_JO_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionO));
         return m_formatter.immediateRel32();
     }
 
     JmpSrc jp()
     {
-        m_formatter.twoByteOp(OP2_JP_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionP));
         return m_formatter.immediateRel32();
     }
     
     JmpSrc js()
     {
-        m_formatter.twoByteOp(OP2_JS_rel32);
+        m_formatter.twoByteOp(jccRel32(ConditionS));
+        return m_formatter.immediateRel32();
+    }
+
+    JmpSrc jCC(Condition cond)
+    {
+        m_formatter.twoByteOp(jccRel32(cond));
         return m_formatter.immediateRel32();
     }
 
@@ -1082,6 +1321,20 @@ public:
         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
     }
 
+    void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F2);
+        m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
+    }
+
+#if !PLATFORM(X86_64)
+    void cvtsi2sd_mr(void* address, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F2);
+        m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
+    }
+#endif
+
     void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
     {
         m_formatter.prefix(PRE_SSE_F2);
@@ -1120,6 +1373,14 @@ public:
         m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
     }
 
+#if !PLATFORM(X86_64)
+    void movsd_mr(void* address, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F2);
+        m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
+    }
+#endif
+
     void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
     {
         m_formatter.prefix(PRE_SSE_F2);
@@ -1157,6 +1418,30 @@ public:
         m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_66);
+        m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
+    }
+
+    void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F2);
+        m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+    }
+
+    void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F2);
+        m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
+    }
+
+    void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_66);
+        m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
+    }
+
     // Misc instructions:
 
     void int3()
@@ -1181,6 +1466,11 @@ public:
         return JmpDst(m_formatter.size());
     }
     
+    static JmpDst labelFor(JmpSrc jump, intptr_t offset = 0)
+    {
+        return JmpDst(jump.m_offset + offset);
+    }
+    
     JmpDst align(int alignment)
     {
         while (!m_formatter.isAligned(alignment))
@@ -1190,31 +1480,83 @@ public:
     }
 
     // Linking & patching:
+    //
+    // 'link' and 'patch' methods are for use on unprotected code - such as the code
+    // within the AssemblerBuffer, and code being patched by the patch buffer.  Once
+    // code has been finalized it is (platform support permitting) within a non-
+    // writable region of memory; to modify the code in an execute-only execuable
+    // pool the 'repatch' and 'relink' methods should be used.
 
-    void link(JmpSrc from, JmpDst to)
+    void linkJump(JmpSrc from, JmpDst to)
     {
-        ASSERT(to.m_offset != -1);
         ASSERT(from.m_offset != -1);
-        
-        reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
+        ASSERT(to.m_offset != -1);
+
+        char* code = reinterpret_cast<char*>(m_formatter.data());
+        setRel32(code + from.m_offset, code + to.m_offset);
     }
     
-    static void patchAddress(void* code, JmpDst position, void* value)
+    static void linkJump(void* code, JmpSrc from, void* to)
     {
-        ASSERT(position.m_offset != -1);
-        
-        reinterpret_cast<void**>(reinterpret_cast<ptrdiff_t>(code) + position.m_offset)[-1] = value;
+        ASSERT(from.m_offset != -1);
+
+        setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
     }
-    
-    static void link(void* code, JmpSrc from, void* to)
+
+    static void linkCall(void* code, JmpSrc from, void* to)
     {
         ASSERT(from.m_offset != -1);
-        
-        reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
+
+        setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
+    }
+
+    static void linkPointer(void* code, JmpDst where, void* value)
+    {
+        ASSERT(where.m_offset != -1);
+
+        setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
+    }
+
+    static void relinkJump(void* from, void* to)
+    {
+        setRel32(from, to);
+    }
+    
+    static void relinkCall(void* from, void* to)
+    {
+        setRel32(from, to);
+    }
+
+    static void repatchInt32(void* where, int32_t value)
+    {
+        setInt32(where, value);
+    }
+
+    static void repatchPointer(void* where, void* value)
+    {
+        setPointer(where, value);
+    }
+
+    static void repatchLoadPtrToLEA(void* where)
+    {
+#if PLATFORM(X86_64)
+        // On x86-64 pointer memory accesses require a 64-bit operand, and as such a REX prefix.
+        // Skip over the prefix byte.
+        where = reinterpret_cast<char*>(where) + 1;
+#endif
+        *reinterpret_cast<unsigned char*>(where) = static_cast<unsigned char>(OP_LEA);
     }
     
+    static unsigned getCallReturnOffset(JmpSrc call)
+    {
+        ASSERT(call.m_offset >= 0);
+        return call.m_offset;
+    }
+
     static void* getRelocatedAddress(void* code, JmpSrc jump)
     {
+        ASSERT(jump.m_offset != -1);
+
         return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
     }
     
@@ -1240,23 +1582,6 @@ public:
         return dst.m_offset - src.m_offset;
     }
     
-    static void patchImmediate(intptr_t where, int32_t value)
-    {
-        reinterpret_cast<int32_t*>(where)[-1] = value;
-    }
-    
-    static void patchPointer(intptr_t where, intptr_t value)
-    {
-        reinterpret_cast<intptr_t*>(where)[-1] = value;
-    }
-    
-    static void patchBranchOffset(intptr_t where, void* destination)
-    {
-        intptr_t offset = reinterpret_cast<intptr_t>(destination) - where;
-        ASSERT(offset == static_cast<int32_t>(offset));
-        reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset);
-    }
-    
     void* executableCopy(ExecutablePool* allocator)
     {
         void* copy = m_formatter.executableCopy(allocator);
@@ -1266,6 +1591,24 @@ public:
 
 private:
 
+    static void setPointer(void* where, void* value)
+    {
+        reinterpret_cast<void**>(where)[-1] = value;
+    }
+
+    static void setInt32(void* where, int32_t value)
+    {
+        reinterpret_cast<int32_t*>(where)[-1] = value;
+    }
+
+    static void setRel32(void* from, void* to)
+    {
+        intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
+        ASSERT(offset == static_cast<int32_t>(offset));
+
+        setInt32(from, offset);
+    }
+
     class X86InstructionFormatter {
 
         static const int maxInstructionSize = 16;
@@ -1383,6 +1726,16 @@ private:
             memoryModRM(reg, base, index, scale, offset);
         }
 
+#if !PLATFORM(X86_64)
+        void twoByteOp(TwoByteOpcodeID opcode, int reg, void* address)
+        {
+            m_buffer.ensureSpace(maxInstructionSize);
+            m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
+            m_buffer.putByteUnchecked(opcode);
+            memoryModRM(reg, address);
+        }
+#endif
+
 #if PLATFORM(X86_64)
         // Quad-word-sized operands:
         //
@@ -1507,6 +1860,11 @@ private:
             m_buffer.putByteUnchecked(imm);
         }
 
+        void immediate16(int imm)
+        {
+            m_buffer.putShortUnchecked(imm);
+        }
+
         void immediate32(int imm)
         {
             m_buffer.putIntUnchecked(imm);
@@ -1601,13 +1959,8 @@ private:
         {
             ASSERT(mode != ModRmRegister);
 
-            // Encode sacle of (1,2,4,8) -> (0,1,2,3)
-            int shift = 0;
-            while (scale >>= 1)
-                shift++;
-
             putModRm(mode, reg, hasSib);
-            m_buffer.putByteUnchecked((shift << 6) | ((index & 7) << 3) | (base & 7));
+            m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
         }
 
         void registerModRM(int reg, RegisterID rm)
index be060d01cb0fa5c5a3b0e8fe848b4eafc5176788..1f64992ea14580d403e0de8e333352cdc36b1f3c 100644 (file)
@@ -55,8 +55,11 @@ static UString escapeQuotes(const UString& str)
     return result;
 }
 
-static UString valueToSourceString(ExecState* exec, JSValuePtr val)
+static UString valueToSourceString(ExecState* exec, JSValue val)
 {
+    if (!val)
+        return "0";
+
     if (val.isString()) {
         UString result("\"");
         result += escapeQuotes(val.toString(exec)) + "\"";
@@ -74,7 +77,7 @@ static CString registerName(int r)
     return (UString("r") + UString::from(r)).UTF8String();
 }
 
-static CString constantName(ExecState* exec, int k, JSValuePtr value)
+static CString constantName(ExecState* exec, int k, JSValue value)
 {
     return (valueToSourceString(exec, value) + "(@k" + UString::from(k) + ")").UTF8String();
 }
@@ -357,21 +360,12 @@ void CodeBlock::dump(ExecState* exec) const
         unsigned registerIndex = m_numVars;
         size_t i = 0;
         do {
-            printf("   r%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue(exec)).ascii());
+            printf("   r%u = %s\n", registerIndex, valueToSourceString(exec, m_constantRegisters[i].jsValue()).ascii());
             ++i;
             ++registerIndex;
         } while (i < m_constantRegisters.size());
     }
 
-    if (m_rareData && !m_rareData->m_unexpectedConstants.isEmpty()) {
-        printf("\nUnexpected Constants:\n");
-        size_t i = 0;
-        do {
-            printf("  k%u = %s\n", static_cast<unsigned>(i), valueToSourceString(exec, m_rareData->m_unexpectedConstants[i]).ascii());
-            ++i;
-        } while (i < m_rareData->m_unexpectedConstants.size());
-    }
-    
     if (m_rareData && !m_rareData->m_regexps.isEmpty()) {
         printf("\nm_regexps:\n");
         size_t i = 0;
@@ -497,15 +491,13 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             printf("[%4d] create_arguments\n", location);
             break;
         }
-        case op_convert_this: {
-            int r0 = (++it)->u.operand;
-            printf("[%4d] convert_this %s\n", location, registerName(r0).c_str());
+        case op_init_arguments: {
+            printf("[%4d] init_arguments\n", location);
             break;
         }
-        case op_unexpected_load: {
+        case op_convert_this: {
             int r0 = (++it)->u.operand;
-            int k0 = (++it)->u.operand;
-            printf("[%4d] unexpected_load\t %s, %s\n", location, registerName(r0).c_str(), constantName(exec, k0, unexpectedConstant(k0)).c_str());
+            printf("[%4d] convert_this %s\n", location, registerName(r0).c_str());
             break;
         }
         case op_new_object: {
@@ -606,6 +598,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_div: {
             printBinaryOp(location, it, "div");
+            ++it;
             break;
         }
         case op_mod: {
@@ -703,7 +696,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_resolve_global: {
             int r0 = (++it)->u.operand;
-            JSValuePtr scope = JSValuePtr((++it)->u.jsCell);
+            JSValue scope = JSValue((++it)->u.jsCell);
             int id0 = (++it)->u.operand;
             printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).c_str());
             it += 2;
@@ -725,13 +718,13 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_get_global_var: {
             int r0 = (++it)->u.operand;
-            JSValuePtr scope = JSValuePtr((++it)->u.jsCell);
+            JSValue scope = JSValue((++it)->u.jsCell);
             int index = (++it)->u.operand;
             printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(r0).c_str(), valueToSourceString(exec, scope).ascii(), index);
             break;
         }
         case op_put_global_var: {
-            JSValuePtr scope = JSValuePtr((++it)->u.jsCell);
+            JSValue scope = JSValue((++it)->u.jsCell);
             int index = (++it)->u.operand;
             int r0 = (++it)->u.operand;
             printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(r0).c_str());
@@ -750,13 +743,6 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
             break;
         }
-        case op_resolve_func: {
-            int r0 = (++it)->u.operand;
-            int r1 = (++it)->u.operand;
-            int id0 = (++it)->u.operand;
-            printf("[%4d] resolve_func\t %s, %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
-            break;
-        }
         case op_get_by_id: {
             printGetByIdOp(location, it, m_identifiers, "get_by_id");
             break;
@@ -823,6 +809,10 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(r1).c_str());
             break;
         }
+        case op_method_check: {
+            printf("[%4d] op_method_check\n", location);
+            break;
+        }
         case op_del_by_id: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
@@ -888,6 +878,13 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             printConditionalJump(begin, it, location, "jneq_null");
             break;
         }
+        case op_jneq_ptr: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            int offset = (++it)->u.operand;
+            printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+            break;
+        }
         case op_jnless: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
@@ -895,6 +892,13 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
             break;
         }
+        case op_jnlesseq: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            int offset = (++it)->u.operand;
+            printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(r0).c_str(), registerName(r1).c_str(), offset, locationForOffset(begin, it, offset));
+            break;
+        }
         case op_loop_if_less: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
@@ -958,6 +962,18 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), argCount, registerOffset);
             break;
         }
+        case op_call_varargs: {
+            int dst = (++it)->u.operand;
+            int func = (++it)->u.operand;
+            int argCount = (++it)->u.operand;
+            int registerOffset = (++it)->u.operand;
+            printf("[%4d] call_varargs\t %s, %s, %s, %d\n", location, registerName(dst).c_str(), registerName(func).c_str(), registerName(argCount).c_str(), registerOffset);
+            break;
+        }
+        case op_load_varargs: {
+            printUnaryOp(location, it, "load_varargs");
+            break;
+        }
         case op_tear_off_activation: {
             int r0 = (++it)->u.operand;
             printf("[%4d] tear_off_activation\t %s\n", location, registerName(r0).c_str());
@@ -988,6 +1004,19 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             printf("[%4d] construct_verify\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
             break;
         }
+        case op_strcat: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            int count = (++it)->u.operand;
+            printf("[%4d] op_strcat\t %s, %s, %d\n", location, registerName(r0).c_str(), registerName(r1).c_str(), count);
+            break;
+        }
+        case op_to_primitive: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            printf("[%4d] op_to_primitive\t %s, %s\n", location, registerName(r0).c_str(), registerName(r1).c_str());
+            break;
+        }
         case op_get_pnames: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
@@ -1037,7 +1066,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int r0 = (++it)->u.operand;
             int errorType = (++it)->u.operand;
             int k0 = (++it)->u.operand;
-            printf("[%4d] new_error\t %s, %d, %s\n", location, registerName(r0).c_str(), errorType, constantName(exec, k0, unexpectedConstant(k0)).c_str());
+            printf("[%4d] new_error\t %s, %d, %s\n", location, registerName(r0).c_str(), errorType, constantName(exec, k0, getConstant(k0)).c_str());
             break;
         }
         case op_jsr: {
@@ -1095,7 +1124,6 @@ static HashSet<CodeBlock*> liveCodeBlockSet;
 #define FOR_EACH_MEMBER_VECTOR_RARE_DATA(macro) \
     macro(regexps) \
     macro(functions) \
-    macro(unexpectedConstants) \
     macro(exceptionHandlers) \
     macro(immediateSwitchJumpTables) \
     macro(characterSwitchJumpTables) \
@@ -1218,10 +1246,30 @@ void CodeBlock::dumpStatistics()
 #endif
 }
 
+CodeBlock::CodeBlock(ScopeNode* ownerNode)
+    : m_numCalleeRegisters(0)
+    , m_numVars(0)
+    , m_numParameters(0)
+    , m_ownerNode(ownerNode)
+    , m_globalData(0)
+#ifndef NDEBUG
+    , m_instructionCount(0)
+#endif
+    , m_needsFullScopeChain(false)
+    , m_usesEval(false)
+    , m_isNumericCompareFunction(false)
+    , m_codeType(NativeCode)
+    , m_source(0)
+    , m_sourceOffset(0)
+    , m_exceptionInfo(0)
+{
+#if DUMP_CODE_BLOCK_STATISTICS
+    liveCodeBlockSet.add(this);
+#endif
+}
 
 CodeBlock::CodeBlock(ScopeNode* ownerNode, CodeType codeType, PassRefPtr<SourceProvider> sourceProvider, unsigned sourceOffset)
     : m_numCalleeRegisters(0)
-    , m_numConstants(0)
     , m_numVars(0)
     , m_numParameters(0)
     , m_ownerNode(ownerNode)
@@ -1267,15 +1315,27 @@ CodeBlock::~CodeBlock()
             callLinkInfo->callee->removeCaller(callLinkInfo);
     }
 
+    for (size_t size = m_methodCallLinkInfos.size(), i = 0; i < size; ++i) {
+        if (Structure* structure = m_methodCallLinkInfos[i].cachedStructure) {
+            structure->deref();
+            // Both members must be filled at the same time
+            ASSERT(m_methodCallLinkInfos[i].cachedPrototypeStructure);
+            m_methodCallLinkInfos[i].cachedPrototypeStructure->deref();
+        }
+    }
+
+#if ENABLE(JIT_OPTIMIZE_CALL)
     unlinkCallers();
 #endif
 
+#endif // !ENABLE(JIT)
+
 #if DUMP_CODE_BLOCK_STATISTICS
     liveCodeBlockSet.remove(this);
 #endif
 }
 
-#if ENABLE(JIT
+#if ENABLE(JIT_OPTIMIZE_CALL)
 void CodeBlock::unlinkCallers()
 {
     size_t size = m_linkedCallerList.size();
@@ -1290,6 +1350,7 @@ void CodeBlock::unlinkCallers()
 
 void CodeBlock::derefStructures(Instruction* vPC) const
 {
+    ASSERT(m_codeType != NativeCode);
     Interpreter* interpreter = m_globalData->interpreter;
 
     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
@@ -1335,6 +1396,7 @@ void CodeBlock::derefStructures(Instruction* vPC) const
 
 void CodeBlock::refStructures(Instruction* vPC) const
 {
+    ASSERT(m_codeType != NativeCode);
     Interpreter* interpreter = m_globalData->interpreter;
 
     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
@@ -1379,16 +1441,13 @@ void CodeBlock::mark()
         for (size_t i = 0; i < m_rareData->m_functions.size(); ++i)
             m_rareData->m_functions[i]->body()->mark();
 
-        for (size_t i = 0; i < m_rareData->m_unexpectedConstants.size(); ++i) {
-            if (!m_rareData->m_unexpectedConstants[i].marked())
-                m_rareData->m_unexpectedConstants[i].mark();
-        }
         m_rareData->m_evalCodeCache.mark();
     }
 }
 
 void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
 {
+    ASSERT(m_codeType != NativeCode);
     if (m_exceptionInfo)
         return;
 
@@ -1420,7 +1479,7 @@ void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
 
 #if ENABLE(JIT)
             JIT::compile(m_globalData, &newCodeBlock);
-            ASSERT(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize);
+            ASSERT(newFunctionBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size());
 #endif
 
             m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release());
@@ -1441,7 +1500,7 @@ void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
 
 #if ENABLE(JIT)
             JIT::compile(m_globalData, &newCodeBlock);
-            ASSERT(newCodeBlock.m_jitCode.codeSize == m_jitCode.codeSize);
+            ASSERT(newEvalBody->generatedJITCode().size() == ownerNode()->generatedJITCode().size());
 #endif
 
             m_exceptionInfo.set(newCodeBlock.m_exceptionInfo.release());
@@ -1459,6 +1518,7 @@ void CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame)
 
 HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
 {
+    ASSERT(m_codeType != NativeCode);
     ASSERT(bytecodeOffset < m_instructionCount);
 
     if (!m_rareData)
@@ -1477,6 +1537,7 @@ HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset)
 
 int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset)
 {
+    ASSERT(m_codeType != NativeCode);
     ASSERT(bytecodeOffset < m_instructionCount);
 
     reparseForExceptionInfoIfNecessary(callFrame);
@@ -1502,6 +1563,7 @@ int CodeBlock::lineNumberForBytecodeOffset(CallFrame* callFrame, unsigned byteco
 
 int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset)
 {
+    ASSERT(m_codeType != NativeCode);
     ASSERT(bytecodeOffset < m_instructionCount);
 
     reparseForExceptionInfoIfNecessary(callFrame);
@@ -1541,6 +1603,7 @@ int CodeBlock::expressionRangeForBytecodeOffset(CallFrame* callFrame, unsigned b
 
 bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsigned bytecodeOffset, OpcodeID& opcodeID)
 {
+    ASSERT(m_codeType != NativeCode);
     ASSERT(bytecodeOffset < m_instructionCount);
 
     reparseForExceptionInfoIfNecessary(callFrame);
@@ -1569,6 +1632,7 @@ bool CodeBlock::getByIdExceptionInfoForBytecodeOffset(CallFrame* callFrame, unsi
 #if ENABLE(JIT)
 bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex)
 {
+    ASSERT(m_codeType != NativeCode);
     ASSERT(bytecodeOffset < m_instructionCount);
 
     if (!m_rareData || !m_rareData->m_functionRegisterInfos.size())
@@ -1595,6 +1659,7 @@ bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int&
 #if !ENABLE(JIT)
 bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset)
 {
+    ASSERT(m_codeType != NativeCode);
     if (m_globalResolveInstructions.isEmpty())
         return false;
 
@@ -1615,6 +1680,7 @@ bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOff
 #else
 bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
 {
+    ASSERT(m_codeType != NativeCode);
     if (m_globalResolveInfos.isEmpty())
         return false;
 
@@ -1635,9 +1701,10 @@ bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
 #endif
 
 #if ENABLE(JIT)
-void CodeBlock::setJITCode(JITCodeRef& jitCode)
+void CodeBlock::setJITCode(JITCode jitCode)
 {
-    m_jitCode = jitCode;
+    ASSERT(m_codeType != NativeCode); 
+    ownerNode()->setJITCode(jitCode);
 #if !ENABLE(OPCODE_SAMPLING)
     if (!BytecodeGenerator::dumpsGeneratedCode())
         m_instructions.clear();
@@ -1672,7 +1739,6 @@ void CodeBlock::shrinkToFit()
     if (m_rareData) {
         m_rareData->m_exceptionHandlers.shrinkToFit();
         m_rareData->m_functions.shrinkToFit();
-        m_rareData->m_unexpectedConstants.shrinkToFit();
         m_rareData->m_regexps.shrinkToFit();
         m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
         m_rareData->m_characterSwitchJumpTables.shrinkToFit();
index e5d78d3ea8edee610002915a7adfb4239e71ecd8..eaf5d1d2679fffb3be9438f64723d484bc374ad5 100644 (file)
 
 #include "EvalCodeCache.h"
 #include "Instruction.h"
+#include "JITCode.h"
 #include "JSGlobalObject.h"
 #include "JumpTable.h"
 #include "Nodes.h"
 #include "RegExp.h"
 #include "UString.h"
+#include <wtf/FastAllocBase.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 
 #include "StructureStubInfo.h"
 #endif
 
+// Register numbers used in bytecode operations have different meaning accoring to their ranges:
+//      0x80000000-0xFFFFFFFF  Negative indicies from the CallFrame pointer are entries in the call frame, see RegisterFile.h.
+//      0x00000000-0x3FFFFFFF  Forwards indices from the CallFrame pointer are local vars and temporaries with the function's callframe.
+//      0x40000000-0x7FFFFFFF  Positive indices from 0x40000000 specify entries in the constant pool on the CodeBlock.
+static const int FirstConstantRegisterIndex = 0x40000000;
+
 namespace JSC {
 
     class ExecState;
 
-    enum CodeType { GlobalCode, EvalCode, FunctionCode };
+    enum CodeType { GlobalCode, EvalCode, FunctionCode, NativeCode };
 
     static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
 
@@ -58,38 +66,10 @@ namespace JSC {
         uint32_t target;
         uint32_t scopeDepth;
 #if ENABLE(JIT)
-        void* nativeCode;
+        CodeLocationLabel nativeCode;
 #endif
     };
 
-#if ENABLE(JIT)
-    // The code, and the associated pool from which it was allocated.
-    struct JITCodeRef {
-        void* code;
-#ifndef NDEBUG
-        unsigned codeSize;
-#endif
-        RefPtr<ExecutablePool> executablePool;
-
-        JITCodeRef()
-            : code(0)
-#ifndef NDEBUG
-            , codeSize(0)
-#endif
-        {
-        }
-        
-        JITCodeRef(void* code, PassRefPtr<ExecutablePool> executablePool)
-            : code(code)
-#ifndef NDEBUG
-            , codeSize(0)
-#endif
-            , executablePool(executablePool)
-        {
-        }
-    };
-#endif
-
     struct ExpressionRangeInfo {
         enum {
             MaxOffset = (1 << 7) - 1, 
@@ -117,19 +97,15 @@ namespace JSC {
 #if ENABLE(JIT)
     struct CallLinkInfo {
         CallLinkInfo()
-            : callReturnLocation(0)
-            , hotPathBegin(0)
-            , hotPathOther(0)
-            , coldPathOther(0)
-            , callee(0)
+            : callee(0)
         {
         }
     
         unsigned bytecodeIndex;
-        void* callReturnLocation;
-        void* hotPathBegin;
-        void* hotPathOther;
-        void* coldPathOther;
+        CodeLocationNearCall callReturnLocation;
+        CodeLocationDataLabelPtr hotPathBegin;
+        CodeLocationNearCall hotPathOther;
+        CodeBlock* ownerCodeBlock;
         CodeBlock* callee;
         unsigned position;
         
@@ -137,6 +113,19 @@ namespace JSC {
         bool isLinked() { return callee; }
     };
 
+    struct MethodCallLinkInfo {
+        MethodCallLinkInfo()
+            : cachedStructure(0)
+            , cachedPrototypeStructure(0)
+        {
+        }
+
+        CodeLocationCall callReturnLocation;
+        CodeLocationDataLabelPtr structureLabel;
+        Structure* cachedStructure;
+        Structure* cachedPrototypeStructure;
+    };
+
     struct FunctionRegisterInfo {
         FunctionRegisterInfo(unsigned bytecodeOffset, int functionRegisterIndex)
             : bytecodeOffset(bytecodeOffset)
@@ -161,14 +150,18 @@ namespace JSC {
         unsigned bytecodeOffset;
     };
 
-    struct PC {
-        PC(ptrdiff_t nativePCOffset, unsigned bytecodeIndex)
-            : nativePCOffset(nativePCOffset)
+    // This structure is used to map from a call return location
+    // (given as an offset in bytes into the JIT code) back to
+    // the bytecode index of the corresponding bytecode operation.
+    // This is then used to look up the corresponding handler.
+    struct CallReturnOffsetToBytecodeIndex {
+        CallReturnOffsetToBytecodeIndex(unsigned callReturnOffset, unsigned bytecodeIndex)
+            : callReturnOffset(callReturnOffset)
             , bytecodeIndex(bytecodeIndex)
         {
         }
 
-        ptrdiff_t nativePCOffset;
+        unsigned callReturnOffset;
         unsigned bytecodeIndex;
     };
 
@@ -176,17 +169,22 @@ namespace JSC {
 
     inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
     {
-        return structureStubInfo->callReturnLocation;
+        return structureStubInfo->callReturnLocation.executableAddress();
     }
 
     inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo)
     {
-        return callLinkInfo->callReturnLocation;
+        return callLinkInfo->callReturnLocation.executableAddress();
+    }
+
+    inline void* getMethodCallLinkInfoReturnLocation(MethodCallLinkInfo* methodCallLinkInfo)
+    {
+        return methodCallLinkInfo->callReturnLocation.executableAddress();
     }
 
-    inline ptrdiff_t getNativePCOffset(PC* pc)
+    inline unsigned getCallReturnOffset(CallReturnOffsetToBytecodeIndex* pc)
     {
-        return pc->nativePCOffset;
+        return pc->callReturnOffset;
     }
 
     // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
@@ -226,16 +224,17 @@ namespace JSC {
     }
 #endif
 
-    class CodeBlock {
+    class CodeBlock : public WTF::FastAllocBase {
         friend class JIT;
     public:
+        CodeBlock(ScopeNode* ownerNode);
         CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset);
         ~CodeBlock();
 
         void mark();
         void refStructures(Instruction* vPC) const;
         void derefStructures(Instruction* vPC) const;
-#if ENABLE(JIT)
+#if ENABLE(JIT_OPTIMIZE_CALL)
         void unlinkCallers();
 #endif
 
@@ -258,19 +257,9 @@ namespace JSC {
             return false;
         }
 
-        ALWAYS_INLINE bool isConstantRegisterIndex(int index)
-        {
-            return index >= m_numVars && index < m_numVars + m_numConstants;
-        }
-
-        ALWAYS_INLINE JSValuePtr getConstant(int index)
-        {
-            return m_constantRegisters[index - m_numVars].getJSValue();
-        }
-
         ALWAYS_INLINE bool isTemporaryRegisterIndex(int index)
         {
-            return index >= m_numVars + m_numConstants;
+            return index >= m_numVars;
         }
 
         HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset);
@@ -298,21 +287,25 @@ namespace JSC {
             m_linkedCallerList.shrink(lastPos);
         }
 
-        StructureStubInfo& getStubInfo(void* returnAddress)
+        StructureStubInfo& getStubInfo(ReturnAddressPtr returnAddress)
         {
-            return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress));
+            return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress.value()));
         }
 
-        CallLinkInfo& getCallLinkInfo(void* returnAddress)
+        CallLinkInfo& getCallLinkInfo(ReturnAddressPtr returnAddress)
         {
-            return *(binaryChop<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress));
+            return *(binaryChop<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress.value()));
         }
 
-        unsigned getBytecodeIndex(CallFrame* callFrame, void* nativePC)
+        MethodCallLinkInfo& getMethodCallLinkInfo(ReturnAddressPtr returnAddress)
+        {
+            return *(binaryChop<MethodCallLinkInfo, void*, getMethodCallLinkInfoReturnLocation>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), returnAddress.value()));
+        }
+
+        unsigned getBytecodeIndex(CallFrame* callFrame, ReturnAddressPtr returnAddress)
         {
             reparseForExceptionInfoIfNecessary(callFrame);
-            ptrdiff_t nativePCOffset = reinterpret_cast<void**>(nativePC) - reinterpret_cast<void**>(m_jitCode.code);
-            return binaryChop<PC, ptrdiff_t, getNativePCOffset>(m_exceptionInfo->m_pcVector.begin(), m_exceptionInfo->m_pcVector.size(), nativePCOffset)->bytecodeIndex;
+            return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(m_exceptionInfo->m_callReturnIndexVector.begin(), m_exceptionInfo->m_callReturnIndexVector.size(), ownerNode()->generatedJITCode().offsetOf(returnAddress.value()))->bytecodeIndex;
         }
         
         bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex);
@@ -327,9 +320,9 @@ namespace JSC {
 #endif
 
 #if ENABLE(JIT)
-        void setJITCode(JITCodeRef& jitCode);
-        void* jitCode() { return m_jitCode.code; }
-        ExecutablePool* executablePool() { return m_jitCode.executablePool.get(); }
+        JITCode& getJITCode() { return ownerNode()->generatedJITCode(); }
+        void setJITCode(JITCode);
+        ExecutablePool* executablePool() { return ownerNode()->getExecutablePool(); }
 #endif
 
         ScopeNode* ownerNode() const { return m_ownerNode; }
@@ -348,8 +341,8 @@ namespace JSC {
 
         CodeType codeType() const { return m_codeType; }
 
-        SourceProvider* source() const { return m_source.get(); }
-        unsigned sourceOffset() const { return m_sourceOffset; }
+        SourceProvider* source() const { ASSERT(m_codeType != NativeCode); return m_source.get(); }
+        unsigned sourceOffset() const { ASSERT(m_codeType != NativeCode); return m_sourceOffset; }
 
         size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
         void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
@@ -373,6 +366,9 @@ namespace JSC {
         void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); }
         CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
 
+        void addMethodCallLinkInfos(unsigned n) { m_methodCallLinkInfos.grow(n); }
+        MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; }
+
         void addFunctionRegisterInfo(unsigned bytecodeOffset, int functionIndex) { createRareDataIfNecessary(); m_rareData->m_functionRegisterInfos.append(FunctionRegisterInfo(bytecodeOffset, functionIndex)); }
 #endif
 
@@ -393,7 +389,7 @@ namespace JSC {
         LineInfo& lastLineInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_lineInfo.last(); }
 
 #if ENABLE(JIT)
-        Vector<PC>& pcVector() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_pcVector; }
+        Vector<CallReturnOffsetToBytecodeIndex>& callReturnIndexVector() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_callReturnIndexVector; }
 #endif
 
         // Constant Pool
@@ -404,7 +400,9 @@ namespace JSC {
 
         size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
         void addConstantRegister(const Register& r) { return m_constantRegisters.append(r); }
-        Register& constantRegister(int index) { return m_constantRegisters[index]; }
+        Register& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
+        ALWAYS_INLINE bool isConstantRegisterIndex(int index) { return index >= FirstConstantRegisterIndex; }
+        ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].jsValue(); }
 
         unsigned addFunctionExpression(FuncExprNode* n) { unsigned size = m_functionExpressions.size(); m_functionExpressions.append(n); return size; }
         FuncExprNode* functionExpression(int index) const { return m_functionExpressions[index].get(); }
@@ -414,9 +412,6 @@ namespace JSC {
 
         bool hasFunctions() const { return m_functionExpressions.size() || (m_rareData && m_rareData->m_functions.size()); }
 
-        unsigned addUnexpectedConstant(JSValuePtr v) { createRareDataIfNecessary(); unsigned size = m_rareData->m_unexpectedConstants.size(); m_rareData->m_unexpectedConstants.append(v); return size; }
-        JSValuePtr unexpectedConstant(int index) const { ASSERT(m_rareData); return m_rareData->m_unexpectedConstants[index]; }
-
         unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
         RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
 
@@ -438,18 +433,13 @@ namespace JSC {
 
         SymbolTable& symbolTable() { return m_symbolTable; }
 
-        EvalCodeCache& evalCodeCache() { createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
+        EvalCodeCache& evalCodeCache() { ASSERT(m_codeType != NativeCode); createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
 
         void shrinkToFit();
 
         // FIXME: Make these remaining members private.
 
         int m_numCalleeRegisters;
-        // NOTE: numConstants holds the number of constant registers allocated
-        // by the code generator, not the number of constant registers used.
-        // (Duplicate constants are uniqued during code generation, and spare
-        // constant registers may be allocated.)
-        int m_numConstants;
         int m_numVars;
         int m_numParameters;
 
@@ -462,6 +452,7 @@ namespace JSC {
 
         void createRareDataIfNecessary()
         {
+            ASSERT(m_codeType != NativeCode); 
             if (!m_rareData)
                 m_rareData.set(new RareData);
         }
@@ -473,9 +464,6 @@ namespace JSC {
 #ifndef NDEBUG
         unsigned m_instructionCount;
 #endif
-#if ENABLE(JIT)
-        JITCodeRef m_jitCode;
-#endif
 
         int m_thisRegister;
 
@@ -496,6 +484,7 @@ namespace JSC {
         Vector<StructureStubInfo> m_structureStubInfos;
         Vector<GlobalResolveInfo> m_globalResolveInfos;
         Vector<CallLinkInfo> m_callLinkInfos;
+        Vector<MethodCallLinkInfo> m_methodCallLinkInfos;
         Vector<CallLinkInfo*> m_linkedCallerList;
 #endif
 
@@ -514,7 +503,7 @@ namespace JSC {
             Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo;
 
 #if ENABLE(JIT)
-            Vector<PC> m_pcVector;
+            Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector;
 #endif
         };
         OwnPtr<ExceptionInfo> m_exceptionInfo;
@@ -524,7 +513,6 @@ namespace JSC {
 
             // Rare Constants
             Vector<RefPtr<FuncDeclNode> > m_functions;
-            Vector<JSValuePtr> m_unexpectedConstants;
             Vector<RefPtr<RegExp> > m_regexps;
 
             // Jump Tables
@@ -579,6 +567,14 @@ namespace JSC {
         int m_baseScopeDepth;
     };
 
+    inline Register& ExecState::r(int index)
+    {
+        CodeBlock* codeBlock = this->codeBlock();
+        if (codeBlock->isConstantRegisterIndex(index))
+            return codeBlock->constantRegister(index);
+        return this[index];
+    }
+
 } // namespace JSC
 
 #endif // CodeBlock_h
index 2d6f7dc14636037b9078775f0177de272527448d..f0ce73e9531263f30e1092f505d45e83c029ceaf 100644 (file)
@@ -41,7 +41,7 @@ namespace JSC {
 
     class EvalCodeCache {
     public:
-        PassRefPtr<EvalNode> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValuePtr& exceptionValue)
+        PassRefPtr<EvalNode> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue)
         {
             RefPtr<EvalNode> evalNode;
 
index 1fab106094d75c46304e2274660ce5bce77c57a1..eeeac6f4c3e3712d57f157f4c23aad78be286485 100644 (file)
 #ifndef Instruction_h
 #define Instruction_h
 
+#include "MacroAssembler.h"
 #include "Opcode.h"
 #include "Structure.h"
 #include <wtf/VectorTraits.h>
 
-#define POLYMORPHIC_LIST_CACHE_SIZE 4
+#define POLYMORPHIC_LIST_CACHE_SIZE 8
 
 namespace JSC {
 
+    // *Sigh*, If the JIT is enabled we need to track the stubRountine (of type CodeLocationLabel),
+    // If the JIT is not in use we don't actually need the variable (that said, if the JIT is not in use we don't
+    // curently actually use PolymorphicAccessStructureLists, which we should).  Anyway, this seems like the best
+    // solution for now - will need to something smarter if/when we actually want mixed-mode operation.
+#if ENABLE(JIT)
+    typedef CodeLocationLabel PolymorphicAccessStructureListStubRoutineType;
+#else
+    typedef void* PolymorphicAccessStructureListStubRoutineType;
+#endif
+
     class JSCell;
     class Structure;
     class StructureChain;
@@ -45,14 +56,14 @@ namespace JSC {
     struct PolymorphicAccessStructureList {
         struct PolymorphicStubInfo {
             bool isChain;
-            void* stubRoutine;
+            PolymorphicAccessStructureListStubRoutineType stubRoutine;
             Structure* base;
             union {
                 Structure* proto;
                 StructureChain* chain;
             } u;
 
-            void set(void* _stubRoutine, Structure* _base)
+            void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base)
             {
                 stubRoutine = _stubRoutine;
                 base = _base;
@@ -60,7 +71,7 @@ namespace JSC {
                 isChain = false;
             }
             
-            void set(void* _stubRoutine, Structure* _base, Structure* _proto)
+            void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto)
             {
                 stubRoutine = _stubRoutine;
                 base = _base;
@@ -68,7 +79,7 @@ namespace JSC {
                 isChain = false;
             }
             
-            void set(void* _stubRoutine, Structure* _base, StructureChain* _chain)
+            void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain)
             {
                 stubRoutine = _stubRoutine;
                 base = _base;
@@ -77,17 +88,17 @@ namespace JSC {
             }
         } list[POLYMORPHIC_LIST_CACHE_SIZE];
         
-        PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase)
+        PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase)
         {
             list[0].set(stubRoutine, firstBase);
         }
 
-        PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, Structure* firstProto)
+        PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto)
         {
             list[0].set(stubRoutine, firstBase, firstProto);
         }
 
-        PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, StructureChain* firstChain)
+        PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain)
         {
             list[0].set(stubRoutine, firstBase, firstChain);
         }
index 44e224d566cf36f0cda9b157dfc9093ab14db2a9..b4f8e4401cb14af529e5eedcd87fdd2e060ed69b 100644 (file)
@@ -30,6 +30,7 @@
 #ifndef JumpTable_h
 #define JumpTable_h
 
+#include "MacroAssembler.h"
 #include "UString.h"
 #include <wtf/HashMap.h>
 #include <wtf/Vector.h>
@@ -39,7 +40,7 @@ namespace JSC {
     struct OffsetLocation {
         int32_t branchOffset;
 #if ENABLE(JIT)
-        void* ctiOffset;
+        CodeLocationLabel ctiOffset;
 #endif
     };
 
@@ -47,7 +48,7 @@ namespace JSC {
         typedef HashMap<RefPtr<UString::Rep>, OffsetLocation> StringOffsetTable;
         StringOffsetTable offsetTable;
 #if ENABLE(JIT)
-        void* ctiDefault; // FIXME: it should not be necessary to store this.
+        CodeLocationLabel ctiDefault; // FIXME: it should not be necessary to store this.
 #endif
 
         inline int32_t offsetForValue(UString::Rep* value, int32_t defaultOffset)
@@ -60,7 +61,7 @@ namespace JSC {
         }
 
 #if ENABLE(JIT)
-        inline void* ctiForValue(UString::Rep* value)
+        inline CodeLocationLabel ctiForValue(UString::Rep* value)
         {
             StringOffsetTable::const_iterator end = offsetTable.end();
             StringOffsetTable::const_iterator loc = offsetTable.find(value);
@@ -76,8 +77,8 @@ namespace JSC {
         Vector<int32_t> branchOffsets;
         int32_t min;
 #if ENABLE(JIT)
-        Vector<void*> ctiOffsets;
-        void* ctiDefault;
+        Vector<CodeLocationLabel> ctiOffsets;
+        CodeLocationLabel ctiDefault;
 #endif
 
         int32_t offsetForValue(int32_t value, int32_t defaultOffset);
@@ -88,7 +89,7 @@ namespace JSC {
         }
 
 #if ENABLE(JIT)
-        inline void* ctiForValue(int32_t value)
+        inline CodeLocationLabel ctiForValue(int32_t value)
         {
             if (value >= min && static_cast<uint32_t>(value - min) < ctiOffsets.size())
                 return ctiOffsets[value - min];
index d00178bd048fb1799a9722d2853d66ec1f9bbb47..ec39f11cc25b535d8eb6b77bb7f4c70eb4aa3721 100644 (file)
@@ -40,10 +40,10 @@ namespace JSC {
     #define FOR_EACH_OPCODE_ID(macro) \
         macro(op_enter, 1) \
         macro(op_enter_with_activation, 2) \
+        macro(op_init_arguments, 1) \
         macro(op_create_arguments, 1) \
         macro(op_convert_this, 2) \
         \
-        macro(op_unexpected_load, 3) \
         macro(op_new_object, 2) \
         macro(op_new_array, 4) \
         macro(op_new_regexp, 3) \
@@ -67,7 +67,7 @@ namespace JSC {
         macro(op_negate, 3) \
         macro(op_add, 5) \
         macro(op_mul, 5) \
-        macro(op_div, 4) \
+        macro(op_div, 5) \
         macro(op_mod, 4) \
         macro(op_sub, 5) \
         \
@@ -98,7 +98,6 @@ namespace JSC {
         macro(op_put_global_var, 4) \
         macro(op_resolve_base, 3) \
         macro(op_resolve_with_base, 4) \
-        macro(op_resolve_func, 4) \
         macro(op_get_by_id, 8) \
         macro(op_get_by_id_self, 8) \
         macro(op_get_by_id_self_list, 8) \
@@ -125,7 +124,9 @@ namespace JSC {
         macro(op_jfalse, 3) \
         macro(op_jeq_null, 3) \
         macro(op_jneq_null, 3) \
+        macro(op_jneq_ptr, 4) \
         macro(op_jnless, 4) \
+        macro(op_jnlesseq, 4) \
         macro(op_jmp_scopes, 3) \
         macro(op_loop, 2) \
         macro(op_loop_if_true, 3) \
@@ -139,12 +140,17 @@ namespace JSC {
         macro(op_new_func_exp, 3) \
         macro(op_call, 5) \
         macro(op_call_eval, 5) \
+        macro(op_call_varargs, 5) \
+        macro(op_load_varargs, 3) \
         macro(op_tear_off_activation, 2) \
         macro(op_tear_off_arguments, 1) \
         macro(op_ret, 2) \
+        macro(op_method_check, 1) \
         \
         macro(op_construct, 7) \
         macro(op_construct_verify, 3) \
+        macro(op_strcat, 4) \
+        macro(op_to_primitive, 3) \
         \
         macro(op_get_pnames, 3) \
         macro(op_next_pname, 4) \
@@ -174,7 +180,7 @@ namespace JSC {
 
     #define OPCODE_ID_LENGTHS(id, length) const int id##_length = length;
          FOR_EACH_OPCODE_ID(OPCODE_ID_LENGTHS);
-    #undef OPCODE_ID_SIZES
+    #undef OPCODE_ID_LENGTHS
     
     #define OPCODE_LENGTH(opcode) opcode##_length
 
@@ -187,7 +193,7 @@ namespace JSC {
     #undef VERIFY_OPCODE_ID
 
 #if HAVE(COMPUTED_GOTO)
-    typedef void* Opcode;
+    typedef const void* Opcode;
 #else
     typedef OpcodeID Opcode;
 #endif
index 215ebe5d7951d4f14f930ffd5bb2fe8a8bed8f1e..86517233ae015f014499e4b7b05ce8974c32d664 100644 (file)
 
 namespace JSC {
 
-void ScopeSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC)
+#if ENABLE(SAMPLING_FLAGS)
+
+void SamplingFlags::sample()
 {
-    if (!m_samples) {
-        m_size = codeBlock->instructions().size();
-        m_samples = static_cast<int*>(calloc(m_size, sizeof(int)));
-        m_codeBlock = codeBlock;
+    uint32_t mask = 1 << 31;
+    unsigned index;
+
+    for (index = 0; index < 32; ++index) {
+        if (mask & s_flags)
+            break;
+        mask >>= 1;
     }
 
-    ++m_sampleCount;
+    s_flagCounts[32 - index]++;
+}
 
-    unsigned offest = vPC - codeBlock->instructions().begin();
-    // Since we don't read and write codeBlock and vPC atomically, this check
-    // can fail if we sample mid op_call / op_ret.
-    if (offest < m_size) {
-        m_samples[offest]++;
-        m_opcodeSampleCount++;
-    }
+void SamplingFlags::start()
+{
+    for (unsigned i = 0; i <= 32; ++i)
+        s_flagCounts[i] = 0;
 }
+void SamplingFlags::stop()
+{
+    uint64_t total = 0;
+    for (unsigned i = 0; i <= 32; ++i)
+        total += s_flagCounts[i];
+
+    if (total) {
+        printf("\nSamplingFlags: sample counts with flags set: (%lld total)\n", total);
+        for (unsigned i = 0; i <= 32; ++i) {
+            if (s_flagCounts[i])
+                printf("  [ %02d ] : %lld\t\t(%03.2f%%)\n", i, s_flagCounts[i], (100.0 * s_flagCounts[i]) / total);
+        }
+        printf("\n");
+    } else
+    printf("\nSamplingFlags: no samples.\n\n");
+}
+uint64_t SamplingFlags::s_flagCounts[33];
+
+#else
+void SamplingFlags::start() {}
+void SamplingFlags::stop() {}
+#endif
+
+/*
+  Start with flag 16 set.
+  By doing this the monitoring of lower valued flags will be masked out
+  until flag 16 is explictly cleared.
+*/
+uint32_t SamplingFlags::s_flags = 1 << 15;
+
 
 #if PLATFORM(WIN_OS)
 
@@ -82,62 +115,113 @@ static inline unsigned hertz2us(unsigned hertz)
     return 1000000 / hertz;
 }
 
-void SamplingTool::run()
+
+SamplingTool* SamplingTool::s_samplingTool = 0;
+
+
+bool SamplingThread::s_running = false;
+unsigned SamplingThread::s_hertz = 10000;
+ThreadIdentifier SamplingThread::s_samplingThread;
+
+void* SamplingThread::threadStartFunc(void*)
 {
-    while (m_running) {
-        sleepForMicroseconds(hertz2us(m_hertz));
+    while (s_running) {
+        sleepForMicroseconds(hertz2us(s_hertz));
 
-        Sample sample(m_sample, m_codeBlock);
-        ++m_sampleCount;
+#if ENABLE(SAMPLING_FLAGS)
+        SamplingFlags::sample();
+#endif
+#if ENABLE(OPCODE_SAMPLING)
+        SamplingTool::sample();
+#endif
+    }
 
-        if (sample.isNull())
-            continue;
+    return 0;
+}
 
-        if (!sample.inHostFunction()) {
-            unsigned opcodeID = m_interpreter->getOpcodeID(sample.vPC()[0].u.opcode);
 
-            ++m_opcodeSampleCount;
-            ++m_opcodeSamples[opcodeID];
+void SamplingThread::start(unsigned hertz)
+{
+    ASSERT(!s_running);
+    s_running = true;
+    s_hertz = hertz;
 
-            if (sample.inCTIFunction())
-                m_opcodeSamplesInCTIFunctions[opcodeID]++;
-        }
+    s_samplingThread = createThread(threadStartFunc, 0, "JavaScriptCore::Sampler");
+}
+
+void SamplingThread::stop()
+{
+    ASSERT(s_running);
+    s_running = false;
+    waitForThreadCompletion(s_samplingThread, 0);
+}
+
+
+void ScopeSampleRecord::sample(CodeBlock* codeBlock, Instruction* vPC)
+{
+    if (!m_samples) {
+        m_size = codeBlock->instructions().size();
+        m_samples = static_cast<int*>(calloc(m_size, sizeof(int)));
+        m_codeBlock = codeBlock;
+    }
+
+    ++m_sampleCount;
+
+    unsigned offest = vPC - codeBlock->instructions().begin();
+    // Since we don't read and write codeBlock and vPC atomically, this check
+    // can fail if we sample mid op_call / op_ret.
+    if (offest < m_size) {
+        m_samples[offest]++;
+        m_opcodeSampleCount++;
+    }
+}
+
+void SamplingTool::doRun()
+{
+    Sample sample(m_sample, m_codeBlock);
+    ++m_sampleCount;
+
+    if (sample.isNull())
+        return;
+
+    if (!sample.inHostFunction()) {
+        unsigned opcodeID = m_interpreter->getOpcodeID(sample.vPC()[0].u.opcode);
+
+        ++m_opcodeSampleCount;
+        ++m_opcodeSamples[opcodeID];
+
+        if (sample.inCTIFunction())
+            m_opcodeSamplesInCTIFunctions[opcodeID]++;
+    }
 
 #if ENABLE(CODEBLOCK_SAMPLING)
+    if (CodeBlock* codeBlock = sample.codeBlock()) {
         MutexLocker locker(m_scopeSampleMapMutex);
-        ScopeSampleRecord* record = m_scopeSampleMap->get(sample.codeBlock()->ownerNode());
+        ScopeSampleRecord* record = m_scopeSampleMap->get(codeBlock->ownerNode());
         ASSERT(record);
-        record->sample(sample.codeBlock(), sample.vPC());
-#endif
+        record->sample(codeBlock, sample.vPC());
     }
+#endif
 }
 
-void* SamplingTool::threadStartFunc(void* samplingTool)
+void SamplingTool::sample()
 {
-    reinterpret_cast<SamplingTool*>(samplingTool)->run();
-    return 0;
+    s_samplingTool->doRun();
 }
 
 void SamplingTool::notifyOfScope(ScopeNode* scope)
 {
+#if ENABLE(CODEBLOCK_SAMPLING)
     MutexLocker locker(m_scopeSampleMapMutex);
     m_scopeSampleMap->set(scope, new ScopeSampleRecord(scope));
+#else
+    UNUSED_PARAM(scope);
+#endif
 }
 
-void SamplingTool::start(unsigned hertz)
-{
-    ASSERT(!m_running);
-    m_running = true;
-    m_hertz = hertz;
-
-    m_samplingThread = createThread(threadStartFunc, this, "JavaScriptCore::Sampler");
-}
-
-void SamplingTool::stop()
+void SamplingTool::setup()
 {
-    ASSERT(m_running);
-    m_running = false;
-    waitForThreadCompletion(m_samplingThread, 0);
+    s_samplingTool = this;
 }
 
 #if ENABLE(OPCODE_SAMPLING)
@@ -153,14 +237,6 @@ struct LineCountInfo {
     unsigned count;
 };
 
-static int compareLineCountInfoSampling(const void* left, const void* right)
-{
-    const LineCountInfo* leftLineCount = reinterpret_cast<const LineCountInfo*>(left);
-    const LineCountInfo* rightLineCount = reinterpret_cast<const LineCountInfo*>(right);
-
-    return (leftLineCount->line > rightLineCount->line) ? 1 : (leftLineCount->line < rightLineCount->line) ? -1 : 0;
-}
-
 static int compareOpcodeIndicesSampling(const void* left, const void* right)
 {
     const OpcodeSampleInfo* leftSampleInfo = reinterpret_cast<const OpcodeSampleInfo*>(left);
@@ -169,6 +245,15 @@ static int compareOpcodeIndicesSampling(const void* left, const void* right)
     return (leftSampleInfo->count < rightSampleInfo->count) ? 1 : (leftSampleInfo->count > rightSampleInfo->count) ? -1 : 0;
 }
 
+#if ENABLE(CODEBLOCK_SAMPLING)
+static int compareLineCountInfoSampling(const void* left, const void* right)
+{
+    const LineCountInfo* leftLineCount = reinterpret_cast<const LineCountInfo*>(left);
+    const LineCountInfo* rightLineCount = reinterpret_cast<const LineCountInfo*>(right);
+
+    return (leftLineCount->line > rightLineCount->line) ? 1 : (leftLineCount->line < rightLineCount->line) ? -1 : 0;
+}
+
 static int compareScopeSampleRecords(const void* left, const void* right)
 {
     const ScopeSampleRecord* const leftValue = *static_cast<const ScopeSampleRecord* const *>(left);
@@ -176,6 +261,7 @@ static int compareScopeSampleRecords(const void* left, const void* right)
 
     return (leftValue->m_sampleCount < rightValue->m_sampleCount) ? 1 : (leftValue->m_sampleCount > rightValue->m_sampleCount) ? -1 : 0;
 }
+#endif
 
 void SamplingTool::dump(ExecState* exec)
 {
@@ -227,6 +313,8 @@ void SamplingTool::dump(ExecState* exec)
     printf("\tcti count:\tsamples inside a CTI function called by this opcode\n");
     printf("\tcti %% of self:\tcti count / sample count\n");
     
+#if ENABLE(CODEBLOCK_SAMPLING)
+
     // (3) Build and sort 'codeBlockSamples' array.
 
     int scopeCount = m_scopeSampleMap->size();
@@ -285,6 +373,9 @@ void SamplingTool::dump(ExecState* exec)
             }
         }
     }
+#else
+    UNUSED_PARAM(exec);
+#endif
 }
 
 #else
@@ -295,4 +386,21 @@ void SamplingTool::dump(ExecState*)
 
 #endif
 
+void AbstractSamplingCounter::dump()
+{
+#if ENABLE(SAMPLING_COUNTERS)
+    if (s_abstractSamplingCounterChain != &s_abstractSamplingCounterChainEnd) {
+        printf("\nSampling Counter Values:\n");
+        for (AbstractSamplingCounter* currCounter = s_abstractSamplingCounterChain; (currCounter != &s_abstractSamplingCounterChainEnd); currCounter = currCounter->m_next)
+            printf("\t%s\t: %lld\n", currCounter->m_name, currCounter->m_counter);
+        printf("\n\n");
+    }
+    s_completed = true;
+#endif
+}
+
+AbstractSamplingCounter AbstractSamplingCounter::s_abstractSamplingCounterChainEnd;
+AbstractSamplingCounter* AbstractSamplingCounter::s_abstractSamplingCounterChain = &s_abstractSamplingCounterChainEnd;
+bool AbstractSamplingCounter::s_completed = false;
+
 } // namespace JSC
index d1cf2e88901b32874f6767e1eb426db1fea51840..7d7dc9c9593321c60689bed39418e4299bfa340c 100644 (file)
 
 namespace JSC {
 
+    class SamplingFlags {
+        friend class JIT;
+    public:
+        static void start();
+        static void stop();
+
+#if ENABLE(SAMPLING_FLAGS)
+        static void setFlag(unsigned flag)
+        {
+            ASSERT(flag >= 1);
+            ASSERT(flag <= 32);
+            s_flags |= 1u << (flag - 1);
+        }
+
+        static void clearFlag(unsigned flag)
+        {
+            ASSERT(flag >= 1);
+            ASSERT(flag <= 32);
+            s_flags &= ~(1u << (flag - 1));
+        }
+
+        static void sample();
+
+        class ScopedFlag {
+        public:
+            ScopedFlag(int flag)
+                : m_flag(flag)
+            {
+                setFlag(flag);
+            }
+
+            ~ScopedFlag()
+            {
+                clearFlag(m_flag);
+            }
+
+        private:
+            int m_flag;
+        };
+    
+#endif
+    private:
+        static uint32_t s_flags;
+#if ENABLE(SAMPLING_FLAGS)
+        static uint64_t s_flagCounts[33];
+#endif
+    };
+
     class CodeBlock;
     class ExecState;
     class Interpreter;
@@ -73,6 +121,19 @@ namespace JSC {
 
     typedef WTF::HashMap<ScopeNode*, ScopeSampleRecord*> ScopeSampleRecordMap;
 
+    class SamplingThread {
+    public:
+        // Sampling thread state.
+        static bool s_running;
+        static unsigned s_hertz;
+        static ThreadIdentifier s_samplingThread;
+
+        static void start(unsigned hertz=10000);
+        static void stop();
+
+        static void* threadStartFunc(void*);
+    };
+
     class SamplingTool {
     public:
         friend class CallRecord;
@@ -127,12 +188,13 @@ namespace JSC {
 
         SamplingTool(Interpreter* interpreter)
             : m_interpreter(interpreter)
-            , m_running(false)
             , m_codeBlock(0)
             , m_sample(0)
             , m_sampleCount(0)
             , m_opcodeSampleCount(0)
+#if ENABLE(CODEBLOCK_SAMPLING)
             , m_scopeSampleMap(new ScopeSampleRecordMap())
+#endif
         {
             memset(m_opcodeSamples, 0, sizeof(m_opcodeSamples));
             memset(m_opcodeSamplesInCTIFunctions, 0, sizeof(m_opcodeSamplesInCTIFunctions));
@@ -140,11 +202,12 @@ namespace JSC {
 
         ~SamplingTool()
         {
+#if ENABLE(CODEBLOCK_SAMPLING)
             deleteAllValues(*m_scopeSampleMap);
+#endif
         }
 
-        void start(unsigned hertz=10000);
-        void stop();
+        void setup();
         void dump(ExecState*);
 
         void notifyOfScope(ScopeNode* scope);
@@ -165,6 +228,8 @@ namespace JSC {
             return reinterpret_cast<void*>(reinterpret_cast<intptr_t>(vPC) | (static_cast<intptr_t>(inCTIFunction) << 1) | static_cast<intptr_t>(inHostFunction));
         }
 
+        static void sample();
+
     private:
         class Sample {
         public:
@@ -174,7 +239,7 @@ namespace JSC {
             {
             }
             
-            bool isNull() { return !m_sample || !m_codeBlock; }
+            bool isNull() { return !m_sample; }
             CodeBlock* codeBlock() { return m_codeBlock; }
             Instruction* vPC() { return reinterpret_cast<Instruction*>(m_sample & ~0x3); }
             bool inHostFunction() { return m_sample & 0x1; }
@@ -184,17 +249,12 @@ namespace JSC {
             intptr_t m_sample;
             CodeBlock* m_codeBlock;
         };
-        
-        static void* threadStartFunc(void*);
-        void run();
+
+        void doRun();
+        static SamplingTool* s_samplingTool;
         
         Interpreter* m_interpreter;
         
-        // Sampling thread state.
-        bool m_running;
-        unsigned m_hertz;
-        ThreadIdentifier m_samplingThread;
-
         // State tracked by the main thread, used by the sampling thread.
         CodeBlock* m_codeBlock;
         intptr_t m_sample;
@@ -205,9 +265,147 @@ namespace JSC {
         unsigned m_opcodeSamples[numOpcodeIDs];
         unsigned m_opcodeSamplesInCTIFunctions[numOpcodeIDs];
         
+#if ENABLE(CODEBLOCK_SAMPLING)
         Mutex m_scopeSampleMapMutex;
         OwnPtr<ScopeSampleRecordMap> m_scopeSampleMap;
+#endif
+    };
+
+    // AbstractSamplingCounter:
+    //
+    // Implements a named set of counters, printed on exit if ENABLE(SAMPLING_COUNTERS).
+    // See subclasses below, SamplingCounter, GlobalSamplingCounter and DeletableSamplingCounter.
+    class AbstractSamplingCounter {
+        friend class JIT;
+        friend class DeletableSamplingCounter;
+    public:
+        void count(uint32_t count = 1)
+        {
+            m_counter += count;
+        }
+
+        static void dump();
+
+    protected:
+        // Effectively the contructor, however called lazily in the case of GlobalSamplingCounter.
+        void init(const char* name)
+        {
+            m_counter = 0;
+            m_name = name;
+
+            // Set m_next to point to the head of the chain, and inform whatever is
+            // currently at the head that this node will now hold the pointer to it.
+            m_next = s_abstractSamplingCounterChain;
+            s_abstractSamplingCounterChain->m_referer = &m_next;
+            // Add this node to the head of the list.
+            s_abstractSamplingCounterChain = this;
+            m_referer = &s_abstractSamplingCounterChain;
+        }
+
+        int64_t m_counter;
+        const char* m_name;
+        AbstractSamplingCounter* m_next;
+        // This is a pointer to the pointer to this node in the chain; used to
+        // allow fast linked list deletion.
+        AbstractSamplingCounter** m_referer;
+        // Null object used to detect end of static chain.
+        static AbstractSamplingCounter s_abstractSamplingCounterChainEnd;
+        static AbstractSamplingCounter* s_abstractSamplingCounterChain;
+        static bool s_completed;
+    };
+
+#if ENABLE(SAMPLING_COUNTERS)
+    // SamplingCounter:
+    //
+    // This class is suitable and (hopefully!) convenient for cases where a counter is
+    // required within the scope of a single function.  It can be instantiated as a
+    // static variable since it contains a constructor but not a destructor (static
+    // variables in WebKit cannot have destructors).
+    //
+    // For example:
+    //
+    // void someFunction()
+    // {
+    //     static SamplingCounter countMe("This is my counter.  There are many like it, but this one is mine.");
+    //     countMe.count();
+    //     // ...
+    // }
+    //
+    class SamplingCounter : public AbstractSamplingCounter {
+    public:
+        SamplingCounter(const char* name) { init(name); }
+    };
+
+    // GlobalSamplingCounter:
+    //
+    // This class is suitable for use where a counter is to be declared globally,
+    // since it contains neither a constructor nor destructor.  Instead, ensure
+    // that 'name()' is called to provide the counter with a name (and also to
+    // allow it to be printed out on exit).
+    //
+    // GlobalSamplingCounter globalCounter;
+    //
+    // void firstFunction()
+    // {
+    //     // Put this within a function that is definitely called!
+    //     // (Or alternatively alongside all calls to 'count()').
+    //     globalCounter.name("I Name You Destroyer.");
+    //     globalCounter.count();
+    //     // ...
+    // }
+    //
+    // void secondFunction()
+    // {
+    //     globalCounter.count();
+    //     // ...
+    // }
+    //
+    class GlobalSamplingCounter : public AbstractSamplingCounter {
+    public:
+        void name(const char* name)
+        {
+            // Global objects should be mapped in zero filled memory, so this should
+            // be a safe (albeit not necessarily threadsafe) check for 'first call'.
+            if (!m_next)
+                init(name);
+        }
+    };
+
+    // DeletableSamplingCounter:
+    //
+    // The above classes (SamplingCounter, GlobalSamplingCounter), are intended for
+    // use within a global or static scope, and as such cannot have a destructor.
+    // This means there is no convenient way for them to remove themselves from the
+    // static list of counters, and should an instance of either class be freed
+    // before 'dump()' has walked over the list it will potentially walk over an
+    // invalid pointer.
+    //
+    // This class is intended for use where the counter may possibly be deleted before
+    // the program exits.  Should this occur, the counter will print it's value to
+    // stderr, and remove itself from the static list.  Example:
+    //
+    // DeletableSamplingCounter* counter = new DeletableSamplingCounter("The Counter With No Name");
+    // counter->count();
+    // delete counter;
+    //
+    class DeletableSamplingCounter : public AbstractSamplingCounter {
+    public:
+        DeletableSamplingCounter(const char* name) { init(name); }
+
+        ~DeletableSamplingCounter()
+        {
+            if (!s_completed)
+                fprintf(stderr, "DeletableSamplingCounter \"%s\" deleted early (with count %lld)\n", m_name, m_counter);
+            // Our m_referer pointer should know where the pointer to this node is,
+            // and m_next should know that this node is the previous node in the list.
+            ASSERT(*m_referer == this);
+            ASSERT(m_next->m_referer == &m_next);
+            // Remove this node from the list, and inform m_next that we have done so.
+            m_next->m_referer = m_referer;
+            *m_referer = m_next;
+        }
     };
+#endif
 
 } // namespace JSC
 
index a9e0678daa9ee0922430ab5966d3ca2621e28cbc..95dd2664ab3cfd4761aa734ef6d3d7896433e077 100644 (file)
 #ifndef StructureStubInfo_h
 #define StructureStubInfo_h
 
+#if ENABLE(JIT)
+
 #include "Instruction.h"
+#include "MacroAssembler.h"
 #include "Opcode.h"
 #include "Structure.h"
 
 namespace JSC {
 
-#if ENABLE(JIT)
     struct StructureStubInfo {
         StructureStubInfo(OpcodeID opcodeID)
             : opcodeID(opcodeID)
-            , stubRoutine(0)
-            , callReturnLocation(0)
-            , hotPathBegin(0)
         {
         }
 
@@ -145,12 +144,13 @@ namespace JSC {
             } putByIdReplace;
         } u;
 
-        void* stubRoutine;
-        void* callReturnLocation;
-        void* hotPathBegin;
+        CodeLocationLabel stubRoutine;
+        CodeLocationCall callReturnLocation;
+        CodeLocationLabel hotPathBegin;
     };
-#endif
 
 } // namespace JSC
 
+#endif
+
 #endif // StructureStubInfo_h
index cd89c1e7f7d892524a14fb109edb3123c9ab9794..683372effc104d2a6f30bac720f91bcaa384a817 100644 (file)
@@ -31,6 +31,7 @@
 #include "BytecodeGenerator.h"
 
 #include "BatchedTransitionOptimizer.h"
+#include "PrototypeFunction.h"
 #include "JSFunction.h"
 #include "Interpreter.h"
 #include "UString.h"
@@ -195,17 +196,10 @@ bool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, R
     return result.second;
 }
 
-void BytecodeGenerator::allocateConstants(size_t count)
+void BytecodeGenerator::preserveLastVar()
 {
-    m_codeBlock->m_numConstants = count;
-    if (!count)
-        return;
-    
-    m_nextConstantIndex = m_calleeRegisters.size();
-
-    for (size_t i = 0; i < count; ++i)
-        newRegister();
-    m_lastConstant = &m_calleeRegisters.last();
+    if ((m_firstConstantIndex = m_calleeRegisters.size()) != 0)
+        m_lastVar = &m_calleeRegisters.last();
 }
 
 BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock)
@@ -221,6 +215,8 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d
     , m_baseScopeDepth(0)
     , m_codeType(GlobalCode)
     , m_nextGlobalIndex(-1)
+    , m_nextConstantOffset(0)
+    , m_globalConstantIndex(0)
     , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
     , m_lastOpcodeID(op_end)
     , m_emitNodeDepth(0)
@@ -260,7 +256,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d
         m_nextGlobalIndex -= symbolTable->size();
 
         for (size_t i = 0; i < functionStack.size(); ++i) {
-            FuncDeclNode* funcDecl = functionStack[i].get();
+            FuncDeclNode* funcDecl = functionStack[i];
             globalObject->removeDirect(funcDecl->m_ident); // Make sure our new function is not shadowed by an old property.
             emitNewFunction(addGlobalVar(funcDecl->m_ident, false), funcDecl);
         }
@@ -270,13 +266,13 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d
             if (!globalObject->hasProperty(exec, varStack[i].first))
                 newVars.append(addGlobalVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant));
 
-        allocateConstants(programNode->neededConstants());
+        preserveLastVar();
 
         for (size_t i = 0; i < newVars.size(); ++i)
             emitLoad(newVars[i], jsUndefined());
     } else {
         for (size_t i = 0; i < functionStack.size(); ++i) {
-            FuncDeclNode* funcDecl = functionStack[i].get();
+            FuncDeclNode* funcDecl = functionStack[i];
             globalObject->putWithAttributes(exec, funcDecl->m_ident, funcDecl->makeFunction(exec, scopeChain.node()), DontDelete);
         }
         for (size_t i = 0; i < varStack.size(); ++i) {
@@ -288,7 +284,7 @@ BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* d
             globalObject->putWithAttributes(exec, varStack[i].first, jsUndefined(), attributes);
         }
 
-        allocateConstants(programNode->neededConstants());
+        preserveLastVar();
     }
 }
 
@@ -303,6 +299,8 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
     , m_dynamicScopeDepth(0)
     , m_baseScopeDepth(0)
     , m_codeType(FunctionCode)
+    , m_nextConstantOffset(0)
+    , m_globalConstantIndex(0)
     , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
     , m_lastOpcodeID(op_end)
     , m_emitNodeDepth(0)
@@ -329,12 +327,19 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
     } else
         emitOpcode(op_enter);
 
-    if (usesArguments)
-        emitOpcode(op_create_arguments);
+    if (usesArguments) {
+        emitOpcode(op_init_arguments);
+
+        // The debugger currently retrieves the arguments object from an activation rather than pulling
+        // it from a call frame.  In the long-term it should stop doing that (<rdar://problem/6911886>),
+        // but for now we force eager creation of the arguments object when debugging.
+        if (m_shouldEmitDebugHooks)
+            emitOpcode(op_create_arguments);
+    }
 
     const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
     for (size_t i = 0; i < functionStack.size(); ++i) {
-        FuncDeclNode* funcDecl = functionStack[i].get();
+        FuncDeclNode* funcDecl = functionStack[i];
         const Identifier& ident = funcDecl->m_ident;
         m_functions.add(ident.ustring().rep());
         emitNewFunction(addVar(ident, false), funcDecl);
@@ -362,7 +367,7 @@ BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debug
     for (size_t i = 0; i < parameterCount; ++i)
         addParameter(parameters[i]);
 
-    allocateConstants(functionBody->neededConstants());
+    preserveLastVar();
 }
 
 BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock)
@@ -377,6 +382,8 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge
     , m_dynamicScopeDepth(0)
     , m_baseScopeDepth(codeBlock->baseScopeDepth())
     , m_codeType(EvalCode)
+    , m_nextConstantOffset(0)
+    , m_globalConstantIndex(0)
     , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
     , m_lastOpcodeID(op_end)
     , m_emitNodeDepth(0)
@@ -390,7 +397,7 @@ BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugge
     codeBlock->setGlobalData(m_globalData);
     m_codeBlock->m_numParameters = 1; // Allocate space for "this"
 
-    allocateConstants(evalNode->neededConstants());
+    preserveLastVar();
 }
 
 RegisterID* BytecodeGenerator::addParameter(const Identifier& ident)
@@ -424,6 +431,36 @@ RegisterID* BytecodeGenerator::registerFor(const Identifier& ident)
     if (entry.isNull())
         return 0;
 
+    if (ident == propertyNames().arguments)
+        createArgumentsIfNecessary();
+
+    return &registerFor(entry.getIndex());
+}
+
+bool BytecodeGenerator::willResolveToArguments(const Identifier& ident)
+{
+    if (ident != propertyNames().arguments)
+        return false;
+    
+    if (!shouldOptimizeLocals())
+        return false;
+    
+    SymbolTableEntry entry = symbolTable().get(ident.ustring().rep());
+    if (entry.isNull())
+        return false;
+    
+    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
+        return true;
+    
+    return false;
+}
+
+RegisterID* BytecodeGenerator::uncheckedRegisterForArguments()
+{
+    ASSERT(willResolveToArguments(propertyNames().arguments));
+
+    SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.ustring().rep());
+    ASSERT(!entry.isNull());
     return &registerFor(entry.getIndex());
 }
 
@@ -648,6 +685,21 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta
             instructions().append(target->offsetFrom(instructions().size()));
             return target;
         }
+    } else if (m_lastOpcodeID == op_lesseq) {
+        int dstIndex;
+        int src1Index;
+        int src2Index;
+
+        retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
+
+        if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
+            rewindBinaryOp();
+            emitOpcode(op_jnlesseq);
+            instructions().append(src1Index);
+            instructions().append(src2Index);
+            instructions().append(target->offsetFrom(instructions().size()));
+            return target;
+        }
     } else if (m_lastOpcodeID == op_not) {
         int dstIndex;
         int srcIndex;
@@ -695,6 +747,24 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* ta
     return target;
 }
 
+PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target)
+{
+    emitOpcode(op_jneq_ptr);
+    instructions().append(cond->index());
+    instructions().append(m_scopeChain->globalObject()->d()->callFunction);
+    instructions().append(target->offsetFrom(instructions().size()));
+    return target;
+}
+
+PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
+{
+    emitOpcode(op_jneq_ptr);
+    instructions().append(cond->index());
+    instructions().append(m_scopeChain->globalObject()->d()->applyFunction);
+    instructions().append(target->offsetFrom(instructions().size()));
+    return target;
+}
+
 unsigned BytecodeGenerator::addConstant(FuncDeclNode* n)
 {
     // No need to explicitly unique function body nodes -- they're unique already.
@@ -717,24 +787,19 @@ unsigned BytecodeGenerator::addConstant(const Identifier& ident)
     return result.first->second;
 }
 
-RegisterID* BytecodeGenerator::addConstant(JSValuePtr v)
+RegisterID* BytecodeGenerator::addConstantValue(JSValue v)
 {
-    pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValuePtr::encode(v), m_nextConstantIndex);
-    if (result.second) {
-        RegisterID& constant = m_calleeRegisters[m_nextConstantIndex];
-        
-        ++m_nextConstantIndex;
+    int index = m_nextConstantOffset;
 
-        m_codeBlock->addConstantRegister(JSValuePtr(v));
-        return &constant;
-    }
-
-    return &registerFor(result.first->second);
-}
+    pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantOffset);
+    if (result.second) {
+        m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
+        ++m_nextConstantOffset;
+        m_codeBlock->addConstantRegister(JSValue(v));
+    } else
+        index = result.first->second;
 
-unsigned BytecodeGenerator::addUnexpectedConstant(JSValuePtr v)
-{
-    return m_codeBlock->addUnexpectedConstant(v);
+    return &m_constantPoolRegisters[index];
 }
 
 unsigned BytecodeGenerator::addRegExp(RegExp* r)
@@ -796,9 +861,8 @@ RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst,
     instructions().append(src2->index());
 
     if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
-        opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub) {
+        opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
         instructions().append(types.toInt());
-    }
 
     return dst;
 }
@@ -814,8 +878,8 @@ RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst
         if (src1->index() == dstIndex
             && src1->isTemporary()
             && m_codeBlock->isConstantRegisterIndex(src2->index())
-            && m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec()).isString()) {
-            const UString& value = asString(m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec()))->value();
+            && m_codeBlock->constantRegister(src2->index()).jsValue().isString()) {
+            const UString& value = asString(m_codeBlock->constantRegister(src2->index()).jsValue())->value();
             if (value == "undefined") {
                 rewindUnaryOp();
                 emitOpcode(op_is_undefined);
@@ -879,7 +943,7 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
     // Later we can do the extra work to handle that like the other cases.
     if (number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
         return emitLoad(dst, jsNumber(globalData(), number));
-    JSValuePtr& valueInMap = m_numberMap.add(number, noValue()).first->second;
+    JSValue& valueInMap = m_numberMap.add(number, JSValue()).first->second;
     if (!valueInMap)
         valueInMap = jsNumber(globalData(), number);
     return emitLoad(dst, valueInMap);
@@ -890,33 +954,17 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& ident
     JSString*& stringInMap = m_stringMap.add(identifier.ustring().rep(), 0).first->second;
     if (!stringInMap)
         stringInMap = jsOwnedString(globalData(), identifier.ustring());
-    return emitLoad(dst, JSValuePtr(stringInMap));
+    return emitLoad(dst, JSValue(stringInMap));
 }
 
-RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValuePtr v)
+RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
 {
-    RegisterID* constantID = addConstant(v);
+    RegisterID* constantID = addConstantValue(v);
     if (dst)
         return emitMove(dst, constantID);
     return constantID;
 }
 
-RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, bool b)
-{
-    emitOpcode(op_unexpected_load);
-    instructions().append(dst->index());
-    instructions().append(addUnexpectedConstant(jsBoolean(b)));
-    return dst;
-}
-
-RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d)
-{
-    emitOpcode(op_unexpected_load);
-    instructions().append(dst->index());
-    instructions().append(addUnexpectedConstant(jsNumber(globalData(), d)));
-    return dst;
-}
-
 bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject)
 {
     // Cases where we cannot statically optimize the lookup.
@@ -1037,7 +1085,7 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& pr
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValuePtr globalObject)
+RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue globalObject)
 {
     if (globalObject) {
         emitOpcode(op_get_global_var);
@@ -1054,7 +1102,7 @@ RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, i
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValuePtr globalObject)
+RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue globalObject)
 {
     if (globalObject) {
         emitOpcode(op_put_global_var);
@@ -1072,28 +1120,71 @@ RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, Registe
 
 RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property)
 {
-    emitOpcode(op_resolve_base);
-    instructions().append(dst->index());
-    instructions().append(addConstant(property));
-    return dst;
+    size_t depth = 0;
+    int index = 0;
+    JSObject* globalObject = 0;
+    findScopedProperty(property, index, depth, false, globalObject);
+    if (!globalObject) {
+        // We can't optimise at all :-(
+        emitOpcode(op_resolve_base);
+        instructions().append(dst->index());
+        instructions().append(addConstant(property));
+        return dst;
+    }
+
+    // Global object is the base
+    return emitLoad(dst, JSValue(globalObject));
 }
 
 RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
 {
-    emitOpcode(op_resolve_with_base);
-    instructions().append(baseDst->index());
+    size_t depth = 0;
+    int index = 0;
+    JSObject* globalObject = 0;
+    if (!findScopedProperty(property, index, depth, false, globalObject) || !globalObject) {
+        // We can't optimise at all :-(
+        emitOpcode(op_resolve_with_base);
+        instructions().append(baseDst->index());
+        instructions().append(propDst->index());
+        instructions().append(addConstant(property));
+        return baseDst;
+    }
+
+    bool forceGlobalResolve = false;
+    if (m_regeneratingForExceptionInfo) {
+#if ENABLE(JIT)
+        forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInfoAtBytecodeOffset(instructions().size());
+#else
+        forceGlobalResolve = m_codeBlockBeingRegeneratedFrom->hasGlobalResolveInstructionAtBytecodeOffset(instructions().size());
+#endif
+    }
+
+    // Global object is the base
+    emitLoad(baseDst, JSValue(globalObject));
+
+    if (index != missingSymbolMarker() && !forceGlobalResolve) {
+        // Directly index the property lookup across multiple scopes.
+        emitGetScopedVar(propDst, depth, index, globalObject);
+        return baseDst;
+    }
+
+#if ENABLE(JIT)
+    m_codeBlock->addGlobalResolveInfo(instructions().size());
+#else
+    m_codeBlock->addGlobalResolveInstruction(instructions().size());
+#endif
+    emitOpcode(op_resolve_global);
     instructions().append(propDst->index());
+    instructions().append(globalObject);
     instructions().append(addConstant(property));
+    instructions().append(0);
+    instructions().append(0);
     return baseDst;
 }
 
-RegisterID* BytecodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property)
+void BytecodeGenerator::emitMethodCheck()
 {
-    emitOpcode(op_resolve_func);
-    instructions().append(baseDst->index());
-    instructions().append(funcDst->index());
-    instructions().append(addConstant(property));
-    return baseDst;
+    emitOpcode(op_method_check);
 }
 
 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
@@ -1252,8 +1343,15 @@ RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, Regis
     return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
 }
 
+void BytecodeGenerator::createArgumentsIfNecessary()
+{
+    if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
+        emitOpcode(op_create_arguments);
+}
+
 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
 {
+    createArgumentsIfNecessary();
     return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
 }
 
@@ -1280,7 +1378,7 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi
     // Generate code for arguments.
     Vector<RefPtr<RegisterID>, 16> argv;
     argv.append(thisRegister);
-    for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) {
+    for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next) {
         argv.append(newTemporary());
         // op_call requires the arguments to be a sequential range of registers
         ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
@@ -1327,6 +1425,44 @@ RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Regi
     return dst;
 }
 
+RegisterID* BytecodeGenerator::emitLoadVarargs(RegisterID* argCountDst, RegisterID* arguments)
+{
+    ASSERT(argCountDst->index() < arguments->index());
+    emitOpcode(op_load_varargs);
+    instructions().append(argCountDst->index());
+    instructions().append(arguments->index());
+    return argCountDst;
+}
+
+RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCountRegister, unsigned divot, unsigned startOffset, unsigned endOffset)
+{
+    ASSERT(func->refCount());
+    ASSERT(thisRegister->refCount());
+    ASSERT(dst != func);
+    if (m_shouldEmitProfileHooks) {
+        emitOpcode(op_profile_will_call);
+        instructions().append(func->index());
+        
+#if ENABLE(JIT)
+        m_codeBlock->addFunctionRegisterInfo(instructions().size(), func->index());
+#endif
+    }
+    
+    emitExpressionInfo(divot, startOffset, endOffset);
+    
+    // Emit call.
+    emitOpcode(op_call_varargs);
+    instructions().append(dst->index()); // dst
+    instructions().append(func->index()); // func
+    instructions().append(argCountRegister->index()); // arg count
+    instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset
+    if (m_shouldEmitProfileHooks) {
+        emitOpcode(op_profile_did_call);
+        instructions().append(func->index());
+    }
+    return dst;
+}
+
 RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
 {
     if (m_codeBlock->needsFullScopeChain()) {
@@ -1365,7 +1501,7 @@ RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func,
     // Generate code for arguments.
     Vector<RefPtr<RegisterID>, 16> argv;
     argv.append(newTemporary()); // reserve space for "this"
-    for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode.get() : 0; n; n = n->m_next.get()) {
+    for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode : 0; n; n = n->m_next) {
         argv.append(newTemporary());
         // op_construct requires the arguments to be a sequential range of registers
         ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
@@ -1416,6 +1552,23 @@ RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func,
     return dst;
 }
 
+RegisterID* BytecodeGenerator::emitStrcat(RegisterID* dst, RegisterID* src, int count)
+{
+    emitOpcode(op_strcat);
+    instructions().append(dst->index());
+    instructions().append(src->index());
+    instructions().append(count);
+
+    return dst;
+}
+
+void BytecodeGenerator::emitToPrimitive(RegisterID* dst, RegisterID* src)
+{
+    emitOpcode(op_to_primitive);
+    instructions().append(dst->index());
+    instructions().append(src->index());
+}
+
 RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
 {
     ASSERT(scope->isTemporary());
@@ -1423,6 +1576,7 @@ RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
     context.isFinallyBlock = false;
     m_scopeContextStack.append(context);
     m_dynamicScopeDepth++;
+    createArgumentsIfNecessary();
 
     return emitUnaryNoDstOp(op_push_scope, scope);
 }
@@ -1470,8 +1624,17 @@ void BytecodeGenerator::popFinallyContext()
 LabelScope* BytecodeGenerator::breakTarget(const Identifier& name)
 {
     // Reclaim free label scopes.
-    while (m_labelScopes.size() && !m_labelScopes.last().refCount())
+    //
+    // The condition was previously coded as 'm_labelScopes.size() && !m_labelScopes.last().refCount()',
+    // however sometimes this appears to lead to GCC going a little haywire and entering the loop with
+    // size 0, leading to segfaulty badness.  We are yet to identify a valid cause within our code to
+    // cause the GCC codegen to misbehave in this fashion, and as such the following refactoring of the
+    // loop condition is a workaround.
+    while (m_labelScopes.size()) {
+        if  (m_labelScopes.last().refCount())
+            break;
         m_labelScopes.removeLast();
+    }
 
     if (!m_labelScopes.size())
         return 0;
@@ -1568,14 +1731,10 @@ PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, Contro
             emitLabel(nextInsn.get());
         }
 
-        // To get here there must be at least one finally block present
-        do {
-            ASSERT(topScope->isFinallyBlock);
+        while (topScope > bottomScope && topScope->isFinallyBlock) {
             emitJumpSubroutine(topScope->finallyContext.retAddrDst, topScope->finallyContext.finallyAddr);
             --topScope;
-            if (!topScope->isFinallyBlock)
-                break;
-        } while (topScope > bottomScope);
+        }
     }
     return emitJump(target);
 }
@@ -1611,7 +1770,7 @@ RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID*
 RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
 {
 #if ENABLE(JIT)
-    HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, 0 };
+    HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
 #else
     HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
 #endif
@@ -1622,12 +1781,12 @@ RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* star
     return targetRegister;
 }
 
-RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSValuePtr message)
+RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSValue message)
 {
     emitOpcode(op_new_error);
     instructions().append(dst->index());
     instructions().append(static_cast<int>(type));
-    instructions().append(addUnexpectedConstant(message));
+    instructions().append(addConstantValue(message)->index());
     return dst;
 }
 
@@ -1636,6 +1795,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst,
     emitOpcode(op_jsr);
     instructions().append(retAddrDst->index());
     instructions().append(finally->offsetFrom(instructions().size()));
+    emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it.
     return finally;
 }
 
@@ -1652,6 +1812,8 @@ void BytecodeGenerator::emitPushNewScope(RegisterID* dst, Identifier& property,
     m_scopeContextStack.append(context);
     m_dynamicScopeDepth++;
     
+    createArgumentsIfNecessary();
+
     emitOpcode(op_push_new_scope);
     instructions().append(dst->index());
     instructions().append(addConstant(property));
@@ -1687,7 +1849,6 @@ static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t
     ASSERT(node->isNumber());
     double value = static_cast<NumberNode*>(node)->value();
     int32_t key = static_cast<int32_t>(value);
-    ASSERT(JSValuePtr::makeInt32Fast(key) && (JSValuePtr::makeInt32Fast(key).getInt32Fast() == value));
     ASSERT(key == value);
     ASSERT(key >= min);
     ASSERT(key <= max);
@@ -1744,9 +1905,6 @@ static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t
         UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep();
         OffsetLocation location;
         location.branchOffset = labels[i]->offsetFrom(switchAddress);
-#if ENABLE(JIT)
-        location.ctiOffset = 0;
-#endif
         jumpTable.offsetTable.add(clause, location);
     }
 }
index 194aabd6d4f94e3566eb472d0402f61416c8f141..c273597eac58a0438c1cc0aeaaa5bd6bea7b6d72 100644 (file)
 #include "LabelScope.h"
 #include "Interpreter.h"
 #include "RegisterID.h"
-#include "SegmentedVector.h"
 #include "SymbolTable.h"
 #include "Debugger.h"
 #include "Nodes.h"
+#include <wtf/FastAllocBase.h>
 #include <wtf/PassRefPtr.h>
+#include <wtf/SegmentedVector.h>
 #include <wtf/Vector.h>
 
 namespace JSC {
@@ -60,7 +61,7 @@ namespace JSC {
         FinallyContext finallyContext;
     };
 
-    class BytecodeGenerator {
+    class BytecodeGenerator : public WTF::FastAllocBase {
     public:
         typedef DeclarationStacks::VarStack VarStack;
         typedef DeclarationStacks::FunctionStack FunctionStack;
@@ -81,6 +82,9 @@ namespace JSC {
         // such register exists. Registers returned by registerFor do not
         // require explicit reference counting.
         RegisterID* registerFor(const Identifier&);
+        
+        bool willResolveToArguments(const Identifier&);
+        RegisterID* uncheckedRegisterForArguments();
 
         // Behaves as registerFor does, but ignores dynamic scope as
         // dynamic scope should not interfere with const initialisation
@@ -240,9 +244,7 @@ namespace JSC {
         RegisterID* emitLoad(RegisterID* dst, bool);
         RegisterID* emitLoad(RegisterID* dst, double);
         RegisterID* emitLoad(RegisterID* dst, const Identifier&);
-        RegisterID* emitLoad(RegisterID* dst, JSValuePtr);
-        RegisterID* emitUnexpectedLoad(RegisterID* dst, bool);
-        RegisterID* emitUnexpectedLoad(RegisterID* dst, double);
+        RegisterID* emitLoad(RegisterID* dst, JSValue);
 
         RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
         RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes);
@@ -269,12 +271,13 @@ namespace JSC {
         RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
 
         RegisterID* emitResolve(RegisterID* dst, const Identifier& property);
-        RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index, JSValuePtr globalObject);
-        RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValuePtr globalObject);
+        RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index, JSValue globalObject);
+        RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValue globalObject);
 
         RegisterID* emitResolveBase(RegisterID* dst, const Identifier& property);
         RegisterID* emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property);
-        RegisterID* emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property);
+
+        void emitMethodCheck();
 
         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
         RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
@@ -288,16 +291,22 @@ namespace JSC {
 
         RegisterID* emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
         RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCount, unsigned divot, unsigned startOffset, unsigned endOffset);
+        RegisterID* emitLoadVarargs(RegisterID* argCountDst, RegisterID* args);
 
         RegisterID* emitReturn(RegisterID* src);
         RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
 
         RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        RegisterID* emitStrcat(RegisterID* dst, RegisterID* src, int count);
+        void emitToPrimitive(RegisterID* dst, RegisterID* src);
 
         PassRefPtr<Label> emitLabel(Label*);
         PassRefPtr<Label> emitJump(Label* target);
         PassRefPtr<Label> emitJumpIfTrue(RegisterID* cond, Label* target);
         PassRefPtr<Label> emitJumpIfFalse(RegisterID* cond, Label* target);
+        PassRefPtr<Label> emitJumpIfNotFunctionCall(RegisterID* cond, Label* target);
+        PassRefPtr<Label> emitJumpIfNotFunctionApply(RegisterID* cond, Label* target);
         PassRefPtr<Label> emitJumpScopes(Label* target, int targetScopeDepth);
 
         PassRefPtr<Label> emitJumpSubroutine(RegisterID* retAddrDst, Label*);
@@ -308,7 +317,7 @@ namespace JSC {
 
         RegisterID* emitCatch(RegisterID*, Label* start, Label* end);
         void emitThrow(RegisterID* exc) { emitUnaryNoDstOp(op_throw, exc); }
-        RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValuePtr message);
+        RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValue message);
         void emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value);
 
         RegisterID* emitPushScope(RegisterID* scope);
@@ -345,12 +354,7 @@ namespace JSC {
 
         PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
 
-        struct JSValueHashTraits : HashTraits<JSValueEncodedAsPointer*> {
-            static void constructDeletedValue(JSValueEncodedAsPointer*& slot) { slot = JSValuePtr::encode(jsImpossibleValue()); }
-            static bool isDeletedValue(JSValueEncodedAsPointer* value) { return value == JSValuePtr::encode(jsImpossibleValue()); }
-        };
-
-        typedef HashMap<JSValueEncodedAsPointer*, unsigned, PtrHash<JSValueEncodedAsPointer*>, JSValueHashTraits> JSValueMap;
+        typedef HashMap<EncodedJSValue, unsigned, EncodedJSValueHash, EncodedJSValueHashTraits> JSValueMap;
 
         struct IdentifierMapIndexHashTraits {
             typedef int TraitType;
@@ -362,9 +366,9 @@ namespace JSC {
         };
 
         typedef HashMap<RefPtr<UString::Rep>, int, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, IdentifierMapIndexHashTraits> IdentifierMap;
-        typedef HashMap<double, JSValuePtr> NumberMap;
+        typedef HashMap<double, JSValue> NumberMap;
         typedef HashMap<UString::Rep*, JSString*, IdentifierRepHash> IdentifierStringMap;
-
+        
         RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
         
         RegisterID* newRegister();
@@ -391,7 +395,7 @@ namespace JSC {
 
         RegisterID* addParameter(const Identifier&);
         
-        void allocateConstants(size_t);
+        void preserveLastVar();
 
         RegisterID& registerFor(int index)
         {
@@ -412,8 +416,7 @@ namespace JSC {
         unsigned addConstant(FuncDeclNode*);
         unsigned addConstant(FuncExprNode*);
         unsigned addConstant(const Identifier&);
-        RegisterID* addConstant(JSValuePtr);
-        unsigned addUnexpectedConstant(JSValuePtr);
+        RegisterID* addConstantValue(JSValue);
         unsigned addRegExp(RegExp*);
 
         Vector<Instruction>& instructions() { return m_codeBlock->instructions(); }
@@ -424,6 +427,8 @@ namespace JSC {
 
         RegisterID* emitThrowExpressionTooDeepException();
 
+        void createArgumentsIfNecessary();
+
         bool m_shouldEmitDebugHooks;
         bool m_shouldEmitProfileHooks;
 
@@ -433,17 +438,20 @@ namespace JSC {
         ScopeNode* m_scopeNode;
         CodeBlock* m_codeBlock;
 
+        // Some of these objects keep pointers to one another. They are arranged
+        // to ensure a sane destruction order that avoids references to freed memory.
         HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions;
         RegisterID m_ignoredResultRegister;
         RegisterID m_thisRegister;
         RegisterID m_argumentsRegister;
         int m_activationRegisterIndex;
-        SegmentedVector<RegisterID, 512> m_calleeRegisters;
-        SegmentedVector<RegisterID, 512> m_parameters;
-        SegmentedVector<RegisterID, 512> m_globals;
-        SegmentedVector<LabelScope, 256> m_labelScopes;
-        SegmentedVector<Label, 256> m_labels;
-        RefPtr<RegisterID> m_lastConstant;
+        WTF::SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
+        WTF::SegmentedVector<RegisterID, 32> m_calleeRegisters;
+        WTF::SegmentedVector<RegisterID, 32> m_parameters;
+        WTF::SegmentedVector<RegisterID, 32> m_globals;
+        WTF::SegmentedVector<Label, 32> m_labels;
+        WTF::SegmentedVector<LabelScope, 8> m_labelScopes;
+        RefPtr<RegisterID> m_lastVar;
         int m_finallyDepth;
         int m_dynamicScopeDepth;
         int m_baseScopeDepth;
@@ -454,7 +462,9 @@ namespace JSC {
 
         int m_nextGlobalIndex;
         int m_nextParameterIndex;
-        int m_nextConstantIndex;
+        int m_firstConstantIndex;
+        int m_nextConstantOffset;
+        unsigned m_globalConstantIndex;
 
         int m_globalVarStorageOffset;
 
@@ -473,7 +483,7 @@ namespace JSC {
         bool m_regeneratingForExceptionInfo;
         CodeBlock* m_codeBlockBeingRegeneratedFrom;
 
-        static const unsigned s_maxEmitNodeDepth = 10000;
+        static const unsigned s_maxEmitNodeDepth = 5000;
     };
 
 }
diff --git a/bytecompiler/SegmentedVector.h b/bytecompiler/SegmentedVector.h
deleted file mode 100644 (file)
index bbab04f..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SegmentedVector_h
-#define SegmentedVector_h
-
-#include <wtf/Vector.h>
-
-namespace JSC {
-
-    // SegmentedVector is just like Vector, but it doesn't move the values
-    // stored in its buffer when it grows. Therefore, it is safe to keep
-    // pointers into a SegmentedVector.
-    template <typename T, size_t SegmentSize> class SegmentedVector {
-    public:
-        SegmentedVector()
-            : m_size(0)
-        {
-            m_segments.append(&m_inlineSegment);
-        }
-
-        ~SegmentedVector()
-        {
-            deleteAllSegments();
-        }
-
-        size_t size() const { return m_size; }
-
-        T& at(size_t index)
-        {
-            if (index < SegmentSize)
-                return m_inlineSegment[index];
-            return segmentFor(index)->at(subscriptFor(index));
-        }
-
-        T& operator[](size_t index)
-        {
-            return at(index);
-        }
-
-        T& last()
-        {
-            return at(size() - 1);
-        }
-
-        template <typename U> void append(const U& value)
-        {
-            ++m_size;
-
-            if (m_size <= SegmentSize) {
-                m_inlineSegment.uncheckedAppend(value);
-                return;
-            }
-
-            if (!segmentExistsFor(m_size - 1))
-                m_segments.append(new Segment);
-            segmentFor(m_size - 1)->uncheckedAppend(value);
-        }
-
-        void removeLast()
-        {
-            if (m_size <= SegmentSize)
-                m_inlineSegment.removeLast();
-            else
-                segmentFor(m_size - 1)->removeLast();
-            --m_size;
-        }
-
-        void grow(size_t size)
-        {
-            ASSERT(size > m_size);
-            ensureSegmentsFor(size);
-            m_size = size;
-        }
-
-        void clear()
-        {
-            deleteAllSegments();
-            m_segments.resize(1);
-            m_inlineSegment.clear();
-            m_size = 0;
-        }
-
-    private:
-        typedef Vector<T, SegmentSize> Segment;
-        
-        void deleteAllSegments()
-        {
-            // Skip the first segment, because it's our inline segment, which was
-            // not created by new.
-            for (size_t i = 1; i < m_segments.size(); i++)
-                delete m_segments[i];
-        }
-        
-        bool segmentExistsFor(size_t index)
-        {
-            return index / SegmentSize < m_segments.size();
-        }
-        
-        Segment* segmentFor(size_t index)
-        {
-            return m_segments[index / SegmentSize];
-        }
-        
-        size_t subscriptFor(size_t index)
-        {
-            return index % SegmentSize;
-        }
-        
-        void ensureSegmentsFor(size_t size)
-        {
-            size_t segmentCount = m_size / SegmentSize;
-            if (m_size % SegmentSize)
-                ++segmentCount;
-            segmentCount = std::max<size_t>(segmentCount, 1); // We always have at least our inline segment.
-
-            size_t neededSegmentCount = size / SegmentSize;
-            if (size % SegmentSize)
-                ++neededSegmentCount;
-
-            // Fill up to N - 1 segments.
-            size_t end = neededSegmentCount - 1;
-            for (size_t i = segmentCount - 1; i < end; ++i)
-                ensureSegment(i, SegmentSize);
-            
-            // Grow segment N to accomodate the remainder.
-            ensureSegment(end, subscriptFor(size - 1) + 1);
-        }
-
-        void ensureSegment(size_t segmentIndex, size_t size)
-        {
-            ASSERT(segmentIndex <= m_segments.size());
-            if (segmentIndex == m_segments.size())
-                m_segments.append(new Segment);
-            m_segments[segmentIndex]->grow(size);
-        }
-
-        size_t m_size;
-        Segment m_inlineSegment;
-        Vector<Segment*, 32> m_segments;
-    };
-
-} // namespace JSC
-
-#endif // SegmentedVector_h
index a85178cb3b5b339126bea0027fe0315cafda83fd..66817612f6071240dd5d432e4aa98146f8ec807f 100644 (file)
--- a/config.h
+++ b/config.h
 
 #include <wtf/Platform.h>
 
+#if PLATFORM(WIN_OS) && !defined(BUILDING_WX__) && !COMPILER(GCC)
+#if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
+#define JS_EXPORTDATA __declspec(dllexport)
+#else
+#define JS_EXPORTDATA __declspec(dllimport)
+#endif
+#else
+#define JS_EXPORTDATA
+#endif
+
 #if PLATFORM(WIN_OS)
 
 // If we don't define these, they get defined in windef.h. 
@@ -32,7 +42,7 @@
 #define max max
 #define min min
 
-#if !COMPILER(MSVC7) && !PLATFORM(WIN_CE)
+#if !COMPILER(MSVC7) && !PLATFORM(WINCE)
 // We need to define this before the first #include of stdlib.h or it won't contain rand_s.
 #ifndef _CRT_RAND_S
 #define _CRT_RAND_S
index 3bd9f76e86d5ac2e379b0c16d034a4d231fcea17..4184500ed4ccb6044f4a2ea8bde6ca79be4b7b63 100755 (executable)
@@ -268,11 +268,7 @@ sub output() {
     }
     print "   { 0, 0, 0, 0 }\n";
     print "};\n\n";
-    print "extern const struct HashTable $name =\n";
-    print "#if ENABLE(PERFECT_HASH_SIZE)\n";
-    print "    \{ ", $pefectHashSize - 1, ", $nameEntries, 0 \};\n";
-    print "#else\n";
+    print "extern JSC_CONST_HASHTABLE HashTable $name =\n";
     print "    \{ $compactSize, $compactHashSizeMask, $nameEntries, 0 \};\n";
-    print "#endif\n\n";
     print "} // namespace\n";
 }
index da1cb3dd5231999b1245fdb5ef76b8e5782c6b7a..7d791e7c8155a962644ed0fbc2c82933005cfca1 100644 (file)
@@ -53,7 +53,7 @@ void Debugger::detach(JSGlobalObject* globalObject)
     globalObject->setDebugger(0);
 }
 
-JSValuePtr evaluateInGlobalCallFrame(const UString& script, JSValuePtr& exception, JSGlobalObject* globalObject)
+JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
 {
     CallFrame* globalCallFrame = globalObject->globalExec();
 
index 055989881d90a6f00424e1cde49e0b87831f5648..98d09358cd62159fd371f70af6898e6f4553dab2 100644 (file)
@@ -38,7 +38,7 @@ namespace JSC {
         virtual ~Debugger();
 
         void attach(JSGlobalObject*);
-        void detach(JSGlobalObject*);
+        virtual void detach(JSGlobalObject*);
 
         virtual void sourceParsed(ExecState*, const SourceCode&, int errorLine, const UString& errorMsg) = 0;
         virtual void exception(const DebuggerCallFrame&, intptr_t sourceID, int lineno) = 0;
@@ -56,7 +56,7 @@ namespace JSC {
 
     // This method exists only for backwards compatibility with existing
     // WebScriptDebugger clients
-    JSValuePtr evaluateInGlobalCallFrame(const UString&, JSValuePtr& exception, JSGlobalObject*);
+    JSValue evaluateInGlobalCallFrame(const UString&, JSValue& exception, JSGlobalObject*);
 
 } // namespace JSC
 
index 9d4dcbf9ff187cedee5736534b1ed7b18c9aa7f1..4b2568f026c254966a3f2cabbbd30e38cfa58214 100644 (file)
@@ -55,12 +55,12 @@ bool DebuggerActivation::getOwnPropertySlot(ExecState* exec, const Identifier& p
     return m_activation->getOwnPropertySlot(exec, propertyName, slot);
 }
 
-void DebuggerActivation::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void DebuggerActivation::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     m_activation->put(exec, propertyName, value, slot);
 }
 
-void DebuggerActivation::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+void DebuggerActivation::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
 {
     m_activation->putWithAttributes(exec, propertyName, value, attributes);
 }
@@ -90,12 +90,12 @@ void DebuggerActivation::defineSetter(ExecState* exec, const Identifier& propert
     m_activation->defineSetter(exec, propertyName, setterFunction);
 }
 
-JSValuePtr DebuggerActivation::lookupGetter(ExecState* exec, const Identifier& propertyName)
+JSValue DebuggerActivation::lookupGetter(ExecState* exec, const Identifier& propertyName)
 {
     return m_activation->lookupGetter(exec, propertyName);
 }
 
-JSValuePtr DebuggerActivation::lookupSetter(ExecState* exec, const Identifier& propertyName)
+JSValue DebuggerActivation::lookupSetter(ExecState* exec, const Identifier& propertyName)
 {
     return m_activation->lookupSetter(exec, propertyName);
 }
index c2ede4fa44b778529a66d75e3e91ccbd8b157854..9e1f9f52dd379b7cede9a27f800ec93b52f5c89e 100644 (file)
@@ -39,17 +39,17 @@ namespace JSC {
         virtual void mark();
         virtual UString className() const;
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
-        virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
-        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr, unsigned attributes);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue, unsigned attributes);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
         virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
         virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction);
         virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction);
-        virtual JSValuePtr lookupGetter(ExecState*, const Identifier& propertyName);
-        virtual JSValuePtr lookupSetter(ExecState*, const Identifier& propertyName);
+        virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName);
+        virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName);
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype) 
+        static PassRefPtr<Structure> createStructure(JSValue prototype) 
         {
             return Structure::create(prototype, TypeInfo(ObjectType)); 
         }
index 27b824cd3f14e604e64c234d2ebd13a89148218a..cd8702bc44bed163b0ed404b3bea909d5abe7947 100644 (file)
@@ -46,6 +46,17 @@ const UString* DebuggerCallFrame::functionName() const
         return 0;
     return &function->name(&m_callFrame->globalData());
 }
+    
+UString DebuggerCallFrame::calculatedFunctionName() const
+{
+    if (!m_callFrame->codeBlock())
+        return 0;
+    
+    JSFunction* function = static_cast<JSFunction*>(m_callFrame->callee());
+    if (!function)
+        return 0;
+    return function->calculatedDisplayName(&m_callFrame->globalData());
+}
 
 DebuggerCallFrame::Type DebuggerCallFrame::type() const
 {
@@ -63,10 +74,10 @@ JSObject* DebuggerCallFrame::thisObject() const
     return asObject(m_callFrame->thisValue());
 }
 
-JSValuePtr DebuggerCallFrame::evaluate(const UString& script, JSValuePtr& exception) const
+JSValue DebuggerCallFrame::evaluate(const UString& script, JSValue& exception) const
 {
     if (!m_callFrame->codeBlock())
-        return noValue();
+        return JSValue();
 
     int errLine;
     UString errMsg;
index cdf49651dfaa3a8fdbb393f504721dc8a7878952..9d377ef97a0a2db3aaac32285ea6cf011d7e16b8 100644 (file)
@@ -39,11 +39,10 @@ namespace JSC {
 
         DebuggerCallFrame(CallFrame* callFrame)
             : m_callFrame(callFrame)
-            , m_exception(noValue())
         {
         }
 
-        DebuggerCallFrame(CallFrame* callFrame, JSValuePtr exception)
+        DebuggerCallFrame(CallFrame* callFrame, JSValue exception)
             : m_callFrame(callFrame)
             , m_exception(exception)
         {
@@ -52,14 +51,15 @@ namespace JSC {
         JSGlobalObject* dynamicGlobalObject() const { return m_callFrame->dynamicGlobalObject(); }
         const ScopeChainNode* scopeChain() const { return m_callFrame->scopeChain(); }
         const UString* functionName() const;
+        UString calculatedFunctionName() const;
         Type type() const;
         JSObject* thisObject() const;
-        JSValuePtr evaluate(const UString&, JSValuePtr& exception) const;
-        JSValuePtr exception() const { return m_exception; }
+        JSValue evaluate(const UString&, JSValue& exception) const;
+        JSValue exception() const { return m_exception; }
 
     private:
         CallFrame* m_callFrame;
-        JSValuePtr m_exception;
+        JSValue m_exception;
     };
 
 } // namespace JSC
diff --git a/interpreter/CachedCall.h b/interpreter/CachedCall.h
new file mode 100644 (file)
index 0000000..f48f4f4
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CachedCall_h
+#define CachedCall_h
+
+#include "CallFrameClosure.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
+#include "Interpreter.h"
+
+namespace JSC {
+    class CachedCall : Noncopyable {
+    public:
+        CachedCall(CallFrame* callFrame, JSFunction* function, int argCount, JSValue* exception)
+            : m_valid(false)
+            , m_interpreter(callFrame->interpreter())
+            , m_exception(exception)
+            , m_globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : function->scope().node()->globalObject())
+        {
+            m_closure = m_interpreter->prepareForRepeatCall(function->body(), callFrame, function, argCount, function->scope().node(), exception);
+            m_valid = !*exception;
+        }
+        
+        JSValue call()
+        { 
+            ASSERT(m_valid);
+            return m_interpreter->execute(m_closure, m_exception);
+        }
+        void setThis(JSValue v) { m_closure.setArgument(0, v); }
+        void setArgument(int n, JSValue v) { m_closure.setArgument(n + 1, v); }
+        CallFrame* newCallFrame() { return m_closure.newCallFrame; }
+        ~CachedCall()
+        {
+            if (m_valid)
+                m_interpreter->endRepeatCall(m_closure);
+        }
+        
+    private:
+        bool m_valid;
+        Interpreter* m_interpreter;
+        JSValue* m_exception;
+        DynamicGlobalObjectScope m_globalObjectScope;
+        CallFrameClosure m_closure;
+    };
+}
+
+#endif
index 1c74280f82dcb6ed50adf2b1415c4d42dbdb40bb..972487565f5aacacb25898c190e49a88fc32cedc 100644 (file)
 #include "CallFrame.h"
 
 #include "CodeBlock.h"
+#include "Interpreter.h"
 
 namespace JSC {
 
-JSValuePtr CallFrame::thisValue()
+JSValue CallFrame::thisValue()
 {
-    return this[codeBlock()->thisRegister()].jsValue(this);
+    return this[codeBlock()->thisRegister()].jsValue();
 }
 
+#ifndef NDEBUG
+void CallFrame::dumpCaller()
+{
+    int signedLineNumber;
+    intptr_t sourceID;
+    UString urlString;
+    JSValue function;
+    
+    interpreter()->retrieveLastCaller(this, signedLineNumber, sourceID, urlString, function);
+    printf("Callpoint => %s:%d\n", urlString.ascii(), signedLineNumber);
+}
+#endif
+
 }
index d6b9b7967bd3f402b6d257b88635c0b43ca1812d..8126d74aa341814fa57ef621ade07d34a92659c9 100644 (file)
@@ -40,8 +40,9 @@ namespace JSC  {
         JSFunction* callee() const { return this[RegisterFile::Callee].function(); }
         CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); }
         ScopeChainNode* scopeChain() const { return this[RegisterFile::ScopeChain].Register::scopeChain(); }
+        int argumentCount() const { return this[RegisterFile::ArgumentCount].i(); }
 
-        JSValuePtr thisValue();
+        JSValue thisValue();
 
         // Global object in which execution began.
         JSGlobalObject* dynamicGlobalObject();
@@ -73,48 +74,40 @@ namespace JSC  {
         // pointer, so these are inefficient, and should be used sparingly in new code.
         // But they're used in many places in legacy code, so they're not going away any time soon.
 
-        void setException(JSValuePtr exception) { globalData().exception = exception; }
-        void clearException() { globalData().exception = noValue(); }
-        JSValuePtr exception() const { return globalData().exception; }
-        JSValuePtr* exceptionSlot() { return &globalData().exception; }
+        void setException(JSValue exception) { globalData().exception = exception; }
+        void clearException() { globalData().exception = JSValue(); }
+        JSValue exception() const { return globalData().exception; }
+        JSValue* exceptionSlot() { return &globalData().exception; }
         bool hadException() const { return globalData().exception; }
 
         const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
-        const ArgList& emptyList() const { return *globalData().emptyList; }
+        const MarkedArgumentBuffer& emptyList() const { return *globalData().emptyList; }
         Interpreter* interpreter() { return globalData().interpreter; }
         Heap* heap() { return &globalData().heap; }
-
+#ifndef NDEBUG
+        void dumpCaller();
+#endif
         static const HashTable* arrayTable(CallFrame* callFrame) { return callFrame->globalData().arrayTable; }
         static const HashTable* dateTable(CallFrame* callFrame) { return callFrame->globalData().dateTable; }
+        static const HashTable* jsonTable(CallFrame* callFrame) { return callFrame->globalData().jsonTable; }
         static const HashTable* mathTable(CallFrame* callFrame) { return callFrame->globalData().mathTable; }
         static const HashTable* numberTable(CallFrame* callFrame) { return callFrame->globalData().numberTable; }
         static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->globalData().regExpTable; }
         static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->globalData().regExpConstructorTable; }
         static const HashTable* stringTable(CallFrame* callFrame) { return callFrame->globalData().stringTable; }
 
-    private:
-        friend class Arguments;
-        friend class JSActivation;
-        friend class JSGlobalObject;
-        friend class Interpreter;
-
         static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
         Register* registers() { return this; }
 
         CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
 
-        int argumentCount() const { return this[RegisterFile::ArgumentCount].i(); }
         CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); }
         Arguments* optionalCalleeArguments() const { return this[RegisterFile::OptionalCalleeArguments].arguments(); }
         Instruction* returnPC() const { return this[RegisterFile::ReturnPC].vPC(); }
-        int returnValueRegister() const { return this[RegisterFile::ReturnValueRegister].i(); }
 
-        void setArgumentCount(int count) { this[RegisterFile::ArgumentCount] = count; }
-        void setCallee(JSFunction* callee) { this[RegisterFile::Callee] = callee; }
-        void setCalleeArguments(Arguments* arguments) { this[RegisterFile::OptionalCalleeArguments] = arguments; }
-        void setCallerFrame(CallFrame* callerFrame) { this[RegisterFile::CallerFrame] = callerFrame; }
-        void setCodeBlock(CodeBlock* codeBlock) { this[RegisterFile::CodeBlock] = codeBlock; }
-        void setScopeChain(ScopeChainNode* scopeChain) { this[RegisterFile::ScopeChain] = scopeChain; }
+        void setCalleeArguments(JSValue arguments) { static_cast<Register*>(this)[RegisterFile::OptionalCalleeArguments] = arguments; }
+        void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
+        void setScopeChain(ScopeChainNode* scopeChain) { static_cast<Register*>(this)[RegisterFile::ScopeChain] = scopeChain; }
 
         ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain,
             CallFrame* callerFrame, int returnValueRegister, int argc, JSFunction* function)
@@ -124,20 +117,30 @@ namespace JSC  {
             setCodeBlock(codeBlock);
             setScopeChain(scopeChain);
             setCallerFrame(callerFrame);
-            this[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*.
-            this[RegisterFile::ReturnValueRegister] = returnValueRegister;
+            static_cast<Register*>(this)[RegisterFile::ReturnPC] = vPC; // This is either an Instruction* or a pointer into JIT generated code stored as an Instruction*.
+            static_cast<Register*>(this)[RegisterFile::ReturnValueRegister] = Register::withInt(returnValueRegister);
             setArgumentCount(argc); // original argument count (for the sake of the "arguments" object)
             setCallee(function);
-            setCalleeArguments(0);
+            setCalleeArguments(JSValue());
         }
 
-        static const intptr_t HostCallFrameFlag = 1;
+        // Read a register from the codeframe (or constant from the CodeBlock).
+        inline Register& r(int);
 
         static CallFrame* noCaller() { return reinterpret_cast<CallFrame*>(HostCallFrameFlag); }
+        int returnValueRegister() const { return this[RegisterFile::ReturnValueRegister].i(); }
+
         bool hasHostCallFrameFlag() const { return reinterpret_cast<intptr_t>(this) & HostCallFrameFlag; }
         CallFrame* addHostCallFrameFlag() const { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) | HostCallFrameFlag); }
         CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); }
 
+    private:
+        void setArgumentCount(int count) { static_cast<Register*>(this)[RegisterFile::ArgumentCount] = Register::withInt(count); }
+        void setCallee(JSFunction* callee) { static_cast<Register*>(this)[RegisterFile::Callee] = callee; }
+        void setCodeBlock(CodeBlock* codeBlock) { static_cast<Register*>(this)[RegisterFile::CodeBlock] = codeBlock; }
+
+        static const intptr_t HostCallFrameFlag = 1;
+
         ExecState();
         ~ExecState();
     };
diff --git a/interpreter/CallFrameClosure.h b/interpreter/CallFrameClosure.h
new file mode 100644 (file)
index 0000000..9085327
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef CallFrameClosure_h
+#define CallFrameClosure_h
+
+namespace JSC {
+
+struct CallFrameClosure {
+    CallFrame* oldCallFrame;
+    CallFrame* newCallFrame;
+    JSFunction* function;
+    FunctionBodyNode* functionBody;
+    JSGlobalData* globalData;
+    Register* oldEnd;
+    ScopeChainNode* scopeChain;
+    int expectedParams;
+    int providedParams;
+    
+    void setArgument(int arg, JSValue value)
+    {
+        if (arg < expectedParams)
+            newCallFrame[arg - RegisterFile::CallFrameHeaderSize - expectedParams] = value;
+        else
+            newCallFrame[arg - RegisterFile::CallFrameHeaderSize - expectedParams - providedParams] = value;
+    }
+    void resetCallFrame()
+    {
+        newCallFrame->setScopeChain(scopeChain);
+        newCallFrame->setCalleeArguments(JSValue());
+        for (int i = providedParams; i < expectedParams; ++i)
+            newCallFrame[i - RegisterFile::CallFrameHeaderSize - expectedParams] = jsUndefined();
+    }
+};
+
+}
+
+#endif
index a45773c5d496d8aa2a74f6fe9b34f0e54dba62f5..a9e00995a81ce2441351d95cb6af845277cfca50 100644 (file)
 
 #include "Arguments.h"
 #include "BatchedTransitionOptimizer.h"
+#include "CallFrame.h"
+#include "CallFrameClosure.h"
 #include "CodeBlock.h"
+#include "Collector.h"
+#include "Debugger.h"
 #include "DebuggerCallFrame.h"
 #include "EvalCodeCache.h"
 #include "ExceptionHelpers.h"
-#include "CallFrame.h"
 #include "GlobalEvalFunction.h"
 #include "JSActivation.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "JSNotAnObject.h"
 #include "JSPropertyNameIterator.h"
+#include "LiteralParser.h"
 #include "JSStaticScopeObject.h"
 #include "JSString.h"
 #include "ObjectPrototype.h"
+#include "Operations.h"
 #include "Parser.h"
 #include "Profiler.h"
 #include "RegExpObject.h"
 #include "RegExpPrototype.h"
 #include "Register.h"
-#include "Collector.h"
-#include "Debugger.h"
-#include "Operations.h"
 #include "SamplingTool.h"
 #include <stdio.h>
+#include <wtf/Threading.h>
 
 #if ENABLE(JIT)
 #include "JIT.h"
 #endif
 
-#if ENABLE(ASSEMBLER)
-#include "AssemblerBuffer.h"
-#endif
-
-#if PLATFORM(DARWIN)
-#include <mach/mach.h>
-#endif
-
-#if HAVE(SYS_TIME_H)
-#include <sys/time.h>
-#endif
-
-#if PLATFORM(WIN_OS)
-#include <windows.h>
-#endif
-
-#if PLATFORM(QT)
-#include <QDateTime>
-#endif
-
 using namespace std;
 
 namespace JSC {
 
-// Preferred number of milliseconds between each timeout check
-static const int preferredScriptCheckTimeInterval = 1000;
-
 static ALWAYS_INLINE unsigned bytecodeOffsetForPC(CallFrame* callFrame, CodeBlock* codeBlock, void* pc)
 {
 #if ENABLE(JIT)
-    return codeBlock->getBytecodeIndex(callFrame, pc);
+    return codeBlock->getBytecodeIndex(callFrame, ReturnAddressPtr(pc));
 #else
     UNUSED_PARAM(callFrame);
     return static_cast<Instruction*>(pc) - codeBlock->instructions().begin();
@@ -107,163 +87,8 @@ static int depth(CodeBlock* codeBlock, ScopeChain& sc)
     return sc.localDepth();
 }
 
-static inline bool jsLess(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
-{
-    if (JSValuePtr::areBothInt32Fast(v1, v2))
-        return v1.getInt32Fast() < v2.getInt32Fast();
-
-    double n1;
-    double n2;
-    if (v1.getNumber(n1) && v2.getNumber(n2))
-        return n1 < n2;
-
-    Interpreter* interpreter = callFrame->interpreter();
-    if (interpreter->isJSString(v1) && interpreter->isJSString(v2))
-        return asString(v1)->value() < asString(v2)->value();
-
-    JSValuePtr p1;
-    JSValuePtr p2;
-    bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
-    bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
-
-    if (wasNotString1 | wasNotString2)
-        return n1 < n2;
-
-    return asString(p1)->value() < asString(p2)->value();
-}
-
-static inline bool jsLessEq(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
-{
-    if (JSValuePtr::areBothInt32Fast(v1, v2))
-        return v1.getInt32Fast() <= v2.getInt32Fast();
-
-    double n1;
-    double n2;
-    if (v1.getNumber(n1) && v2.getNumber(n2))
-        return n1 <= n2;
-
-    Interpreter* interpreter = callFrame->interpreter();
-    if (interpreter->isJSString(v1) && interpreter->isJSString(v2))
-        return !(asString(v2)->value() < asString(v1)->value());
-
-    JSValuePtr p1;
-    JSValuePtr p2;
-    bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
-    bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
-
-    if (wasNotString1 | wasNotString2)
-        return n1 <= n2;
-
-    return !(asString(p2)->value() < asString(p1)->value());
-}
-
-static NEVER_INLINE JSValuePtr jsAddSlowCase(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
-{
-    // exception for the Date exception in defaultValue()
-    JSValuePtr p1 = v1.toPrimitive(callFrame);
-    JSValuePtr p2 = v2.toPrimitive(callFrame);
-
-    if (p1.isString() || p2.isString()) {
-        RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
-        if (!value)
-            return throwOutOfMemoryError(callFrame);
-        return jsString(callFrame, value.release());
-    }
-
-    return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
-}
-
-// Fast-path choices here are based on frequency data from SunSpider:
-//    <times> Add case: <t1> <t2>
-//    ---------------------------
-//    5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
-//    247412  Add case: 5 5
-//    20900   Add case: 5 6
-//    13962   Add case: 5 3
-//    4000    Add case: 3 5
-
-static ALWAYS_INLINE JSValuePtr jsAdd(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
-{
-    double left;
-    double right = 0.0;
-
-    bool rightIsNumber = v2.getNumber(right);
-    if (rightIsNumber && v1.getNumber(left))
-        return jsNumber(callFrame, left + right);
-    
-    bool leftIsString = v1.isString();
-    if (leftIsString && v2.isString()) {
-        RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
-        if (!value)
-            return throwOutOfMemoryError(callFrame);
-        return jsString(callFrame, value.release());
-    }
-
-    if (rightIsNumber & leftIsString) {
-        RefPtr<UString::Rep> value = v2.isInt32Fast() ?
-            concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) :
-            concatenate(asString(v1)->value().rep(), right);
-
-        if (!value)
-            return throwOutOfMemoryError(callFrame);
-        return jsString(callFrame, value.release());
-    }
-
-    // All other cases are pretty uncommon
-    return jsAddSlowCase(callFrame, v1, v2);
-}
-
-static JSValuePtr jsTypeStringForValue(CallFrame* callFrame, JSValuePtr v)
-{
-    if (v.isUndefined())
-        return jsNontrivialString(callFrame, "undefined");
-    if (v.isBoolean())
-        return jsNontrivialString(callFrame, "boolean");
-    if (v.isNumber())
-        return jsNontrivialString(callFrame, "number");
-    if (v.isString())
-        return jsNontrivialString(callFrame, "string");
-    if (v.isObject()) {
-        // Return "undefined" for objects that should be treated
-        // as null when doing comparisons.
-        if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
-            return jsNontrivialString(callFrame, "undefined");
-        CallData callData;
-        if (asObject(v)->getCallData(callData) != CallTypeNone)
-            return jsNontrivialString(callFrame, "function");
-    }
-    return jsNontrivialString(callFrame, "object");
-}
-
-static bool jsIsObjectType(JSValuePtr v)
-{
-    if (!v.isCell())
-        return v.isNull();
-
-    JSType type = asCell(v)->structure()->typeInfo().type();
-    if (type == NumberType || type == StringType)
-        return false;
-    if (type == ObjectType) {
-        if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
-            return false;
-        CallData callData;
-        if (asObject(v)->getCallData(callData) != CallTypeNone)
-            return false;
-    }
-    return true;
-}
-
-static bool jsIsFunctionType(JSValuePtr v)
-{
-    if (v.isObject()) {
-        CallData callData;
-        if (asObject(v)->getCallData(callData) != CallTypeNone)
-            return true;
-    }
-    return false;
-}
-
-NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
+#if USE(INTERPRETER)
+NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
 {
     int dst = (vPC + 1)->u.operand;
     int property = (vPC + 2)->u.operand;
@@ -279,11 +104,11 @@ NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, J
         JSObject* o = *iter;
         PropertySlot slot(o);
         if (o->getPropertySlot(callFrame, ident, slot)) {
-            JSValuePtr result = slot.getValue(callFrame, ident);
+            JSValue result = slot.getValue(callFrame, ident);
             exceptionValue = callFrame->globalData().exception;
             if (exceptionValue)
                 return false;
-            callFrame[dst] = JSValuePtr(result);
+            callFrame->r(dst) = JSValue(result);
             return true;
         }
     } while (++iter != end);
@@ -291,7 +116,7 @@ NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, J
     return false;
 }
 
-NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
+NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
 {
     CodeBlock* codeBlock = callFrame->codeBlock();
 
@@ -312,11 +137,11 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP
         JSObject* o = *iter;
         PropertySlot slot(o);
         if (o->getPropertySlot(callFrame, ident, slot)) {
-            JSValuePtr result = slot.getValue(callFrame, ident);
+            JSValue result = slot.getValue(callFrame, ident);
             exceptionValue = callFrame->globalData().exception;
             if (exceptionValue)
                 return false;
-            callFrame[dst] = JSValuePtr(result);
+            callFrame->r(dst) = JSValue(result);
             return true;
         }
     } while (++iter != end);
@@ -324,7 +149,7 @@ NEVER_INLINE bool Interpreter::resolveSkip(CallFrame* callFrame, Instruction* vP
     return false;
 }
 
-NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
+NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
 {
     int dst = (vPC + 1)->u.operand;
     JSGlobalObject* globalObject = static_cast<JSGlobalObject*>((vPC + 2)->u.jsCell);
@@ -334,7 +159,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
     int offset = (vPC + 5)->u.operand;
 
     if (structure == globalObject->structure()) {
-        callFrame[dst] = JSValuePtr(globalObject->getDirectOffset(offset));
+        callFrame->r(dst) = JSValue(globalObject->getDirectOffset(offset));
         return true;
     }
 
@@ -342,21 +167,21 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
     Identifier& ident = codeBlock->identifier(property);
     PropertySlot slot(globalObject);
     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
-        JSValuePtr result = slot.getValue(callFrame, ident);
-        if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) {
+        JSValue result = slot.getValue(callFrame, ident);
+        if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
             if (vPC[4].u.structure)
                 vPC[4].u.structure->deref();
             globalObject->structure()->ref();
             vPC[4] = globalObject->structure();
             vPC[5] = slot.cachedOffset();
-            callFrame[dst] = JSValuePtr(result);
+            callFrame->r(dst) = JSValue(result);
             return true;
         }
 
         exceptionValue = callFrame->globalData().exception;
         if (exceptionValue)
             return false;
-        callFrame[dst] = JSValuePtr(result);
+        callFrame->r(dst) = JSValue(result);
         return true;
     }
 
@@ -364,37 +189,14 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
     return false;
 }
 
-static ALWAYS_INLINE JSValuePtr inlineResolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
-{
-    ScopeChainIterator iter = scopeChain->begin();
-    ScopeChainIterator next = iter;
-    ++next;
-    ScopeChainIterator end = scopeChain->end();
-    ASSERT(iter != end);
-
-    PropertySlot slot;
-    JSObject* base;
-    while (true) {
-        base = *iter;
-        if (next == end || base->getPropertySlot(callFrame, property, slot))
-            return base;
-
-        iter = next;
-        ++next;
-    }
-
-    ASSERT_NOT_REACHED();
-    return noValue();
-}
-
 NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC)
 {
     int dst = (vPC + 1)->u.operand;
     int property = (vPC + 2)->u.operand;
-    callFrame[dst] = JSValuePtr(inlineResolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain()));
+    callFrame->r(dst) = JSValue(JSC::resolveBase(callFrame, callFrame->codeBlock()->identifier(property), callFrame->scopeChain()));
 }
 
-NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
+NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
 {
     int baseDst = (vPC + 1)->u.operand;
     int propDst = (vPC + 2)->u.operand;
@@ -415,12 +217,12 @@ NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Inst
         base = *iter;
         PropertySlot slot(base);
         if (base->getPropertySlot(callFrame, ident, slot)) {
-            JSValuePtr result = slot.getValue(callFrame, ident);
+            JSValue result = slot.getValue(callFrame, ident);
             exceptionValue = callFrame->globalData().exception;
             if (exceptionValue)
                 return false;
-            callFrame[propDst] = JSValuePtr(result);
-            callFrame[baseDst] = JSValuePtr(base);
+            callFrame->r(propDst) = JSValue(result);
+            callFrame->r(baseDst) = JSValue(base);
             return true;
         }
         ++iter;
@@ -430,7 +232,7 @@ NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Inst
     return false;
 }
 
-NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
+NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
 {
     int baseDst = (vPC + 1)->u.operand;
     int funcDst = (vPC + 2)->u.operand;
@@ -459,13 +261,13 @@ NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruct
             // that in host objects you always get a valid object for this.
             // We also handle wrapper substitution for the global object at the same time.
             JSObject* thisObj = base->toThisObject(callFrame);
-            JSValuePtr result = slot.getValue(callFrame, ident);
+            JSValue result = slot.getValue(callFrame, ident);
             exceptionValue = callFrame->globalData().exception;
             if (exceptionValue)
                 return false;
 
-            callFrame[baseDst] = JSValuePtr(thisObj);
-            callFrame[funcDst] = JSValuePtr(result);
+            callFrame->r(baseDst) = JSValue(thisObj);
+            callFrame->r(funcDst) = JSValue(result);
             return true;
         }
         ++iter;
@@ -475,6 +277,8 @@ NEVER_INLINE bool Interpreter::resolveBaseAndFunc(CallFrame* callFrame, Instruct
     return false;
 }
 
+#endif // USE(INTERPRETER)
+
 ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc)
 {
     Register* r = callFrame->registers();
@@ -512,31 +316,46 @@ ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newC
     return CallFrame::create(r);
 }
 
-static NEVER_INLINE bool isNotObject(CallFrame* callFrame, bool forInstanceOf, CodeBlock* codeBlock, const Instruction* vPC, JSValuePtr value, JSValuePtr& exceptionData)
+#if USE(INTERPRETER)
+static NEVER_INLINE bool isInvalidParamForIn(CallFrame* callFrame, CodeBlock* codeBlock, const Instruction* vPC, JSValue value, JSValue& exceptionData)
 {
     if (value.isObject())
         return false;
-    exceptionData = createInvalidParamError(callFrame, forInstanceOf ? "instanceof" : "in" , value, vPC - codeBlock->instructions().begin(), codeBlock);
+    exceptionData = createInvalidParamError(callFrame, "in" , value, vPC - codeBlock->instructions().begin(), codeBlock);
     return true;
 }
 
-NEVER_INLINE JSValuePtr Interpreter::callEval(CallFrame* callFrame, RegisterFile* registerFile, Register* argv, int argc, int registerOffset, JSValuePtr& exceptionValue)
+static NEVER_INLINE bool isInvalidParamForInstanceOf(CallFrame* callFrame, CodeBlock* codeBlock, const Instruction* vPC, JSValue value, JSValue& exceptionData)
+{
+    if (value.isObject() && asObject(value)->structure()->typeInfo().implementsHasInstance())
+        return false;
+    exceptionData = createInvalidParamError(callFrame, "instanceof" , value, vPC - codeBlock->instructions().begin(), codeBlock);
+    return true;
+}
+#endif
+
+NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* registerFile, Register* argv, int argc, int registerOffset, JSValue& exceptionValue)
 {
     if (argc < 2)
         return jsUndefined();
 
-    JSValuePtr program = argv[1].jsValue(callFrame);
+    JSValue program = argv[1].jsValue();
 
     if (!program.isString())
         return program;
 
     UString programSource = asString(program)->value();
 
+    LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON);
+    if (JSValue parsedObject = preparser.tryLiteralParse())
+        return parsedObject;
+    
+    
     ScopeChainNode* scopeChain = callFrame->scopeChain();
     CodeBlock* codeBlock = callFrame->codeBlock();
     RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache().get(callFrame, programSource, scopeChain, exceptionValue);
 
-    JSValuePtr result = jsUndefined();
+    JSValue result = jsUndefined();
     if (evalNode)
         result = callFrame->globalData().interpreter->execute(evalNode.get(), callFrame, callFrame->thisValue().toThisObject(callFrame), callFrame->registers() - registerFile->start() + registerOffset, scopeChain, &exceptionValue);
 
@@ -545,56 +364,14 @@ NEVER_INLINE JSValuePtr Interpreter::callEval(CallFrame* callFrame, RegisterFile
 
 Interpreter::Interpreter()
     : m_sampler(0)
-#if ENABLE(JIT)
-    , m_ctiArrayLengthTrampoline(0)
-    , m_ctiStringLengthTrampoline(0)
-    , m_ctiVirtualCallPreLink(0)
-    , m_ctiVirtualCallLink(0)
-    , m_ctiVirtualCall(0)
-#endif
     , m_reentryDepth(0)
-    , m_timeoutTime(0)
-    , m_timeAtLastCheckTimeout(0)
-    , m_timeExecuting(0)
-    , m_timeoutCheckCount(0)
-    , m_ticksUntilNextTimeoutCheck(initialTickCountThreshold)
 {
-    initTimeout();
+#if HAVE(COMPUTED_GOTO)
     privateExecute(InitializeAndReturn, 0, 0, 0);
-    
-    // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
-    void* storage = fastMalloc(sizeof(CollectorBlock));
-
-    JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull()));
-    m_jsArrayVptr = jsArray->vptr();
-    jsArray->~JSCell();
-
-    JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
-    m_jsByteArrayVptr = jsByteArray->vptr();
-    jsByteArray->~JSCell();
-
-    JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
-    m_jsStringVptr = jsString->vptr();
-    jsString->~JSCell();
-
-    JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
-    m_jsFunctionVptr = jsFunction->vptr();
-    jsFunction->~JSCell();
-    
-    fastFree(storage);
-}
-
-void Interpreter::initialize(JSGlobalData* globalData)
-{
-#if ENABLE(JIT)
-    JIT::compileCTIMachineTrampolines(globalData);
-#else
-    UNUSED_PARAM(globalData);
-#endif
-}
 
-Interpreter::~Interpreter()
-{
+    for (int i = 0; i < numOpcodeIDs; ++i)
+        m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
+#endif // HAVE(COMPUTED_GOTO)
 }
 
 #ifndef NDEBUG
@@ -608,77 +385,92 @@ void Interpreter::dumpCallFrame(CallFrame* callFrame)
 void Interpreter::dumpRegisters(CallFrame* callFrame)
 {
     printf("Register frame: \n\n");
-    printf("----------------------------------------------------\n");
-    printf("            use            |   address  |   value   \n");
-    printf("----------------------------------------------------\n");
+    printf("-----------------------------------------------------------------------------\n");
+    printf("            use            |   address  |                value               \n");
+    printf("-----------------------------------------------------------------------------\n");
 
     CodeBlock* codeBlock = callFrame->codeBlock();
     RegisterFile* registerFile = &callFrame->scopeChain()->globalObject()->globalData()->interpreter->registerFile();
     const Register* it;
     const Register* end;
+    JSValue v;
 
     if (codeBlock->codeType() == GlobalCode) {
         it = registerFile->lastGlobal();
         end = it + registerFile->numGlobals();
         while (it != end) {
-            printf("[global var]               | %10p | %10p \n", it, (*it).v());
+            v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+            printf("[global var]               | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v));
+#else
+            printf("[global var]               | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v));
+#endif
             ++it;
         }
-        printf("----------------------------------------------------\n");
+        printf("-----------------------------------------------------------------------------\n");
     }
     
     it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->m_numParameters;
-    printf("[this]                     | %10p | %10p \n", it, (*it).v()); ++it;
+    v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+    printf("[this]                     | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v)); ++it;
+#else
+    printf("[this]                     | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v)); ++it;
+#endif
     end = it + max(codeBlock->m_numParameters - 1, 0); // - 1 to skip "this"
     if (it != end) {
         do {
-            printf("[param]                    | %10p | %10p \n", it, (*it).v());
+            v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+            printf("[param]                    | %10p | %-16s 0x%llx \n", it, v.description(), JSValue::encode(v));
+#else
+            printf("[param]                    | %10p | %-16s %p \n", it, v.description(), JSValue::encode(v));
+#endif
             ++it;
         } while (it != end);
     }
-    printf("----------------------------------------------------\n");
-
-    printf("[CodeBlock]                | %10p | %10p \n", it, (*it).v()); ++it;
-    printf("[ScopeChain]               | %10p | %10p \n", it, (*it).v()); ++it;
-    printf("[CallerRegisters]          | %10p | %10p \n", it, (*it).v()); ++it;
-    printf("[ReturnPC]                 | %10p | %10p \n", it, (*it).v()); ++it;
-    printf("[ReturnValueRegister]      | %10p | %10p \n", it, (*it).v()); ++it;
-    printf("[ArgumentCount]            | %10p | %10p \n", it, (*it).v()); ++it;
-    printf("[Callee]                   | %10p | %10p \n", it, (*it).v()); ++it;
-    printf("[OptionalCalleeArguments]  | %10p | %10p \n", it, (*it).v()); ++it;
-    printf("----------------------------------------------------\n");
+    printf("-----------------------------------------------------------------------------\n");
+    printf("[CodeBlock]                | %10p | %p \n", it, (*it).codeBlock()); ++it;
+    printf("[ScopeChain]               | %10p | %p \n", it, (*it).scopeChain()); ++it;
+    printf("[CallerRegisters]          | %10p | %d \n", it, (*it).i()); ++it;
+    printf("[ReturnPC]                 | %10p | %p \n", it, (*it).vPC()); ++it;
+    printf("[ReturnValueRegister]      | %10p | %d \n", it, (*it).i()); ++it;
+    printf("[ArgumentCount]            | %10p | %d \n", it, (*it).i()); ++it;
+    printf("[Callee]                   | %10p | %p \n", it, (*it).function()); ++it;
+    printf("[OptionalCalleeArguments]  | %10p | %p \n", it, (*it).arguments()); ++it;
+    printf("-----------------------------------------------------------------------------\n");
 
     int registerCount = 0;
 
     end = it + codeBlock->m_numVars;
     if (it != end) {
         do {
-            printf("[r%2d]                      | %10p | %10p \n", registerCount, it, (*it).v());
-            ++it;
-            ++registerCount;
-        } while (it != end);
-    }
-    printf("----------------------------------------------------\n");
-
-    end = it + codeBlock->m_numConstants;
-    if (it != end) {
-        do {
-            printf("[r%2d]                      | %10p | %10p \n", registerCount, it, (*it).v());
+            v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+            printf("[r%2d]                      | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
+#else
+            printf("[r%2d]                      | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
+#endif
             ++it;
             ++registerCount;
         } while (it != end);
     }
-    printf("----------------------------------------------------\n");
+    printf("-----------------------------------------------------------------------------\n");
 
-    end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numConstants - codeBlock->m_numVars;
+    end = it + codeBlock->m_numCalleeRegisters - codeBlock->m_numVars;
     if (it != end) {
         do {
-            printf("[r%2d]                      | %10p | %10p \n", registerCount, it, (*it).v());
+            v = (*it).jsValue();
+#if USE(JSVALUE32_64)
+            printf("[r%2d]                      | %10p | %-16s 0x%llx \n", registerCount, it, v.description(), JSValue::encode(v));
+#else
+            printf("[r%2d]                      | %10p | %-16s %p \n", registerCount, it, v.description(), JSValue::encode(v));
+#endif
             ++it;
             ++registerCount;
         } while (it != end);
     }
-    printf("----------------------------------------------------\n");
+    printf("-----------------------------------------------------------------------------\n");
 }
 
 #endif
@@ -694,7 +486,7 @@ bool Interpreter::isOpcode(Opcode opcode)
 #endif
 }
 
-NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValuePtr exceptionValue, unsigned& bytecodeOffset, CodeBlock*& codeBlock)
+NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue exceptionValue, unsigned& bytecodeOffset, CodeBlock*& codeBlock)
 {
     CodeBlock* oldCodeBlock = codeBlock;
     ScopeChainNode* scopeChain = callFrame->scopeChain();
@@ -737,7 +529,7 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValuePtr
     return true;
 }
 
-NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValuePtr& exceptionValue, unsigned bytecodeOffset, bool explicitThrow)
+NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSValue& exceptionValue, unsigned bytecodeOffset, bool explicitThrow)
 {
     // Set up the exception object
 
@@ -791,13 +583,13 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
     if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
 #if !ENABLE(JIT)
         if (isCallBytecode(codeBlock->instructions()[bytecodeOffset].u.opcode))
-            profiler->didExecute(callFrame, callFrame[codeBlock->instructions()[bytecodeOffset + 2].u.operand].jsValue(callFrame));
+            profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 2].u.operand).jsValue());
         else if (codeBlock->instructions()[bytecodeOffset + 8].u.opcode == getOpcode(op_construct))
-            profiler->didExecute(callFrame, callFrame[codeBlock->instructions()[bytecodeOffset + 10].u.operand].jsValue(callFrame));
+            profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 10].u.operand).jsValue());
 #else
         int functionRegisterIndex;
         if (codeBlock->functionRegisterForBytecodeOffset(bytecodeOffset, functionRegisterIndex))
-            profiler->didExecute(callFrame, callFrame[functionRegisterIndex].jsValue(callFrame));
+            profiler->didExecute(callFrame, callFrame->r(functionRegisterIndex).jsValue());
 #endif
     }
 
@@ -822,13 +614,15 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
     return handler;
 }
 
-JSValuePtr Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValuePtr* exception)
+JSValue Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValue* exception)
 {
     ASSERT(!scopeChain->globalData->exception);
 
-    if (m_reentryDepth >= MaxReentryDepth) {
-        *exception = createStackOverflowError(callFrame);
-        return jsNull();
+    if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
+        if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
+            *exception = createStackOverflowError(callFrame);
+            return jsNull();
+        }
     }
 
     CodeBlock* codeBlock = &programNode->bytecode(scopeChain);
@@ -847,7 +641,7 @@ JSValuePtr Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame,
     globalObject->copyGlobalsTo(m_registerFile);
 
     CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize);
-    newCallFrame[codeBlock->thisRegister()] = JSValuePtr(thisObj);
+    newCallFrame->r(codeBlock->thisRegister()) = JSValue(thisObj);
     newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), 0, 0, 0);
 
     if (codeBlock->needsFullScopeChain())
@@ -857,15 +651,13 @@ JSValuePtr Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame,
     if (*profiler)
         (*profiler)->willExecute(newCallFrame, programNode->sourceURL(), programNode->lineNo());
 
-    JSValuePtr result;
+    JSValue result;
     {
         SamplingTool::CallRecord callRecord(m_sampler);
 
         m_reentryDepth++;
 #if ENABLE(JIT)
-        if (!codeBlock->jitCode())
-            JIT::compile(scopeChain->globalData, codeBlock);
-        result = JIT::execute(codeBlock->jitCode(), &m_registerFile, newCallFrame, scopeChain->globalData, exception);
+        result = programNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
 #else
         result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
 #endif
@@ -883,13 +675,15 @@ JSValuePtr Interpreter::execute(ProgramNode* programNode, CallFrame* callFrame,
     return result;
 }
 
-JSValuePtr Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValuePtr* exception)
+JSValue Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValue* exception)
 {
     ASSERT(!scopeChain->globalData->exception);
 
-    if (m_reentryDepth >= MaxReentryDepth) {
-        *exception = createStackOverflowError(callFrame);
-        return jsNull();
+    if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
+        if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
+            *exception = createStackOverflowError(callFrame);
+            return jsNull();
+        }
     }
 
     Register* oldEnd = m_registerFile.end();
@@ -904,10 +698,10 @@ JSValuePtr Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* c
 
     CallFrame* newCallFrame = CallFrame::create(oldEnd);
     size_t dst = 0;
-    newCallFrame[0] = JSValuePtr(thisObj);
+    newCallFrame->r(0) = JSValue(thisObj);
     ArgList::const_iterator end = args.end();
     for (ArgList::const_iterator it = args.begin(); it != end; ++it)
-        newCallFrame[++dst] = *it;
+        newCallFrame->r(++dst) = *it;
 
     CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain);
     newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
@@ -923,15 +717,13 @@ JSValuePtr Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* c
     if (*profiler)
         (*profiler)->willExecute(callFrame, function);
 
-    JSValuePtr result;
+    JSValue result;
     {
         SamplingTool::CallRecord callRecord(m_sampler);
 
         m_reentryDepth++;
 #if ENABLE(JIT)
-        if (!codeBlock->jitCode())
-            JIT::compile(scopeChain->globalData, codeBlock);
-        result = JIT::execute(codeBlock->jitCode(), &m_registerFile, newCallFrame, scopeChain->globalData, exception);
+        result = functionBodyNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
 #else
         result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
 #endif
@@ -945,18 +737,91 @@ JSValuePtr Interpreter::execute(FunctionBodyNode* functionBodyNode, CallFrame* c
     return result;
 }
 
-JSValuePtr Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValuePtr* exception)
+CallFrameClosure Interpreter::prepareForRepeatCall(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, int argCount, ScopeChainNode* scopeChain, JSValue* exception)
+{
+    ASSERT(!scopeChain->globalData->exception);
+    
+    if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
+        if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
+            *exception = createStackOverflowError(callFrame);
+            return CallFrameClosure();
+        }
+    }
+    
+    Register* oldEnd = m_registerFile.end();
+    int argc = 1 + argCount; // implicit "this" parameter
+    
+    if (!m_registerFile.grow(oldEnd + argc)) {
+        *exception = createStackOverflowError(callFrame);
+        return CallFrameClosure();
+    }
+
+    CallFrame* newCallFrame = CallFrame::create(oldEnd);
+    size_t dst = 0;
+    for (int i = 0; i < argc; ++i)
+        newCallFrame->r(++dst) = jsUndefined();
+    
+    CodeBlock* codeBlock = &functionBodyNode->bytecode(scopeChain);
+    newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
+    if (UNLIKELY(!newCallFrame)) {
+        *exception = createStackOverflowError(callFrame);
+        m_registerFile.shrink(oldEnd);
+        return CallFrameClosure();
+    }
+    // a 0 codeBlock indicates a built-in caller
+    newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function);
+#if ENABLE(JIT)
+    functionBodyNode->jitCode(scopeChain);
+#endif
+
+    CallFrameClosure result = { callFrame, newCallFrame, function, functionBodyNode, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
+    return result;
+}
+
+JSValue Interpreter::execute(CallFrameClosure& closure, JSValue* exception) 
+{
+    closure.resetCallFrame();
+    Profiler** profiler = Profiler::enabledProfilerReference();
+    if (*profiler)
+        (*profiler)->willExecute(closure.oldCallFrame, closure.function);
+    
+    JSValue result;
+    {
+        SamplingTool::CallRecord callRecord(m_sampler);
+        
+        m_reentryDepth++;
+#if ENABLE(JIT)
+        result = closure.functionBody->generatedJITCode().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception);
+#else
+        result = privateExecute(Normal, &m_registerFile, closure.newCallFrame, exception);
+#endif
+        m_reentryDepth--;
+    }
+    
+    if (*profiler)
+        (*profiler)->didExecute(closure.oldCallFrame, closure.function);
+    return result;
+}
+
+void Interpreter::endRepeatCall(CallFrameClosure& closure)
+{
+    m_registerFile.shrink(closure.oldEnd);
+}
+
+JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception)
 {
     return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNode->bytecode(scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
 }
 
-JSValuePtr Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValuePtr* exception)
+JSValue Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue* exception)
 {
     ASSERT(!scopeChain->globalData->exception);
 
-    if (m_reentryDepth >= MaxReentryDepth) {
-        *exception = createStackOverflowError(callFrame);
-        return jsNull();
+    if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
+        if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
+            *exception = createStackOverflowError(callFrame);
+            return jsNull();
+        }
     }
 
     DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
@@ -1005,7 +870,7 @@ JSValuePtr Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObje
     CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + globalRegisterOffset);
 
     // a 0 codeBlock indicates a built-in caller
-    newCallFrame[codeBlock->thisRegister()] = JSValuePtr(thisObj);
+    newCallFrame->r(codeBlock->thisRegister()) = JSValue(thisObj);
     newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, 0, 0);
 
     if (codeBlock->needsFullScopeChain())
@@ -1015,15 +880,13 @@ JSValuePtr Interpreter::execute(EvalNode* evalNode, CallFrame* callFrame, JSObje
     if (*profiler)
         (*profiler)->willExecute(newCallFrame, evalNode->sourceURL(), evalNode->lineNo());
 
-    JSValuePtr result;
+    JSValue result;
     {
         SamplingTool::CallRecord callRecord(m_sampler);
 
         m_reentryDepth++;
 #if ENABLE(JIT)
-        if (!codeBlock->jitCode())
-            JIT::compile(scopeChain->globalData, codeBlock);
-        result = JIT::execute(codeBlock->jitCode(), &m_registerFile, newCallFrame, scopeChain->globalData, exception);
+        result = evalNode->jitCode(scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
 #else
         result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
 #endif
@@ -1064,110 +927,21 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
             return;
     }
 }
-
-void Interpreter::resetTimeoutCheck()
-{
-    m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
-    m_timeAtLastCheckTimeout = 0;
-    m_timeExecuting = 0;
-}
-
-// Returns the time the current thread has spent executing, in milliseconds.
-static inline unsigned getCPUTime()
-{
-#if PLATFORM(DARWIN)
-    mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
-    thread_basic_info_data_t info;
-
-    // Get thread information
-    mach_port_t threadPort = mach_thread_self();
-    thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
-    mach_port_deallocate(mach_task_self(), threadPort);
-    
-    unsigned time = info.user_time.seconds * 1000 + info.user_time.microseconds / 1000;
-    time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
-    
-    return time;
-#elif HAVE(SYS_TIME_H)
-    // FIXME: This should probably use getrusage with the RUSAGE_THREAD flag.
-    struct timeval tv;
-    gettimeofday(&tv, 0);
-    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-#elif PLATFORM(QT)
-    QDateTime t = QDateTime::currentDateTime();
-    return t.toTime_t() * 1000 + t.time().msec();
-#elif PLATFORM(WIN_OS)
-    union {
-        FILETIME fileTime;
-        unsigned long long fileTimeAsLong;
-    } userTime, kernelTime;
-    
-    // GetThreadTimes won't accept NULL arguments so we pass these even though
-    // they're not used.
-    FILETIME creationTime, exitTime;
-    
-    GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
-    
-    return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
-#else
-#error Platform does not have getCurrentTime function
-#endif
-}
-
-// We have to return a JSValue here, gcc seems to produce worse code if 
-// we attempt to return a bool
-ALWAYS_INLINE bool Interpreter::checkTimeout(JSGlobalObject* globalObject)
-{
-    unsigned currentTime = getCPUTime();
     
-    if (!m_timeAtLastCheckTimeout) {
-        // Suspicious amount of looping in a script -- start timing it
-        m_timeAtLastCheckTimeout = currentTime;
-        return false;
-    }
-    
-    unsigned timeDiff = currentTime - m_timeAtLastCheckTimeout;
-    
-    if (timeDiff == 0)
-        timeDiff = 1;
-    
-    m_timeExecuting += timeDiff;
-    m_timeAtLastCheckTimeout = currentTime;
-    
-    // Adjust the tick threshold so we get the next checkTimeout call in the interval specified in 
-    // preferredScriptCheckTimeInterval
-    m_ticksUntilNextTimeoutCheck = static_cast<unsigned>((static_cast<float>(preferredScriptCheckTimeInterval) / timeDiff) * m_ticksUntilNextTimeoutCheck);
-    // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
-    // preferred script check time interval.
-    if (m_ticksUntilNextTimeoutCheck == 0)
-        m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
-    
-    if (globalObject->shouldInterruptScriptBeforeTimeout())
-        return true;
-
-    if (m_timeoutTime && m_timeExecuting > m_timeoutTime) {
-        if (globalObject->shouldInterruptScript())
-            return true;
-        
-        resetTimeoutCheck();
-    }
-    
-    return false;
-}
-
+#if USE(INTERPRETER)
 NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
 {
     int dst = (++vPC)->u.operand;
     CodeBlock* codeBlock = callFrame->codeBlock();
     Identifier& property = codeBlock->identifier((++vPC)->u.operand);
-    JSValuePtr value = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+    JSValue value = callFrame->r((++vPC)->u.operand).jsValue();
     JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete);
-    callFrame[dst] = JSValuePtr(scope);
+    callFrame->r(dst) = JSValue(scope);
 
     return callFrame->scopeChain()->push(scope);
 }
 
-NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValuePtr baseValue, const PutPropertySlot& slot)
+NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const PutPropertySlot& slot)
 {
     // Recursive invocation may already have specialized this instruction.
     if (vPC[0].u.opcode != getOpcode(op_put_by_id))
@@ -1185,7 +959,7 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock*
     JSCell* baseCell = asCell(baseValue);
     Structure* structure = baseCell->structure();
 
-    if (structure->isDictionary()) {
+    if (structure->isUncacheableDictionary()) {
         vPC[0] = getOpcode(op_put_by_id_generic);
         return;
     }
@@ -1212,12 +986,22 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock*
         return;
     }
 
+    StructureChain* protoChain = structure->prototypeChain(callFrame);
+    if (!protoChain->isCacheable()) {
+        vPC[0] = getOpcode(op_put_by_id_generic);
+        return;
+    }
+
     // Structure transition, cache transition info
     if (slot.type() == PutPropertySlot::NewProperty) {
+        if (structure->isDictionary()) {
+            vPC[0] = getOpcode(op_put_by_id_generic);
+            return;
+        }
         vPC[0] = getOpcode(op_put_by_id_transition);
         vPC[4] = structure->previousID();
         vPC[5] = structure;
-        vPC[6] = structure->prototypeChain(callFrame);
+        vPC[6] = protoChain;
         vPC[7] = slot.cachedOffset();
         codeBlock->refStructures(vPC);
         return;
@@ -1235,35 +1019,7 @@ NEVER_INLINE void Interpreter::uncachePutByID(CodeBlock* codeBlock, Instruction*
     vPC[4] = 0;
 }
 
-static size_t countPrototypeChainEntriesAndCheckForProxies(CallFrame* callFrame, JSValuePtr baseValue, const PropertySlot& slot)
-{
-    JSCell* cell = asCell(baseValue);
-    size_t count = 0;
-
-    while (slot.slotBase() != cell) {
-        JSValuePtr v = cell->structure()->prototypeForLookup(callFrame);
-
-        // If we didn't find slotBase in baseValue's prototype chain, then baseValue
-        // must be a proxy for another object.
-
-        if (v.isNull())
-            return 0;
-
-        cell = asCell(v);
-
-        // Since we're accessing a prototype in a loop, it's a good bet that it
-        // should not be treated as a dictionary.
-        if (cell->structure()->isDictionary()) 
-            asObject(cell)->setStructure(Structure::fromDictionaryTransition(cell->structure())); 
-
-        ++count;
-    }
-    
-    ASSERT(count);
-    return count;
-}
-
-NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot& slot)
+NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot)
 {
     // Recursive invocation may already have specialized this instruction.
     if (vPC[0].u.opcode != getOpcode(op_get_by_id))
@@ -1275,12 +1031,13 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
         return;
     }
 
-    if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
+    JSGlobalData* globalData = &callFrame->globalData();
+    if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
         vPC[0] = getOpcode(op_get_array_length);
         return;
     }
 
-    if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
+    if (isJSString(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
         vPC[0] = getOpcode(op_get_string_length);
         return;
     }
@@ -1293,7 +1050,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
 
     Structure* structure = asCell(baseValue)->structure();
 
-    if (structure->isDictionary()) {
+    if (structure->isUncacheableDictionary()) {
         vPC[0] = getOpcode(op_get_by_id_generic);
         return;
     }
@@ -1322,35 +1079,52 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
         return;
     }
 
+    if (structure->isDictionary()) {
+        vPC[0] = getOpcode(op_get_by_id_generic);
+        return;
+    }
+
     if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
         ASSERT(slot.slotBase().isObject());
 
         JSObject* baseObject = asObject(slot.slotBase());
+        size_t offset = slot.cachedOffset();
 
         // Since we're accessing a prototype in a loop, it's a good bet that it
         // should not be treated as a dictionary.
-        if (baseObject->structure()->isDictionary())
-            baseObject->setStructure(Structure::fromDictionaryTransition(baseObject->structure()));
+        if (baseObject->structure()->isDictionary()) {
+            baseObject->flattenDictionaryObject();
+            offset = baseObject->structure()->get(propertyName);
+        }
+
+        ASSERT(!baseObject->structure()->isUncacheableDictionary());
 
         vPC[0] = getOpcode(op_get_by_id_proto);
         vPC[5] = baseObject->structure();
-        vPC[6] = slot.cachedOffset();
+        vPC[6] = offset;
 
         codeBlock->refStructures(vPC);
         return;
     }
 
-    size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
+    size_t offset = slot.cachedOffset();
+    size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
     if (!count) {
         vPC[0] = getOpcode(op_get_by_id_generic);
         return;
     }
 
-    vPC[0] = getOpcode(op_get_by_id_chain);
-    vPC[4] = structure;
-    vPC[5] = structure->prototypeChain(callFrame);
+    StructureChain* protoChain = structure->prototypeChain(callFrame);
+    if (!protoChain->isCacheable()) {
+        vPC[0] = getOpcode(op_get_by_id_generic);
+        return;
+    }
+
+    vPC[0] = getOpcode(op_get_by_id_chain);
+    vPC[4] = structure;
+    vPC[5] = protoChain;
     vPC[6] = count;
-    vPC[7] = slot.cachedOffset();
+    vPC[7] = offset;
     codeBlock->refStructures(vPC);
 }
 
@@ -1361,40 +1135,45 @@ NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock* codeBlock, Instruction*
     vPC[4] = 0;
 }
 
-JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame, JSValuePtr* exception)
+#endif // USE(INTERPRETER)
+
+JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame, JSValue* exception)
 {
     // One-time initialization of our address tables. We have to put this code
     // here because our labels are only in scope inside this function.
-    if (flag == InitializeAndReturn) {
+    if (UNLIKELY(flag == InitializeAndReturn)) {
         #if HAVE(COMPUTED_GOTO)
-            #define ADD_BYTECODE(id, length) m_opcodeTable[id] = &&id;
-                FOR_EACH_OPCODE_ID(ADD_BYTECODE);
-            #undef ADD_BYTECODE
-
-            #define ADD_OPCODE_ID(id, length) m_opcodeIDTable.add(&&id, id);
-                FOR_EACH_OPCODE_ID(ADD_OPCODE_ID);
-            #undef ADD_OPCODE_ID
-            ASSERT(m_opcodeIDTable.size() == numOpcodeIDs);
+            #define LIST_OPCODE_LABEL(id, length) &&id,
+                static Opcode labels[] = { FOR_EACH_OPCODE_ID(LIST_OPCODE_LABEL) };
+                for (size_t i = 0; i < sizeof(labels) / sizeof(Opcode); ++i)
+                    m_opcodeTable[i] = labels[i];
+            #undef LIST_OPCODE_LABEL
         #endif // HAVE(COMPUTED_GOTO)
-        return noValue();
+        return JSValue();
     }
 
 #if ENABLE(JIT)
-    // Currently with CTI enabled we never interpret functions
+    // Mixing Interpreter + JIT is not supported.
     ASSERT_NOT_REACHED();
 #endif
+#if !USE(INTERPRETER)
+    UNUSED_PARAM(registerFile);
+    UNUSED_PARAM(callFrame);
+    UNUSED_PARAM(exception);
+    return JSValue();
+#else
 
     JSGlobalData* globalData = &callFrame->globalData();
-    JSValuePtr exceptionValue = noValue();
+    JSValue exceptionValue;
     HandlerInfo* handler = 0;
 
     Instruction* vPC = callFrame->codeBlock()->instructions().begin();
     Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
-    unsigned tickCount = m_ticksUntilNextTimeoutCheck + 1;
+    unsigned tickCount = globalData->timeoutChecker.ticksUntilNextCheck();
 
 #define CHECK_FOR_EXCEPTION() \
     do { \
-        if (UNLIKELY(globalData->exception != noValue())) { \
+        if (UNLIKELY(globalData->exception != JSValue())) { \
             exceptionValue = globalData->exception; \
             goto vm_throw; \
         } \
@@ -1406,19 +1185,17 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
 
 #define CHECK_FOR_TIMEOUT() \
     if (!--tickCount) { \
-        if (checkTimeout(callFrame->dynamicGlobalObject())) { \
+        if (globalData->timeoutChecker.didTimeOut(callFrame)) { \
             exceptionValue = jsNull(); \
             goto vm_throw; \
         } \
-        tickCount = m_ticksUntilNextTimeoutCheck; \
+        tickCount = globalData->timeoutChecker.ticksUntilNextCheck(); \
     }
     
 #if ENABLE(OPCODE_SAMPLING)
     #define SAMPLE(codeBlock, vPC) m_sampler->sample(codeBlock, vPC)
-    #define CTI_SAMPLER ARG_globalData->interpreter->sampler()
 #else
     #define SAMPLE(codeBlock, vPC)
-    #define CTI_SAMPLER 0
 #endif
 
 #if HAVE(COMPUTED_GOTO)
@@ -1448,7 +1225,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            constructor, and puts the result in register dst.
         */
         int dst = (++vPC)->u.operand;
-        callFrame[dst] = JSValuePtr(constructEmptyObject(callFrame));
+        callFrame->r(dst) = JSValue(constructEmptyObject(callFrame));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -1465,7 +1242,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int firstArg = (++vPC)->u.operand;
         int argCount = (++vPC)->u.operand;
         ArgList args(callFrame->registers() + firstArg, argCount);
-        callFrame[dst] = JSValuePtr(constructArray(callFrame, args));
+        callFrame->r(dst) = JSValue(constructArray(callFrame, args));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -1479,7 +1256,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int regExp = (++vPC)->u.operand;
-        callFrame[dst] = JSValuePtr(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));
+        callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -1491,7 +1268,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        callFrame[dst] = callFrame[src];
+        callFrame->r(dst) = callFrame->r(src);
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -1504,14 +1281,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            as a boolean in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
-            callFrame[dst] = JSFastMath::equal(src1, src2);
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src1.isInt32() && src2.isInt32())
+            callFrame->r(dst) = jsBoolean(src1.asInt32() == src2.asInt32());
         else {
-            JSValuePtr result = jsBoolean(JSValuePtr::equalSlowCase(callFrame, src1, src2));
+            JSValue result = jsBoolean(JSValue::equalSlowCase(callFrame, src1, src2));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         ++vPC;
@@ -1524,15 +1301,15 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            operator, and puts the result as a boolean in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+        JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
 
         if (src.isUndefinedOrNull()) {
-            callFrame[dst] = jsBoolean(true);
+            callFrame->r(dst) = jsBoolean(true);
             ++vPC;
             NEXT_INSTRUCTION();
         }
         
-        callFrame[dst] = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
+        callFrame->r(dst) = jsBoolean(src.isCell() && src.asCell()->structure()->typeInfo().masqueradesAsUndefined());
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -1544,14 +1321,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            result as a boolean in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
-            callFrame[dst] = JSFastMath::notEqual(src1, src2);
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src1.isInt32() && src2.isInt32())
+            callFrame->r(dst) = jsBoolean(src1.asInt32() != src2.asInt32());
         else {
-            JSValuePtr result = jsBoolean(!JSValuePtr::equalSlowCase(callFrame, src1, src2));
+            JSValue result = jsBoolean(!JSValue::equalSlowCase(callFrame, src1, src2));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         ++vPC;
@@ -1564,15 +1341,15 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            operator, and puts the result as a boolean in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+        JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
 
         if (src.isUndefinedOrNull()) {
-            callFrame[dst] = jsBoolean(false);
+            callFrame->r(dst) = jsBoolean(false);
             ++vPC;
             NEXT_INSTRUCTION();
         }
         
-        callFrame[dst] = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined());
+        callFrame->r(dst) = jsBoolean(!src.isCell() || !asCell(src)->structure()->typeInfo().masqueradesAsUndefined());
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -1584,9 +1361,9 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            result as a boolean in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        callFrame[dst] = jsBoolean(JSValuePtr::strictEqual(src1, src2));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        callFrame->r(dst) = jsBoolean(JSValue::strictEqual(src1, src2));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -1599,9 +1376,9 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            puts the result as a boolean in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        callFrame[dst] = jsBoolean(!JSValuePtr::strictEqual(src1, src2));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        callFrame->r(dst) = jsBoolean(!JSValue::strictEqual(src1, src2));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -1614,11 +1391,11 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            a boolean in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr result = jsBoolean(jsLess(callFrame, src1, src2));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue result = jsBoolean(jsLess(callFrame, src1, src2));
         CHECK_FOR_EXCEPTION();
-        callFrame[dst] = result;
+        callFrame->r(dst) = result;
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -1631,11 +1408,11 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            puts the result as a boolean in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr result = jsBoolean(jsLessEq(callFrame, src1, src2));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue result = jsBoolean(jsLessEq(callFrame, src1, src2));
         CHECK_FOR_EXCEPTION();
-        callFrame[dst] = result;
+        callFrame->r(dst) = result;
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -1647,13 +1424,13 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            back in register srcDst.
         */
         int srcDst = (++vPC)->u.operand;
-        JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
-        if (JSFastMath::canDoFastAdditiveOperations(v))
-            callFrame[srcDst] = JSValuePtr(JSFastMath::incImmediateNumber(v));
+        JSValue v = callFrame->r(srcDst).jsValue();
+        if (v.isInt32() && v.asInt32() < INT_MAX)
+            callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
         else {
-            JSValuePtr result = jsNumber(callFrame, v.toNumber(callFrame) + 1);
+            JSValue result = jsNumber(callFrame, v.toNumber(callFrame) + 1);
             CHECK_FOR_EXCEPTION();
-            callFrame[srcDst] = result;
+            callFrame->r(srcDst) = result;
         }
 
         ++vPC;
@@ -1666,13 +1443,13 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            back in register srcDst.
         */
         int srcDst = (++vPC)->u.operand;
-        JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
-        if (JSFastMath::canDoFastAdditiveOperations(v))
-            callFrame[srcDst] = JSValuePtr(JSFastMath::decImmediateNumber(v));
+        JSValue v = callFrame->r(srcDst).jsValue();
+        if (v.isInt32() && v.asInt32() > INT_MIN)
+            callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
         else {
-            JSValuePtr result = jsNumber(callFrame, v.toNumber(callFrame) - 1);
+            JSValue result = jsNumber(callFrame, v.toNumber(callFrame) - 1);
             CHECK_FOR_EXCEPTION();
-            callFrame[srcDst] = result;
+            callFrame->r(srcDst) = result;
         }
 
         ++vPC;
@@ -1687,15 +1464,15 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int srcDst = (++vPC)->u.operand;
-        JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
-        if (JSFastMath::canDoFastAdditiveOperations(v)) {
-            callFrame[dst] = v;
-            callFrame[srcDst] = JSValuePtr(JSFastMath::incImmediateNumber(v));
+        JSValue v = callFrame->r(srcDst).jsValue();
+        if (v.isInt32() && v.asInt32() < INT_MAX) {
+            callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() + 1);
+            callFrame->r(dst) = v;
         } else {
-            JSValuePtr number = callFrame[srcDst].jsValue(callFrame).toJSNumber(callFrame);
+            JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame);
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = number;
-            callFrame[srcDst] = JSValuePtr(jsNumber(callFrame, number.uncheckedGetNumber() + 1));
+            callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() + 1);
+            callFrame->r(dst) = number;
         }
 
         ++vPC;
@@ -1710,15 +1487,15 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int srcDst = (++vPC)->u.operand;
-        JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
-        if (JSFastMath::canDoFastAdditiveOperations(v)) {
-            callFrame[dst] = v;
-            callFrame[srcDst] = JSValuePtr(JSFastMath::decImmediateNumber(v));
+        JSValue v = callFrame->r(srcDst).jsValue();
+        if (v.isInt32() && v.asInt32() > INT_MIN) {
+            callFrame->r(srcDst) = jsNumber(callFrame, v.asInt32() - 1);
+            callFrame->r(dst) = v;
         } else {
-            JSValuePtr number = callFrame[srcDst].jsValue(callFrame).toJSNumber(callFrame);
+            JSValue number = callFrame->r(srcDst).jsValue().toJSNumber(callFrame);
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = number;
-            callFrame[srcDst] = JSValuePtr(jsNumber(callFrame, number.uncheckedGetNumber() - 1));
+            callFrame->r(srcDst) = jsNumber(callFrame, number.uncheckedGetNumber() - 1);
+            callFrame->r(dst) = number;
         }
 
         ++vPC;
@@ -1733,14 +1510,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
 
-        JSValuePtr srcVal = callFrame[src].jsValue(callFrame);
+        JSValue srcVal = callFrame->r(src).jsValue();
 
         if (LIKELY(srcVal.isNumber()))
-            callFrame[dst] = callFrame[src];
+            callFrame->r(dst) = callFrame->r(src);
         else {
-            JSValuePtr result = srcVal.toJSNumber(callFrame);
+            JSValue result = srcVal.toJSNumber(callFrame);
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         ++vPC;
@@ -1753,17 +1530,16 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            result in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        ++vPC;
-        double v;
-        if (src.getNumber(v))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, -v));
+        JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src.isInt32() && src.asInt32())
+            callFrame->r(dst) = jsNumber(callFrame, -src.asInt32());
         else {
-            JSValuePtr result = jsNumber(callFrame, -src.toNumber(callFrame));
+            JSValue result = jsNumber(callFrame, -src.toNumber(callFrame));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
+        ++vPC;
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_add) {
@@ -1774,14 +1550,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            numeric add, depending on the types of the operands.)
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        if (JSFastMath::canDoFastAdditiveOperations(src1, src2))
-            callFrame[dst] = JSValuePtr(JSFastMath::addImmediateNumbers(src1, src2));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow
+            callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() + src2.asInt32());
         else {
-            JSValuePtr result = jsAdd(callFrame, src1, src2);
+            JSValue result = jsAdd(callFrame, src1, src2);
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
         vPC += 2;
         NEXT_INSTRUCTION();
@@ -1793,23 +1569,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            numbers), and puts the product in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        double left;
-        double right;
-        if (JSValuePtr::areBothInt32Fast(src1, src2)) {
-            int32_t left = src1.getInt32Fast();
-            int32_t right = src2.getInt32Fast();
-            if ((left | right) >> 15 == 0)
-                callFrame[dst] = JSValuePtr(jsNumber(callFrame, left * right));
-            else
-                callFrame[dst] = JSValuePtr(jsNumber(callFrame, static_cast<double>(left) * static_cast<double>(right)));
-        } else if (src1.getNumber(left) && src2.getNumber(right))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, left * right));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() >> 15)) // no overflow
+                callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() * src2.asInt32());
         else {
-            JSValuePtr result = jsNumber(callFrame, src1.toNumber(callFrame) * src2.toNumber(callFrame));
+            JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) * src2.toNumber(callFrame));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         vPC += 2;
@@ -1823,18 +1590,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            quotient in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr dividend = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr divisor = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        double left;
-        double right;
-        if (dividend.getNumber(left) && divisor.getNumber(right))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, left / right));
-        else {
-            JSValuePtr result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
-            CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
-        }
-        ++vPC;
+        JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue();
+
+        JSValue result = jsNumber(callFrame, dividend.toNumber(callFrame) / divisor.toNumber(callFrame));
+        CHECK_FOR_EXCEPTION();
+        callFrame->r(dst) = result;
+
+        vPC += 2;
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_mod) {
@@ -1845,26 +1608,24 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            remainder in register dst.
         */
         int dst = (++vPC)->u.operand;
-        int dividend = (++vPC)->u.operand;
-        int divisor = (++vPC)->u.operand;
+        JSValue dividend = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue divisor = callFrame->r((++vPC)->u.operand).jsValue();
 
-        JSValuePtr dividendValue = callFrame[dividend].jsValue(callFrame);
-        JSValuePtr divisorValue = callFrame[divisor].jsValue(callFrame);
-
-        if (JSValuePtr::areBothInt32Fast(dividendValue, divisorValue) && divisorValue != js0()) {
-            // We expect the result of the modulus of a number that was representable as an int32 to also be representable
-            // as an int32.
-            JSValuePtr result = JSValuePtr::makeInt32Fast(dividendValue.getInt32Fast() % divisorValue.getInt32Fast());
+        if (dividend.isInt32() && divisor.isInt32() && divisor.asInt32() != 0) {
+            JSValue result = jsNumber(callFrame, dividend.asInt32() % divisor.asInt32());
             ASSERT(result);
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
             ++vPC;
             NEXT_INSTRUCTION();
         }
 
-        double d = dividendValue.toNumber(callFrame);
-        JSValuePtr result = jsNumber(callFrame, fmod(d, divisorValue.toNumber(callFrame)));
+        // Conversion to double must happen outside the call to fmod since the
+        // order of argument evaluation is not guaranteed.
+        double d1 = dividend.toNumber(callFrame);
+        double d2 = divisor.toNumber(callFrame);
+        JSValue result = jsNumber(callFrame, fmod(d1, d2));
         CHECK_FOR_EXCEPTION();
-        callFrame[dst] = result;
+        callFrame->r(dst) = result;
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -1876,18 +1637,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        double left;
-        double right;
-        if (JSFastMath::canDoFastAdditiveOperations(src1, src2))
-            callFrame[dst] = JSValuePtr(JSFastMath::subImmediateNumbers(src1, src2));
-        else if (src1.getNumber(left) && src2.getNumber(right))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, left - right));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src1.isInt32() && src2.isInt32() && !(src1.asInt32() | src2.asInt32() & 0xc0000000)) // no overflow
+            callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() - src2.asInt32());
         else {
-            JSValuePtr result = jsNumber(callFrame, src1.toNumber(callFrame) - src2.toNumber(callFrame));
+            JSValue result = jsNumber(callFrame, src1.toNumber(callFrame) - src2.toNumber(callFrame));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
         vPC += 2;
         NEXT_INSTRUCTION();
@@ -1900,18 +1657,15 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        int32_t left;
-        uint32_t right;
-        if (JSValuePtr::areBothInt32Fast(val, shift))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f)));
-        else if (val.numberToInt32(left) && shift.numberToUInt32(right))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, left << (right & 0x1f)));
+        JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
+
+        if (val.isInt32() && shift.isInt32())
+            callFrame->r(dst) = jsNumber(callFrame, val.asInt32() << (shift.asInt32() & 0x1f));
         else {
-            JSValuePtr result = jsNumber(callFrame, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
+            JSValue result = jsNumber(callFrame, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         ++vPC;
@@ -1925,18 +1679,15 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            uint32), and puts the result in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        int32_t left;
-        uint32_t right;
-        if (JSFastMath::canDoFastRshift(val, shift))
-            callFrame[dst] = JSValuePtr(JSFastMath::rightShiftImmediateNumbers(val, shift));
-        else if (val.numberToInt32(left) && shift.numberToUInt32(right))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, left >> (right & 0x1f)));
+        JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
+
+        if (val.isInt32() && shift.isInt32())
+            callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
         else {
-            JSValuePtr result = jsNumber(callFrame, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+            JSValue result = jsNumber(callFrame, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         ++vPC;
@@ -1950,14 +1701,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            uint32), and puts the result in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        if (JSFastMath::canDoFastUrshift(val, shift))
-            callFrame[dst] = JSValuePtr(JSFastMath::rightShiftImmediateNumbers(val, shift));
+        JSValue val = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue shift = callFrame->r((++vPC)->u.operand).jsValue();
+        if (val.isUInt32() && shift.isInt32())
+            callFrame->r(dst) = jsNumber(callFrame, val.asInt32() >> (shift.asInt32() & 0x1f));
         else {
-            JSValuePtr result = jsNumber(callFrame, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+            JSValue result = jsNumber(callFrame, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         ++vPC;
@@ -1971,18 +1722,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        int32_t left;
-        int32_t right;
-        if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
-            callFrame[dst] = JSValuePtr(JSFastMath::andImmediateNumbers(src1, src2));
-        else if (src1.numberToInt32(left) && src2.numberToInt32(right))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, left & right));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src1.isInt32() && src2.isInt32())
+            callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() & src2.asInt32());
         else {
-            JSValuePtr result = jsNumber(callFrame, src1.toInt32(callFrame) & src2.toInt32(callFrame));
+            JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) & src2.toInt32(callFrame));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         vPC += 2;
@@ -1996,18 +1743,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        int32_t left;
-        int32_t right;
-        if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
-            callFrame[dst] = JSValuePtr(JSFastMath::xorImmediateNumbers(src1, src2));
-        else if (src1.numberToInt32(left) && src2.numberToInt32(right))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, left ^ right));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src1.isInt32() && src2.isInt32())
+            callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() ^ src2.asInt32());
         else {
-            JSValuePtr result = jsNumber(callFrame, src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
+            JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         vPC += 2;
@@ -2021,18 +1764,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            result in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        int32_t left;
-        int32_t right;
-        if (JSFastMath::canDoFastBitwiseOperations(src1, src2))
-            callFrame[dst] = JSValuePtr(JSFastMath::orImmediateNumbers(src1, src2));
-        else if (src1.numberToInt32(left) && src2.numberToInt32(right))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, left | right));
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src1.isInt32() && src2.isInt32())
+            callFrame->r(dst) = jsNumber(callFrame, src1.asInt32() | src2.asInt32());
         else {
-            JSValuePtr result = jsNumber(callFrame, src1.toInt32(callFrame) | src2.toInt32(callFrame));
+            JSValue result = jsNumber(callFrame, src1.toInt32(callFrame) | src2.toInt32(callFrame));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
 
         vPC += 2;
@@ -2045,14 +1784,13 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            and puts the result in register dst.
         */
         int dst = (++vPC)->u.operand;
-        JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        int32_t value;
-        if (src.numberToInt32(value))
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, ~value));
+        JSValue src = callFrame->r((++vPC)->u.operand).jsValue();
+        if (src.isInt32())
+            callFrame->r(dst) = jsNumber(callFrame, ~src.asInt32());
         else {
-            JSValuePtr result = jsNumber(callFrame, ~src.toInt32(callFrame));
+            JSValue result = jsNumber(callFrame, ~src.toInt32(callFrame));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
         }
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2065,9 +1803,9 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        JSValuePtr result = jsBoolean(!callFrame[src].jsValue(callFrame).toBoolean(callFrame));
+        JSValue result = jsBoolean(!callFrame->r(src).jsValue().toBoolean(callFrame));
         CHECK_FOR_EXCEPTION();
-        callFrame[dst] = result;
+        callFrame->r(dst) = result;
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2090,13 +1828,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int base = vPC[3].u.operand;
         int baseProto = vPC[4].u.operand;
 
-        JSValuePtr baseVal = callFrame[base].jsValue(callFrame);
+        JSValue baseVal = callFrame->r(base).jsValue();
 
-        if (isNotObject(callFrame, true, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
+        if (isInvalidParamForInstanceOf(callFrame, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
             goto vm_throw;
 
-        JSObject* baseObj = asObject(baseVal);
-        callFrame[dst] = jsBoolean(baseObj->structure()->typeInfo().implementsHasInstance() ? baseObj->hasInstance(callFrame, callFrame[value].jsValue(callFrame), callFrame[baseProto].jsValue(callFrame)) : false);
+        bool result = asObject(baseVal)->hasInstance(callFrame, callFrame->r(value).jsValue(), callFrame->r(baseProto).jsValue());
+        CHECK_FOR_EXCEPTION();
+        callFrame->r(dst) = jsBoolean(result);
 
         vPC += 5;
         NEXT_INSTRUCTION();
@@ -2109,7 +1848,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        callFrame[dst] = JSValuePtr(jsTypeStringForValue(callFrame, callFrame[src].jsValue(callFrame)));
+        callFrame->r(dst) = JSValue(jsTypeStringForValue(callFrame, callFrame->r(src).jsValue()));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2123,8 +1862,8 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        JSValuePtr v = callFrame[src].jsValue(callFrame);
-        callFrame[dst] = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined());
+        JSValue v = callFrame->r(src).jsValue();
+        callFrame->r(dst) = jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined());
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2138,7 +1877,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame).isBoolean());
+        callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isBoolean());
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2152,7 +1891,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame).isNumber());
+        callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isNumber());
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2166,7 +1905,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame).isString());
+        callFrame->r(dst) = jsBoolean(callFrame->r(src).jsValue().isString());
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2180,7 +1919,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        callFrame[dst] = jsBoolean(jsIsObjectType(callFrame[src].jsValue(callFrame)));
+        callFrame->r(dst) = jsBoolean(jsIsObjectType(callFrame->r(src).jsValue()));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2194,7 +1933,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int dst = (++vPC)->u.operand;
         int src = (++vPC)->u.operand;
-        callFrame[dst] = jsBoolean(jsIsFunctionType(callFrame[src].jsValue(callFrame)));
+        callFrame->r(dst) = jsBoolean(jsIsFunctionType(callFrame->r(src).jsValue()));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2212,21 +1951,21 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int property = (++vPC)->u.operand;
         int base = (++vPC)->u.operand;
 
-        JSValuePtr baseVal = callFrame[base].jsValue(callFrame);
-        if (isNotObject(callFrame, false, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
+        JSValue baseVal = callFrame->r(base).jsValue();
+        if (isInvalidParamForIn(callFrame, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
             goto vm_throw;
 
         JSObject* baseObj = asObject(baseVal);
 
-        JSValuePtr propName = callFrame[property].jsValue(callFrame);
+        JSValue propName = callFrame->r(property).jsValue();
 
         uint32_t i;
         if (propName.getUInt32(i))
-            callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, i));
+            callFrame->r(dst) = jsBoolean(baseObj->hasProperty(callFrame, i));
         else {
             Identifier property(callFrame, propName.toString(callFrame));
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, property));
+            callFrame->r(dst) = jsBoolean(baseObj->hasProperty(callFrame, property));
         }
 
         ++vPC;
@@ -2284,7 +2023,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         ASSERT(scope->isGlobalObject());
         int index = (++vPC)->u.operand;
 
-        callFrame[dst] = scope->registerAt(index);
+        callFrame->r(dst) = scope->registerAt(index);
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -2298,7 +2037,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int index = (++vPC)->u.operand;
         int value = (++vPC)->u.operand;
         
-        scope->registerAt(index) = JSValuePtr(callFrame[value].jsValue(callFrame));
+        scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
         ++vPC;
         NEXT_INSTRUCTION();
     }            
@@ -2323,7 +2062,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
 
         ASSERT((*iter)->isVariableObject());
         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
-        callFrame[dst] = scope->registerAt(index);
+        callFrame->r(dst) = scope->registerAt(index);
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -2346,7 +2085,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
 
         ASSERT((*iter)->isVariableObject());
         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
-        scope->registerAt(index) = JSValuePtr(callFrame[value].jsValue(callFrame));
+        scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -2381,27 +2120,6 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         vPC += 4;
         NEXT_INSTRUCTION();
     }
-    DEFINE_OPCODE(op_resolve_func) {
-        /* resolve_func baseDst(r) funcDst(r) property(id)
-
-           Searches the scope chain for an object containing
-           identifier property, and if one is found, writes the
-           appropriate object to use as "this" when calling its
-           properties to register baseDst; and the retrieved property
-           value to register propDst. If the property is not found,
-           raises an exception.
-
-           This differs from resolve_with_base, because the
-           global this value will be substituted for activations or
-           the global object, which is the right behavior for function
-           calls but not for other property lookup.
-        */
-        if (UNLIKELY(!resolveBaseAndFunc(callFrame, vPC, exceptionValue)))
-            goto vm_throw;
-
-        vPC += 4;
-        NEXT_INSTRUCTION();
-    }
     DEFINE_OPCODE(op_get_by_id) {
         /* get_by_id dst(r) base(r) property(id) structure(sID) nop(n) nop(n) nop(n)
 
@@ -2414,14 +2132,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
 
         CodeBlock* codeBlock = callFrame->codeBlock();
         Identifier& ident = codeBlock->identifier(property);
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
         PropertySlot slot(baseValue);
-        JSValuePtr result = baseValue.get(callFrame, ident, slot);
+        JSValue result = baseValue.get(callFrame, ident, slot);
         CHECK_FOR_EXCEPTION();
 
         tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);
 
-        callFrame[dst] = result;
+        callFrame->r(dst) = result;
         vPC += 8;
         NEXT_INSTRUCTION();
     }
@@ -2433,7 +2151,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            op_get_by_id.
         */
         int base = vPC[2].u.operand;
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
 
         if (LIKELY(baseValue.isCell())) {
             JSCell* baseCell = asCell(baseValue);
@@ -2446,7 +2164,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
                 int offset = vPC[5].u.operand;
 
                 ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
-                callFrame[dst] = JSValuePtr(baseObject->getDirectOffset(offset));
+                callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset));
 
                 vPC += 8;
                 NEXT_INSTRUCTION();
@@ -2464,7 +2182,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            reverts to op_get_by_id.
         */
         int base = vPC[2].u.operand;
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
 
         if (LIKELY(baseValue.isCell())) {
             JSCell* baseCell = asCell(baseValue);
@@ -2480,7 +2198,8 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
                     int offset = vPC[6].u.operand;
 
                     ASSERT(protoObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
-                    callFrame[dst] = JSValuePtr(protoObject->getDirectOffset(offset));
+                    ASSERT(baseValue.get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == protoObject->getDirectOffset(offset));
+                    callFrame->r(dst) = JSValue(protoObject->getDirectOffset(offset));
 
                     vPC += 8;
                     NEXT_INSTRUCTION();
@@ -2513,7 +2232,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            reverts to op_get_by_id.
         */
         int base = vPC[2].u.operand;
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
 
         if (LIKELY(baseValue.isCell())) {
             JSCell* baseCell = asCell(baseValue);
@@ -2535,7 +2254,8 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
                         int offset = vPC[7].u.operand;
 
                         ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
-                        callFrame[dst] = JSValuePtr(baseObject->getDirectOffset(offset));
+                        ASSERT(baseValue.get(callFrame, callFrame->codeBlock()->identifier(vPC[3].u.operand)) == baseObject->getDirectOffset(offset));
+                        callFrame->r(dst) = JSValue(baseObject->getDirectOffset(offset));
 
                         vPC += 8;
                         NEXT_INSTRUCTION();
@@ -2561,12 +2281,12 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int property = vPC[3].u.operand;
 
         Identifier& ident = callFrame->codeBlock()->identifier(property);
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
         PropertySlot slot(baseValue);
-        JSValuePtr result = baseValue.get(callFrame, ident, slot);
+        JSValue result = baseValue.get(callFrame, ident, slot);
         CHECK_FOR_EXCEPTION();
 
-        callFrame[dst] = result;
+        callFrame->r(dst) = result;
         vPC += 8;
         NEXT_INSTRUCTION();
     }
@@ -2579,10 +2299,10 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
 
         int base = vPC[2].u.operand;
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
-        if (LIKELY(isJSArray(baseValue))) {
+        JSValue baseValue = callFrame->r(base).jsValue();
+        if (LIKELY(isJSArray(globalData, baseValue))) {
             int dst = vPC[1].u.operand;
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, asArray(baseValue)->length()));
+            callFrame->r(dst) = jsNumber(callFrame, asArray(baseValue)->length());
             vPC += 8;
             NEXT_INSTRUCTION();
         }
@@ -2599,10 +2319,10 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
 
         int base = vPC[2].u.operand;
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
-        if (LIKELY(isJSString(baseValue))) {
+        JSValue baseValue = callFrame->r(base).jsValue();
+        if (LIKELY(isJSString(globalData, baseValue))) {
             int dst = vPC[1].u.operand;
-            callFrame[dst] = JSValuePtr(jsNumber(callFrame, asString(baseValue)->value().size()));
+            callFrame->r(dst) = jsNumber(callFrame, asString(baseValue)->value().size());
             vPC += 8;
             NEXT_INSTRUCTION();
         }
@@ -2625,10 +2345,10 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int value = vPC[3].u.operand;
 
         CodeBlock* codeBlock = callFrame->codeBlock();
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
         Identifier& ident = codeBlock->identifier(property);
         PutPropertySlot slot;
-        baseValue.put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
+        baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
         CHECK_FOR_EXCEPTION();
 
         tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
@@ -2648,7 +2368,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            the register file.
          */
         int base = vPC[1].u.operand;
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
         
         if (LIKELY(baseValue.isCell())) {
             JSCell* baseCell = asCell(baseValue);
@@ -2661,7 +2381,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
 
                 RefPtr<Structure>* it = vPC[6].u.structureChain->head();
 
-                JSValuePtr proto = baseObject->structure()->prototypeForLookup(callFrame);
+                JSValue proto = baseObject->structure()->prototypeForLookup(callFrame);
                 while (!proto.isNull()) {
                     if (UNLIKELY(asObject(proto)->structure() != (*it).get())) {
                         uncachePutByID(callFrame->codeBlock(), vPC);
@@ -2676,7 +2396,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
                 int value = vPC[3].u.operand;
                 unsigned offset = vPC[7].u.operand;
                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset);
-                baseObject->putDirectOffset(offset, callFrame[value].jsValue(callFrame));
+                baseObject->putDirectOffset(offset, callFrame->r(value).jsValue());
 
                 vPC += 8;
                 NEXT_INSTRUCTION();
@@ -2698,7 +2418,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            the register file.
         */
         int base = vPC[1].u.operand;
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
 
         if (LIKELY(baseValue.isCell())) {
             JSCell* baseCell = asCell(baseValue);
@@ -2711,7 +2431,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
                 unsigned offset = vPC[5].u.operand;
                 
                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifier(vPC[2].u.operand))) == offset);
-                baseObject->putDirectOffset(offset, callFrame[value].jsValue(callFrame));
+                baseObject->putDirectOffset(offset, callFrame->r(value).jsValue());
 
                 vPC += 8;
                 NEXT_INSTRUCTION();
@@ -2734,10 +2454,10 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int property = vPC[2].u.operand;
         int value = vPC[3].u.operand;
 
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
         Identifier& ident = callFrame->codeBlock()->identifier(property);
         PutPropertySlot slot;
-        baseValue.put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
+        baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
         CHECK_FOR_EXCEPTION();
 
         vPC += 8;
@@ -2755,11 +2475,11 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int base = (++vPC)->u.operand;
         int property = (++vPC)->u.operand;
 
-        JSObject* baseObj = callFrame[base].jsValue(callFrame).toObject(callFrame);
+        JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame);
         Identifier& ident = callFrame->codeBlock()->identifier(property);
-        JSValuePtr result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
+        JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
         CHECK_FOR_EXCEPTION();
-        callFrame[dst] = result;
+        callFrame->r(dst) = result;
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -2775,22 +2495,22 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int base = (++vPC)->u.operand;
         int property = (++vPC)->u.operand;
         
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
-        JSValuePtr subscript = callFrame[property].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
+        JSValue subscript = callFrame->r(property).jsValue();
 
-        JSValuePtr result;
+        JSValue result;
 
-        if (LIKELY(subscript.isUInt32Fast())) {
-            uint32_t i = subscript.getUInt32Fast();
-            if (isJSArray(baseValue)) {
+        if (LIKELY(subscript.isUInt32())) {
+            uint32_t i = subscript.asUInt32();
+            if (isJSArray(globalData, baseValue)) {
                 JSArray* jsArray = asArray(baseValue);
                 if (jsArray->canGetIndex(i))
                     result = jsArray->getIndex(i);
                 else
                     result = jsArray->JSArray::get(callFrame, i);
-            } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
+            } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
                 result = asString(baseValue)->getIndex(&callFrame->globalData(), i);
-            else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i))
+            else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i))
                 result = asByteArray(baseValue)->getIndex(callFrame, i);
             else
                 result = baseValue.get(callFrame, i);
@@ -2800,7 +2520,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         }
 
         CHECK_FOR_EXCEPTION();
-        callFrame[dst] = result;
+        callFrame->r(dst) = result;
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -2819,34 +2539,34 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int property = (++vPC)->u.operand;
         int value = (++vPC)->u.operand;
 
-        JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
-        JSValuePtr subscript = callFrame[property].jsValue(callFrame);
+        JSValue baseValue = callFrame->r(base).jsValue();
+        JSValue subscript = callFrame->r(property).jsValue();
 
-        if (LIKELY(subscript.isUInt32Fast())) {
-            uint32_t i = subscript.getUInt32Fast();
-            if (isJSArray(baseValue)) {
+        if (LIKELY(subscript.isUInt32())) {
+            uint32_t i = subscript.asUInt32();
+            if (isJSArray(globalData, baseValue)) {
                 JSArray* jsArray = asArray(baseValue);
                 if (jsArray->canSetIndex(i))
-                    jsArray->setIndex(i, callFrame[value].jsValue(callFrame));
+                    jsArray->setIndex(i, callFrame->r(value).jsValue());
                 else
-                    jsArray->JSArray::put(callFrame, i, callFrame[value].jsValue(callFrame));
-            } else if (isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+                    jsArray->JSArray::put(callFrame, i, callFrame->r(value).jsValue());
+            } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
                 JSByteArray* jsByteArray = asByteArray(baseValue);
                 double dValue = 0;
-                JSValuePtr jsValue = callFrame[value].jsValue(callFrame);
-                if (jsValue.isInt32Fast())
-                    jsByteArray->setIndex(i, jsValue.getInt32Fast());
+                JSValue jsValue = callFrame->r(value).jsValue();
+                if (jsValue.isInt32())
+                    jsByteArray->setIndex(i, jsValue.asInt32());
                 else if (jsValue.getNumber(dValue))
                     jsByteArray->setIndex(i, dValue);
                 else
                     baseValue.put(callFrame, i, jsValue);
             } else
-                baseValue.put(callFrame, i, callFrame[value].jsValue(callFrame));
+                baseValue.put(callFrame, i, callFrame->r(value).jsValue());
         } else {
             Identifier property(callFrame, subscript.toString(callFrame));
             if (!globalData->exception) { // Don't put to an object if toString threw an exception.
                 PutPropertySlot slot;
-                baseValue.put(callFrame, property, callFrame[value].jsValue(callFrame), slot);
+                baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot);
             }
         }
 
@@ -2866,10 +2586,10 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int base = (++vPC)->u.operand;
         int property = (++vPC)->u.operand;
 
-        JSObject* baseObj = callFrame[base].jsValue(callFrame).toObject(callFrame); // may throw
+        JSObject* baseObj = callFrame->r(base).jsValue().toObject(callFrame); // may throw
 
-        JSValuePtr subscript = callFrame[property].jsValue(callFrame);
-        JSValuePtr result;
+        JSValue subscript = callFrame->r(property).jsValue();
+        JSValue result;
         uint32_t i;
         if (subscript.getUInt32(i))
             result = jsBoolean(baseObj->deleteProperty(callFrame, i));
@@ -2881,7 +2601,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         }
 
         CHECK_FOR_EXCEPTION();
-        callFrame[dst] = result;
+        callFrame->r(dst) = result;
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -2901,7 +2621,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         unsigned property = (++vPC)->u.operand;
         int value = (++vPC)->u.operand;
 
-        callFrame[base].jsValue(callFrame).put(callFrame, property, callFrame[value].jsValue(callFrame));
+        callFrame->r(base).jsValue().put(callFrame, property, callFrame->r(value).jsValue());
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -2948,7 +2668,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
          */
         int cond = (++vPC)->u.operand;
         int target = (++vPC)->u.operand;
-        if (callFrame[cond].jsValue(callFrame).toBoolean(callFrame)) {
+        if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
             vPC += target;
             CHECK_FOR_TIMEOUT();
             NEXT_INSTRUCTION();
@@ -2965,7 +2685,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int cond = (++vPC)->u.operand;
         int target = (++vPC)->u.operand;
-        if (callFrame[cond].jsValue(callFrame).toBoolean(callFrame)) {
+        if (callFrame->r(cond).jsValue().toBoolean(callFrame)) {
             vPC += target;
             NEXT_INSTRUCTION();
         }
@@ -2981,7 +2701,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int cond = (++vPC)->u.operand;
         int target = (++vPC)->u.operand;
-        if (!callFrame[cond].jsValue(callFrame).toBoolean(callFrame)) {
+        if (!callFrame->r(cond).jsValue().toBoolean(callFrame)) {
             vPC += target;
             NEXT_INSTRUCTION();
         }
@@ -2997,7 +2717,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int src = (++vPC)->u.operand;
         int target = (++vPC)->u.operand;
-        JSValuePtr srcValue = callFrame[src].jsValue(callFrame);
+        JSValue srcValue = callFrame->r(src).jsValue();
 
         if (srcValue.isUndefinedOrNull() || (srcValue.isCell() && srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
             vPC += target;
@@ -3015,7 +2735,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int src = (++vPC)->u.operand;
         int target = (++vPC)->u.operand;
-        JSValuePtr srcValue = callFrame[src].jsValue(callFrame);
+        JSValue srcValue = callFrame->r(src).jsValue();
 
         if (!srcValue.isUndefinedOrNull() || (srcValue.isCell() && !srcValue.asCell()->structure()->typeInfo().masqueradesAsUndefined())) {
             vPC += target;
@@ -3025,6 +2745,24 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         ++vPC;
         NEXT_INSTRUCTION();
     }
+    DEFINE_OPCODE(op_jneq_ptr) {
+        /* jneq_ptr src(r) ptr(jsCell) target(offset)
+         
+           Jumps to offset target from the current instruction, if the value r is equal
+           to ptr, using pointer equality.
+         */
+        int src = (++vPC)->u.operand;
+        JSValue ptr = JSValue((++vPC)->u.jsCell);
+        int target = (++vPC)->u.operand;
+        JSValue srcValue = callFrame->r(src).jsValue();
+        if (srcValue != ptr) {
+            vPC += target;
+            NEXT_INSTRUCTION();
+        }
+
+        ++vPC;
+        NEXT_INSTRUCTION();
+    }
     DEFINE_OPCODE(op_loop_if_less) {
         /* loop_if_less src1(r) src2(r) target(offset)
 
@@ -3036,8 +2774,8 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            Additionally this loop instruction may terminate JS execution is
            the JS timeout is reached.
          */
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
         int target = (++vPC)->u.operand;
         
         bool result = jsLess(callFrame, src1, src2);
@@ -3063,8 +2801,8 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            Additionally this loop instruction may terminate JS execution is
            the JS timeout is reached.
         */
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
         int target = (++vPC)->u.operand;
         
         bool result = jsLessEq(callFrame, src1, src2);
@@ -3087,8 +2825,8 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            target from the current instruction, if and only if the 
            result of the comparison is false.
         */
-        JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
         int target = (++vPC)->u.operand;
 
         bool result = jsLess(callFrame, src1, src2);
@@ -3102,6 +2840,29 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         ++vPC;
         NEXT_INSTRUCTION();
     }
+    DEFINE_OPCODE(op_jnlesseq) {
+        /* jnlesseq src1(r) src2(r) target(offset)
+
+           Checks whether register src1 is less than or equal to
+           register src2, as with the ECMAScript '<=' operator,
+           and then jumps to offset target from the current instruction,
+           if and only if theresult of the comparison is false.
+        */
+        JSValue src1 = callFrame->r((++vPC)->u.operand).jsValue();
+        JSValue src2 = callFrame->r((++vPC)->u.operand).jsValue();
+        int target = (++vPC)->u.operand;
+
+        bool result = jsLessEq(callFrame, src1, src2);
+        CHECK_FOR_EXCEPTION();
+        
+        if (!result) {
+            vPC += target;
+            NEXT_INSTRUCTION();
+        }
+
+        ++vPC;
+        NEXT_INSTRUCTION();
+    }
     DEFINE_OPCODE(op_switch_imm) {
         /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)
 
@@ -3113,13 +2874,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
          */
         int tableIndex = (++vPC)->u.operand;
         int defaultOffset = (++vPC)->u.operand;
-        JSValuePtr scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
-        if (scrutinee.isInt32Fast())
-            vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.getInt32Fast(), defaultOffset);
+        JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
+        if (scrutinee.isInt32())
+            vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(scrutinee.asInt32(), defaultOffset);
         else {
-            int32_t value;
-            if (scrutinee.numberToInt32(value))
-                vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(value, defaultOffset);
+            double value;
+            int32_t intValue;
+            if (scrutinee.getNumber(value) && ((intValue = static_cast<int32_t>(value)) == value))
+                vPC += callFrame->codeBlock()->immediateSwitchJumpTable(tableIndex).offsetForValue(intValue, defaultOffset);
             else
                 vPC += defaultOffset;
         }
@@ -3136,7 +2898,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
          */
         int tableIndex = (++vPC)->u.operand;
         int defaultOffset = (++vPC)->u.operand;
-        JSValuePtr scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+        JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
         if (!scrutinee.isString())
             vPC += defaultOffset;
         else {
@@ -3159,7 +2921,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
          */
         int tableIndex = (++vPC)->u.operand;
         int defaultOffset = (++vPC)->u.operand;
-        JSValuePtr scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
+        JSValue scrutinee = callFrame->r((++vPC)->u.operand).jsValue();
         if (!scrutinee.isString())
             vPC += defaultOffset;
         else 
@@ -3177,7 +2939,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int dst = (++vPC)->u.operand;
         int func = (++vPC)->u.operand;
 
-        callFrame[dst] = callFrame->codeBlock()->function(func)->makeFunction(callFrame, callFrame->scopeChain());
+        callFrame->r(dst) = JSValue(callFrame->codeBlock()->function(func)->makeFunction(callFrame, callFrame->scopeChain()));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -3193,7 +2955,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int dst = (++vPC)->u.operand;
         int func = (++vPC)->u.operand;
 
-        callFrame[dst] = callFrame->codeBlock()->functionExpression(func)->makeFunction(callFrame, callFrame->scopeChain());
+        callFrame->r(dst) = JSValue(callFrame->codeBlock()->functionExpression(func)->makeFunction(callFrame, callFrame->scopeChain()));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -3215,18 +2977,18 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int argCount = vPC[3].u.operand;
         int registerOffset = vPC[4].u.operand;
 
-        JSValuePtr funcVal = callFrame[func].jsValue(callFrame);
+        JSValue funcVal = callFrame->r(func).jsValue();
 
         Register* newCallFrame = callFrame->registers() + registerOffset;
         Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
-        JSValuePtr thisValue = argv[0].jsValue(callFrame);
+        JSValue thisValue = argv[0].jsValue();
         JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
 
         if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
-            JSValuePtr result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
+            JSValue result = callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
             if (exceptionValue)
                 goto vm_throw;
-            callFrame[dst] = result;
+            callFrame->r(dst) = result;
 
             vPC += 5;
             NEXT_INSTRUCTION();
@@ -3252,7 +3014,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int argCount = vPC[3].u.operand;
         int registerOffset = vPC[4].u.operand;
 
-        JSValuePtr v = callFrame[func].jsValue(callFrame);
+        JSValue v = callFrame->r(func).jsValue();
 
         CallData callData;
         CallType callType = v.getCallData(callData);
@@ -3290,18 +3052,18 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
             ArgList args(thisRegister + 1, argCount - 1);
 
             // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
-            JSValuePtr thisValue = thisRegister->jsValue(callFrame);
+            JSValue thisValue = thisRegister->jsValue();
             if (thisValue == jsNull())
                 thisValue = callFrame->globalThisValue();
 
-            JSValuePtr returnValue;
+            JSValue returnValue;
             {
                 SamplingTool::HostCallRecord callRecord(m_sampler);
                 returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
             }
             CHECK_FOR_EXCEPTION();
 
-            callFrame[dst] = JSValuePtr(returnValue);
+            callFrame->r(dst) = returnValue;
 
             vPC += 5;
             NEXT_INSTRUCTION();
@@ -3312,6 +3074,160 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         exceptionValue = createNotAFunctionError(callFrame, v, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock());
         goto vm_throw;
     }
+    DEFINE_OPCODE(op_load_varargs) {
+        int argCountDst = (++vPC)->u.operand;
+        int argsOffset = (++vPC)->u.operand;
+        
+        JSValue arguments = callFrame->r(argsOffset).jsValue();
+        int32_t argCount = 0;
+        if (!arguments) {
+            argCount = (uint32_t)(callFrame->argumentCount()) - 1;
+            int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
+            Register* newEnd = callFrame->registers() + sizeDelta;
+            if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
+                exceptionValue = createStackOverflowError(callFrame);
+                goto vm_throw;
+            }
+            int32_t expectedParams = callFrame->callee()->body()->parameterCount();
+            int32_t inplaceArgs = min(argCount, expectedParams);
+            int32_t i = 0;
+            Register* argStore = callFrame->registers() + argsOffset;
+
+            // First step is to copy the "expected" parameters from their normal location relative to the callframe
+            for (; i < inplaceArgs; i++)
+                argStore[i] = callFrame->registers()[i - RegisterFile::CallFrameHeaderSize - expectedParams];
+            // Then we copy any additional arguments that may be further up the stack ('-1' to account for 'this')
+            for (; i < argCount; i++)
+                argStore[i] = callFrame->registers()[i - RegisterFile::CallFrameHeaderSize - expectedParams - argCount - 1];
+        } else if (!arguments.isUndefinedOrNull()) {
+            if (!arguments.isObject()) {
+                exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock());
+                goto vm_throw;
+            }
+            if (asObject(arguments)->classInfo() == &Arguments::info) {
+                Arguments* args = asArguments(arguments);
+                argCount = args->numProvidedArguments(callFrame);
+                int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
+                Register* newEnd = callFrame->registers() + sizeDelta;
+                if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
+                    exceptionValue = createStackOverflowError(callFrame);
+                    goto vm_throw;
+                }
+                args->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount);
+            } else if (isJSArray(&callFrame->globalData(), arguments)) {
+                JSArray* array = asArray(arguments);
+                argCount = array->length();
+                int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
+                Register* newEnd = callFrame->registers() + sizeDelta;
+                if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
+                    exceptionValue = createStackOverflowError(callFrame);
+                    goto vm_throw;
+                }
+                array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount);
+            } else if (asObject(arguments)->inherits(&JSArray::info)) {
+                JSObject* argObject = asObject(arguments);
+                argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+                int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
+                Register* newEnd = callFrame->registers() + sizeDelta;
+                if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
+                    exceptionValue = createStackOverflowError(callFrame);
+                    goto vm_throw;
+                }
+                Register* argsBuffer = callFrame->registers() + argsOffset;
+                for (int32_t i = 0; i < argCount; ++i) {
+                    argsBuffer[i] = asObject(arguments)->get(callFrame, i);
+                    CHECK_FOR_EXCEPTION();
+                }
+            } else {
+                if (!arguments.isObject()) {
+                    exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock());
+                    goto vm_throw;
+                }
+            }
+        }
+        CHECK_FOR_EXCEPTION();
+        callFrame->r(argCountDst) = Register::withInt(argCount + 1);
+        ++vPC;
+        NEXT_INSTRUCTION();
+    }
+    DEFINE_OPCODE(op_call_varargs) {
+        /* call_varargs dst(r) func(r) argCountReg(r) baseRegisterOffset(n)
+         
+         Perform a function call with a dynamic set of arguments.
+         
+         registerOffset is the distance the callFrame pointer should move
+         before the VM initializes the new call frame's header, excluding
+         space for arguments.
+         
+         dst is where op_ret should store its result.
+         */
+        
+        int dst = vPC[1].u.operand;
+        int func = vPC[2].u.operand;
+        int argCountReg = vPC[3].u.operand;
+        int registerOffset = vPC[4].u.operand;
+        
+        JSValue v = callFrame->r(func).jsValue();
+        int argCount = callFrame->r(argCountReg).i();
+        registerOffset += argCount;
+        CallData callData;
+        CallType callType = v.getCallData(callData);
+        
+        if (callType == CallTypeJS) {
+            ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
+            FunctionBodyNode* functionBodyNode = callData.js.functionBody;
+            CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
+            
+            CallFrame* previousCallFrame = callFrame;
+            
+            callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
+            if (UNLIKELY(!callFrame)) {
+                callFrame = previousCallFrame;
+                exceptionValue = createStackOverflowError(callFrame);
+                goto vm_throw;
+            }
+            
+            callFrame->init(newCodeBlock, vPC + 5, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
+            vPC = newCodeBlock->instructions().begin();
+            
+#if ENABLE(OPCODE_STATS)
+            OpcodeStats::resetLastInstruction();
+#endif
+            
+            NEXT_INSTRUCTION();
+        }
+        
+        if (callType == CallTypeHost) {
+            ScopeChainNode* scopeChain = callFrame->scopeChain();
+            CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
+            newCallFrame->init(0, vPC + 5, scopeChain, callFrame, dst, argCount, 0);
+            
+            Register* thisRegister = newCallFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
+            ArgList args(thisRegister + 1, argCount - 1);
+            
+            // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
+            JSValue thisValue = thisRegister->jsValue();
+            if (thisValue == jsNull())
+                thisValue = callFrame->globalThisValue();
+            
+            JSValue returnValue;
+            {
+                SamplingTool::HostCallRecord callRecord(m_sampler);
+                returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
+            }
+            CHECK_FOR_EXCEPTION();
+            
+            callFrame->r(dst) = returnValue;
+            
+            vPC += 5;
+            NEXT_INSTRUCTION();
+        }
+        
+        ASSERT(callType == CallTypeNone);
+        
+        exceptionValue = createNotAFunctionError(callFrame, v, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock());
+        goto vm_throw;
+    }
     DEFINE_OPCODE(op_tear_off_activation) {
         /* tear_off_activation activation(r)
 
@@ -3328,7 +3244,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int src = (++vPC)->u.operand;
         ASSERT(callFrame->codeBlock()->needsFullScopeChain());
 
-        asActivation(callFrame[src].getJSValue())->copyRegisters(callFrame->optionalCalleeArguments());
+        asActivation(callFrame->r(src).jsValue())->copyRegisters(callFrame->optionalCalleeArguments());
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -3348,7 +3264,8 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
 
         ASSERT(callFrame->codeBlock()->usesArguments() && !callFrame->codeBlock()->needsFullScopeChain());
 
-        callFrame->optionalCalleeArguments()->copyRegisters();
+        if (callFrame->optionalCalleeArguments())
+            callFrame->optionalCalleeArguments()->copyRegisters();
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -3368,7 +3285,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         if (callFrame->codeBlock()->needsFullScopeChain())
             callFrame->scopeChain()->deref();
 
-        JSValuePtr returnValue = callFrame[result].jsValue(callFrame);
+        JSValue returnValue = callFrame->r(result).jsValue();
 
         vPC = callFrame->returnPC();
         int dst = callFrame->returnValueRegister();
@@ -3377,7 +3294,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         if (callFrame->hasHostCallFrameFlag())
             return returnValue;
 
-        callFrame[dst] = JSValuePtr(returnValue);
+        callFrame->r(dst) = returnValue;
 
         NEXT_INSTRUCTION();
     }
@@ -3396,10 +3313,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         CodeBlock* codeBlock = callFrame->codeBlock();
         
         for (size_t count = codeBlock->m_numVars; i < count; ++i)
-            callFrame[i] = jsUndefined();
-
-        for (size_t count = codeBlock->numberOfConstantRegisters(), j = 0; j < count; ++i, ++j)
-            callFrame[i] = codeBlock->constantRegister(j);
+            callFrame->r(i) = jsUndefined();
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -3421,14 +3335,11 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         CodeBlock* codeBlock = callFrame->codeBlock();
 
         for (size_t count = codeBlock->m_numVars; i < count; ++i)
-            callFrame[i] = jsUndefined();
-
-        for (size_t count = codeBlock->numberOfConstantRegisters(), j = 0; j < count; ++i, ++j)
-            callFrame[i] = codeBlock->constantRegister(j);
+            callFrame->r(i) = jsUndefined();
 
         int dst = (++vPC)->u.operand;
         JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionBodyNode*>(codeBlock->ownerNode()));
-        callFrame[dst] = activation;
+        callFrame->r(dst) = JSValue(activation);
         callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
 
         ++vPC;
@@ -3447,28 +3358,40 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
 
         int thisRegister = (++vPC)->u.operand;
-        JSValuePtr thisVal = callFrame[thisRegister].getJSValue();
+        JSValue thisVal = callFrame->r(thisRegister).jsValue();
         if (thisVal.needsThisConversion())
-            callFrame[thisRegister] = JSValuePtr(thisVal.toThisObject(callFrame));
+            callFrame->r(thisRegister) = JSValue(thisVal.toThisObject(callFrame));
 
         ++vPC;
         NEXT_INSTRUCTION();
     }
-    DEFINE_OPCODE(op_create_arguments) {
+    DEFINE_OPCODE(op_init_arguments) {
         /* create_arguments
 
-           Creates the 'arguments' object and places it in both the
-           'arguments' call frame slot and the local 'arguments'
-           register.
+           Initialises the arguments object reference to null to ensure
+           we can correctly detect that we need to create it later (or
+           avoid creating it altogether).
 
            This opcode should only be used at the beginning of a code
            block.
-        */
+         */
+        callFrame->r(RegisterFile::ArgumentsRegister) = JSValue();
+        ++vPC;
+        NEXT_INSTRUCTION();
+    }
+    DEFINE_OPCODE(op_create_arguments) {
+        /* create_arguments
 
-        Arguments* arguments = new (globalData) Arguments(callFrame);
-        callFrame->setCalleeArguments(arguments);
-        callFrame[RegisterFile::ArgumentsRegister] = arguments;
+           Creates the 'arguments' object and places it in both the
+           'arguments' call frame slot and the local 'arguments'
+           register, if it has not already been initialised.
+         */
         
+         if (!callFrame->r(RegisterFile::ArgumentsRegister).jsValue()) {
+             Arguments* arguments = new (globalData) Arguments(callFrame);
+             callFrame->setCalleeArguments(arguments);
+             callFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments);
+         }
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -3494,7 +3417,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int proto = vPC[5].u.operand;
         int thisRegister = vPC[6].u.operand;
 
-        JSValuePtr v = callFrame[func].jsValue(callFrame);
+        JSValue v = callFrame->r(func).jsValue();
 
         ConstructData constructData;
         ConstructType constructType = v.getConstructData(constructData);
@@ -3505,14 +3428,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
             CodeBlock* newCodeBlock = &functionBodyNode->bytecode(callDataScopeChain);
 
             Structure* structure;
-            JSValuePtr prototype = callFrame[proto].jsValue(callFrame);
+            JSValue prototype = callFrame->r(proto).jsValue();
             if (prototype.isObject())
                 structure = asObject(prototype)->inheritorID();
             else
                 structure = callDataScopeChain->globalObject()->emptyObjectStructure();
             JSObject* newObject = new (globalData) JSObject(structure);
 
-            callFrame[thisRegister] = JSValuePtr(newObject); // "this" value
+            callFrame->r(thisRegister) = JSValue(newObject); // "this" value
 
             CallFrame* previousCallFrame = callFrame;
 
@@ -3540,13 +3463,13 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
             CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
             newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
 
-            JSValuePtr returnValue;
+            JSValue returnValue;
             {
                 SamplingTool::HostCallRecord callRecord(m_sampler);
                 returnValue = constructData.native.function(newCallFrame, asObject(v), args);
             }
             CHECK_FOR_EXCEPTION();
-            callFrame[dst] = JSValuePtr(returnValue);
+            callFrame->r(dst) = JSValue(returnValue);
 
             vPC += 7;
             NEXT_INSTRUCTION();
@@ -3564,18 +3487,37 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            the object in register override to register dst.
         */
 
-        int dst = vPC[1].u.operand;;
-        if (LIKELY(callFrame[dst].jsValue(callFrame).isObject())) {
+        int dst = vPC[1].u.operand;
+        if (LIKELY(callFrame->r(dst).jsValue().isObject())) {
             vPC += 3;
             NEXT_INSTRUCTION();
         }
 
         int override = vPC[2].u.operand;
-        callFrame[dst] = callFrame[override];
+        callFrame->r(dst) = callFrame->r(override);
 
         vPC += 3;
         NEXT_INSTRUCTION();
     }
+    DEFINE_OPCODE(op_strcat) {
+        int dst = (++vPC)->u.operand;
+        int src = (++vPC)->u.operand;
+        int count = (++vPC)->u.operand;
+
+        callFrame->r(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count);
+        ++vPC;
+
+        NEXT_INSTRUCTION();
+    }
+    DEFINE_OPCODE(op_to_primitive) {
+        int dst = (++vPC)->u.operand;
+        int src = (++vPC)->u.operand;
+
+        callFrame->r(dst) = callFrame->r(src).jsValue().toPrimitive(callFrame);
+        ++vPC;
+
+        NEXT_INSTRUCTION();
+    }
     DEFINE_OPCODE(op_push_scope) {
         /* push_scope scope(r)
 
@@ -3584,11 +3526,11 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
            are replaced by the result of toObject conversion of the scope.
         */
         int scope = (++vPC)->u.operand;
-        JSValuePtr v = callFrame[scope].jsValue(callFrame);
+        JSValue v = callFrame->r(scope).jsValue();
         JSObject* o = v.toObject(callFrame);
         CHECK_FOR_EXCEPTION();
 
-        callFrame[scope] = JSValuePtr(o);
+        callFrame->r(scope) = JSValue(o);
         callFrame->setScopeChain(callFrame->scopeChain()->push(o));
 
         ++vPC;
@@ -3615,7 +3557,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int dst = (++vPC)->u.operand;
         int base = (++vPC)->u.operand;
 
-        callFrame[dst] = JSPropertyNameIterator::create(callFrame, callFrame[base].jsValue(callFrame));
+        callFrame->r(dst) = JSPropertyNameIterator::create(callFrame, callFrame->r(base).jsValue());
         ++vPC;
         NEXT_INSTRUCTION();
     }
@@ -3632,10 +3574,10 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int iter = (++vPC)->u.operand;
         int target = (++vPC)->u.operand;
 
-        JSPropertyNameIterator* it = callFrame[iter].propertyNameIterator();
-        if (JSValuePtr temp = it->next(callFrame)) {
+        JSPropertyNameIterator* it = callFrame->r(iter).propertyNameIterator();
+        if (JSValue temp = it->next(callFrame)) {
             CHECK_FOR_TIMEOUT();
-            callFrame[dst] = JSValuePtr(temp);
+            callFrame->r(dst) = JSValue(temp);
             vPC += target;
             NEXT_INSTRUCTION();
         }
@@ -3684,15 +3626,15 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
     DEFINE_OPCODE(op_catch) {
         /* catch ex(r)
 
-           Retrieves the VMs current exception and puts it in register
+           Retrieves the VM's current exception and puts it in register
            ex. This is only valid after an exception has been raised,
            and usually forms the beginning of an exception handler.
         */
         ASSERT(exceptionValue);
         ASSERT(!globalData->exception);
         int ex = (++vPC)->u.operand;
-        callFrame[ex] = exceptionValue;
-        exceptionValue = noValue();
+        callFrame->r(ex) = exceptionValue;
+        exceptionValue = JSValue();
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -3709,7 +3651,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
 
         int ex = (++vPC)->u.operand;
-        exceptionValue = callFrame[ex].jsValue(callFrame);
+        exceptionValue = callFrame->r(ex).jsValue();
 
         handler = throwException(callFrame, exceptionValue, vPC - callFrame->codeBlock()->instructions().begin(), true);
         if (!handler) {
@@ -3720,18 +3662,6 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         vPC = callFrame->codeBlock()->instructions().begin() + handler->target;
         NEXT_INSTRUCTION();
     }
-    DEFINE_OPCODE(op_unexpected_load) {
-        /* unexpected_load load dst(r) src(k)
-
-           Copies constant src to register dst.
-        */
-        int dst = (++vPC)->u.operand;
-        int src = (++vPC)->u.operand;
-        callFrame[dst] = JSValuePtr(callFrame->codeBlock()->unexpectedConstant(src));
-
-        ++vPC;
-        NEXT_INSTRUCTION();
-    }
     DEFINE_OPCODE(op_new_error) {
         /* new_error dst(r) type(n) message(k)
 
@@ -3745,7 +3675,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int message = (++vPC)->u.operand;
 
         CodeBlock* codeBlock = callFrame->codeBlock();
-        callFrame[dst] = JSValuePtr(Error::create(callFrame, (ErrorType)type, codeBlock->unexpectedConstant(message).toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()));
+        callFrame->r(dst) = JSValue(Error::create(callFrame, (ErrorType)type, callFrame->r(message).jsValue().toString(callFrame), codeBlock->lineNumberForBytecodeOffset(callFrame, vPC - codeBlock->instructions().begin()), codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL()));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -3763,7 +3693,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
             scopeChain->deref();
         }
         int result = (++vPC)->u.operand;
-        return callFrame[result].jsValue(callFrame);
+        return callFrame->r(result).jsValue();
     }
     DEFINE_OPCODE(op_put_getter) {
         /* put_getter base(r) property(id) function(r)
@@ -3780,11 +3710,11 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int property = (++vPC)->u.operand;
         int function = (++vPC)->u.operand;
 
-        ASSERT(callFrame[base].jsValue(callFrame).isObject());
-        JSObject* baseObj = asObject(callFrame[base].jsValue(callFrame));
+        ASSERT(callFrame->r(base).jsValue().isObject());
+        JSObject* baseObj = asObject(callFrame->r(base).jsValue());
         Identifier& ident = callFrame->codeBlock()->identifier(property);
-        ASSERT(callFrame[function].jsValue(callFrame).isObject());
-        baseObj->defineGetter(callFrame, ident, asObject(callFrame[function].jsValue(callFrame)));
+        ASSERT(callFrame->r(function).jsValue().isObject());
+        baseObj->defineGetter(callFrame, ident, asObject(callFrame->r(function).jsValue()));
 
         ++vPC;
         NEXT_INSTRUCTION();
@@ -3804,15 +3734,19 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int property = (++vPC)->u.operand;
         int function = (++vPC)->u.operand;
 
-        ASSERT(callFrame[base].jsValue(callFrame).isObject());
-        JSObject* baseObj = asObject(callFrame[base].jsValue(callFrame));
+        ASSERT(callFrame->r(base).jsValue().isObject());
+        JSObject* baseObj = asObject(callFrame->r(base).jsValue());
         Identifier& ident = callFrame->codeBlock()->identifier(property);
-        ASSERT(callFrame[function].jsValue(callFrame).isObject());
-        baseObj->defineSetter(callFrame, ident, asObject(callFrame[function].jsValue(callFrame)));
+        ASSERT(callFrame->r(function).jsValue().isObject());
+        baseObj->defineSetter(callFrame, ident, asObject(callFrame->r(function).jsValue()));
 
         ++vPC;
         NEXT_INSTRUCTION();
     }
+    DEFINE_OPCODE(op_method_check) {
+        vPC++;
+        NEXT_INSTRUCTION();
+    }
     DEFINE_OPCODE(op_jsr) {
         /* jsr retAddrDst(r) target(offset)
 
@@ -3821,7 +3755,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         */
         int retAddrDst = (++vPC)->u.operand;
         int target = (++vPC)->u.operand;
-        callFrame[retAddrDst] = vPC + 1;
+        callFrame->r(retAddrDst) = vPC + 1;
 
         vPC += target;
         NEXT_INSTRUCTION();
@@ -3834,7 +3768,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
          register, not as an immediate.
         */
         int retAddrSrc = (++vPC)->u.operand;
-        vPC = callFrame[retAddrSrc].vPC();
+        vPC = callFrame->r(retAddrSrc).vPC();
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_debug) {
@@ -3861,7 +3795,7 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int function = vPC[1].u.operand;
 
         if (*enabledProfilerReference)
-            (*enabledProfilerReference)->willExecute(callFrame, callFrame[function].jsValue(callFrame));
+            (*enabledProfilerReference)->willExecute(callFrame, callFrame->r(function).jsValue());
 
         vPC += 2;
         NEXT_INSTRUCTION();
@@ -3875,13 +3809,13 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
         int function = vPC[1].u.operand;
 
         if (*enabledProfilerReference)
-            (*enabledProfilerReference)->didExecute(callFrame, callFrame[function].jsValue(callFrame));
+            (*enabledProfilerReference)->didExecute(callFrame, callFrame->r(function).jsValue());
 
         vPC += 2;
         NEXT_INSTRUCTION();
     }
     vm_throw: {
-        globalData->exception = noValue();
+        globalData->exception = JSValue();
         if (!tickCount) {
             // The exceptionValue is a lie! (GCC produces bad code for reasons I 
             // cannot fathom if we don't assign to the exceptionValue before branching)
@@ -3900,13 +3834,14 @@ JSValuePtr Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registe
 #if !HAVE(COMPUTED_GOTO)
     } // iterator loop ends
 #endif
+#endif // USE(INTERPRETER)
     #undef NEXT_INSTRUCTION
     #undef DEFINE_OPCODE
     #undef CHECK_FOR_EXCEPTION
     #undef CHECK_FOR_TIMEOUT
 }
 
-JSValuePtr Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* function) const
+JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* function) const
 {
     CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function);
     if (!functionCallFrame)
@@ -3917,7 +3852,12 @@ JSValuePtr Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* func
         ASSERT(codeBlock->codeType() == FunctionCode);
         SymbolTable& symbolTable = codeBlock->symbolTable();
         int argumentsIndex = symbolTable.get(functionCallFrame->propertyNames().arguments.ustring().rep()).getIndex();
-        return functionCallFrame[argumentsIndex].jsValue(callFrame);
+        if (!functionCallFrame->r(argumentsIndex).jsValue()) {
+            Arguments* arguments = new (callFrame) Arguments(functionCallFrame);
+            functionCallFrame->setCalleeArguments(arguments);
+            functionCallFrame->r(RegisterFile::ArgumentsRegister) = JSValue(arguments);
+        }
+        return functionCallFrame->r(argumentsIndex).jsValue();
     }
 
     Arguments* arguments = functionCallFrame->optionalCalleeArguments();
@@ -3930,7 +3870,7 @@ JSValuePtr Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* func
     return arguments;
 }
 
-JSValuePtr Interpreter::retrieveCaller(CallFrame* callFrame, InternalFunction* function) const
+JSValue Interpreter::retrieveCaller(CallFrame* callFrame, InternalFunction* function) const
 {
     CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function);
     if (!functionCallFrame)
@@ -3940,16 +3880,16 @@ JSValuePtr Interpreter::retrieveCaller(CallFrame* callFrame, InternalFunction* f
     if (callerFrame->hasHostCallFrameFlag())
         return jsNull();
 
-    JSValuePtr caller = callerFrame->callee();
+    JSValue caller = callerFrame->callee();
     if (!caller)
         return jsNull();
 
     return caller;
 }
 
-void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValuePtr& function) const
+void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const
 {
-    function = noValue();
+    function = JSValue();
     lineNumber = -1;
     sourceURL = UString();
 
@@ -3977,2113 +3917,4 @@ CallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, InternalFunc
     return 0;
 }
 
-#if ENABLE(JIT)
-
-#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
-
-NEVER_INLINE void Interpreter::tryCTICachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, void* returnAddress, JSValuePtr baseValue, const PutPropertySlot& slot)
-{
-    // The interpreter checks for recursion here; I do not believe this can occur in CTI.
-
-    if (!baseValue.isCell())
-        return;
-
-    // Uncacheable: give up.
-    if (!slot.isCacheable()) {
-        ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_put_by_id_generic));
-        return;
-    }
-    
-    JSCell* baseCell = asCell(baseValue);
-    Structure* structure = baseCell->structure();
-
-    if (structure->isDictionary()) {
-        ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_put_by_id_generic));
-        return;
-    }
-
-    // If baseCell != base, then baseCell must be a proxy for another object.
-    if (baseCell != slot.base()) {
-        ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_put_by_id_generic));
-        return;
-    }
-
-    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
-
-    // Cache hit: Specialize instruction and ref Structures.
-
-    // Structure transition, cache transition info
-    if (slot.type() == PutPropertySlot::NewProperty) {
-        StructureChain* prototypeChain = structure->prototypeChain(callFrame);
-        stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain);
-        JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress); 
-        return;
-    }
-    
-    stubInfo->initPutByIdReplace(structure);
-
-#if USE(CTI_REPATCH_PIC)
-    UNUSED_PARAM(callFrame);
-    JIT::patchPutByIdReplace(stubInfo, structure, slot.cachedOffset(), returnAddress);
-#else
-    JIT::compilePutByIdReplace(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
-#endif
-}
-
-NEVER_INLINE void Interpreter::tryCTICacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, void* returnAddress, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot& slot)
-{
-    // FIXME: Write a test that proves we need to check for recursion here just
-    // like the interpreter does, then add a check for recursion.
-
-    // FIXME: Cache property access for immediates.
-    if (!baseValue.isCell()) {
-        ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_get_by_id_generic));
-        return;
-    }
-
-    if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
-#if USE(CTI_REPATCH_PIC)
-        JIT::compilePatchGetArrayLength(callFrame->scopeChain()->globalData, codeBlock, returnAddress);
-#else
-        ctiPatchCallByReturnAddress(returnAddress, m_ctiArrayLengthTrampoline);
-#endif
-        return;
-    }
-    if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
-        // The tradeoff of compiling an patched inline string length access routine does not seem
-        // to pay off, so we currently only do this for arrays.
-        ctiPatchCallByReturnAddress(returnAddress, m_ctiStringLengthTrampoline);
-        return;
-    }
-
-    // Uncacheable: give up.
-    if (!slot.isCacheable()) {
-        ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_get_by_id_generic));
-        return;
-    }
-
-    JSCell* baseCell = asCell(baseValue);
-    Structure* structure = baseCell->structure();
-
-    if (structure->isDictionary()) {
-        ctiPatchCallByReturnAddress(returnAddress, reinterpret_cast<void*>(cti_op_get_by_id_generic));
-        return;
-    }
-
-    // In the interpreter the last structure is trapped here; in CTI we use the
-    // *_second method to achieve a similar (but not quite the same) effect.
-
-    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
-
-    // Cache hit: Specialize instruction and ref Structures.
-
-    if (slot.slotBase() == baseValue) {
-        // set this up, so derefStructures can do it's job.
-        stubInfo->initGetByIdSelf(structure);
-        
-#if USE(CTI_REPATCH_PIC)
-        JIT::patchGetByIdSelf(stubInfo, structure, slot.cachedOffset(), returnAddress);
-#else
-        JIT::compileGetByIdSelf(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
-#endif
-        return;
-    }
-
-    if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
-        ASSERT(slot.slotBase().isObject());
-
-        JSObject* slotBaseObject = asObject(slot.slotBase());
-
-        // Since we're accessing a prototype in a loop, it's a good bet that it
-        // should not be treated as a dictionary.
-        if (slotBaseObject->structure()->isDictionary()) 
-            slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure())); 
-
-        stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
-
-        JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), slot.cachedOffset(), returnAddress);
-        return;
-    }
-
-    size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot);
-    if (!count) {
-        stubInfo->opcodeID = op_get_by_id_generic;
-        return;
-    }
-
-    StructureChain* prototypeChain = structure->prototypeChain(callFrame); 
-    stubInfo->initGetByIdChain(structure, prototypeChain); 
-    JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, slot.cachedOffset(), returnAddress); 
-}
-
-#endif
-
-#if USE(JIT_STUB_ARGUMENT_VA_LIST)
-#define SETUP_VA_LISTL_ARGS va_list vl_args; va_start(vl_args, args)
-#else // JIT_STUB_ARGUMENT_REGISTER or JIT_STUB_ARGUMENT_STACK
-#define SETUP_VA_LISTL_ARGS
-#endif
-
-#ifndef NDEBUG
-
-extern "C" {
-
-static void jscGeneratedNativeCode() 
-{
-    // When executing a CTI function (which might do an allocation), we hack the return address
-    // to pretend to be executing this function, to keep stack logging tools from blowing out
-    // memory.
-}
-
-}
-
-struct StackHack {
-    ALWAYS_INLINE StackHack(void** location) 
-    { 
-        returnAddressLocation = location;
-        savedReturnAddress = *returnAddressLocation;
-        ctiSetReturnAddress(returnAddressLocation, reinterpret_cast<void*>(jscGeneratedNativeCode));
-    }
-    ALWAYS_INLINE ~StackHack() 
-    { 
-        ctiSetReturnAddress(returnAddressLocation, savedReturnAddress);
-    }
-
-    void** returnAddressLocation;
-    void* savedReturnAddress;
-};
-
-#define BEGIN_STUB_FUNCTION() SETUP_VA_LISTL_ARGS; StackHack stackHack(&STUB_RETURN_ADDRESS_SLOT)
-#define STUB_SET_RETURN_ADDRESS(address) stackHack.savedReturnAddress = address
-#define STUB_RETURN_ADDRESS stackHack.savedReturnAddress
-
-#else
-
-#define BEGIN_STUB_FUNCTION() SETUP_VA_LISTL_ARGS
-#define STUB_SET_RETURN_ADDRESS(address) ctiSetReturnAddress(&STUB_RETURN_ADDRESS_SLOT, address);
-#define STUB_RETURN_ADDRESS STUB_RETURN_ADDRESS_SLOT
-
-#endif
-
-// The reason this is not inlined is to avoid having to do a PIC branch
-// to get the address of the ctiVMThrowTrampoline function. It's also
-// good to keep the code size down by leaving as much of the exception
-// handling code out of line as possible.
-static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, void* exceptionLocation, void*& returnAddressSlot)
-{
-    ASSERT(globalData->exception);
-    globalData->exceptionLocation = exceptionLocation;
-    ctiSetReturnAddress(&returnAddressSlot, reinterpret_cast<void*>(ctiVMThrowTrampoline));
-}
-
-static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalData* globalData, void* exceptionLocation, void*& returnAddressSlot)
-{
-    globalData->exception = createStackOverflowError(callFrame);
-    returnToThrowTrampoline(globalData, exceptionLocation, returnAddressSlot);
-}
-
-#define VM_THROW_EXCEPTION() \
-    do { \
-        VM_THROW_EXCEPTION_AT_END(); \
-        return 0; \
-    } while (0)
-#define VM_THROW_EXCEPTION_2() \
-    do { \
-        VM_THROW_EXCEPTION_AT_END(); \
-        RETURN_PAIR(0, 0); \
-    } while (0)
-#define VM_THROW_EXCEPTION_AT_END() \
-    returnToThrowTrampoline(ARG_globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS)
-
-#define CHECK_FOR_EXCEPTION() \
-    do { \
-        if (UNLIKELY(ARG_globalData->exception != noValue())) \
-            VM_THROW_EXCEPTION(); \
-    } while (0)
-#define CHECK_FOR_EXCEPTION_AT_END() \
-    do { \
-        if (UNLIKELY(ARG_globalData->exception != noValue())) \
-            VM_THROW_EXCEPTION_AT_END(); \
-    } while (0)
-#define CHECK_FOR_EXCEPTION_VOID() \
-    do { \
-        if (UNLIKELY(ARG_globalData->exception != noValue())) { \
-            VM_THROW_EXCEPTION_AT_END(); \
-            return; \
-        } \
-    } while (0)
-
-JSObject* Interpreter::cti_op_convert_this(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr v1 = ARG_src1;
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSObject* result = v1.toThisObject(callFrame);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return result;
-}
-
-void Interpreter::cti_op_end(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    ScopeChainNode* scopeChain = ARG_callFrame->scopeChain();
-    ASSERT(scopeChain->refCount > 1);
-    scopeChain->deref();
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_add(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr v1 = ARG_src1;
-    JSValuePtr v2 = ARG_src2;
-
-    double left;
-    double right = 0.0;
-
-    bool rightIsNumber = v2.getNumber(right);
-    if (rightIsNumber && v1.getNumber(left))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, left + right));
-    
-    CallFrame* callFrame = ARG_callFrame;
-
-    bool leftIsString = v1.isString();
-    if (leftIsString && v2.isString()) {
-        RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
-        if (UNLIKELY(!value)) {
-            throwOutOfMemoryError(callFrame);
-            VM_THROW_EXCEPTION();
-        }
-
-        return JSValuePtr::encode(jsString(ARG_globalData, value.release()));
-    }
-
-    if (rightIsNumber & leftIsString) {
-        RefPtr<UString::Rep> value = v2.isInt32Fast() ?
-            concatenate(asString(v1)->value().rep(), v2.getInt32Fast()) :
-            concatenate(asString(v1)->value().rep(), right);
-
-        if (UNLIKELY(!value)) {
-            throwOutOfMemoryError(callFrame);
-            VM_THROW_EXCEPTION();
-        }
-        return JSValuePtr::encode(jsString(ARG_globalData, value.release()));
-    }
-
-    // All other cases are pretty uncommon
-    JSValuePtr result = jsAddSlowCase(callFrame, v1, v2);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_pre_inc(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr v = ARG_src1;
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, v.toNumber(callFrame) + 1);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-int Interpreter::cti_timeout_check(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-    Interpreter* interpreter = ARG_globalData->interpreter;
-
-    if (interpreter->checkTimeout(ARG_callFrame->dynamicGlobalObject())) {
-        ARG_globalData->exception = createInterruptedExecutionException(ARG_globalData);
-        VM_THROW_EXCEPTION_AT_END();
-    }
-    
-    return interpreter->m_ticksUntilNextTimeoutCheck;
-}
-
-void Interpreter::cti_register_file_check(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    if (LIKELY(ARG_registerFile->grow(ARG_callFrame + ARG_callFrame->codeBlock()->m_numCalleeRegisters)))
-        return;
-
-    // Rewind to the previous call frame because op_call already optimistically
-    // moved the call frame forward.
-    CallFrame* oldCallFrame = ARG_callFrame->callerFrame();
-    ARG_setCallFrame(oldCallFrame);
-    throwStackOverflowError(oldCallFrame, ARG_globalData, oldCallFrame->returnPC(), STUB_RETURN_ADDRESS);
-}
-
-int Interpreter::cti_op_loop_if_less(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-    CallFrame* callFrame = ARG_callFrame;
-
-    bool result = jsLess(callFrame, src1, src2);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return result;
-}
-
-int Interpreter::cti_op_loop_if_lesseq(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-    CallFrame* callFrame = ARG_callFrame;
-
-    bool result = jsLessEq(callFrame, src1, src2);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return result;
-}
-
-JSObject* Interpreter::cti_op_new_object(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return constructEmptyObject(ARG_callFrame);
-}
-
-void Interpreter::cti_op_put_by_id_generic(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    PutPropertySlot slot;
-    ARG_src1.put(ARG_callFrame, *ARG_id2, ARG_src3, slot);
-    CHECK_FOR_EXCEPTION_AT_END();
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_generic(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    Identifier& ident = *ARG_id2;
-
-    JSValuePtr baseValue = ARG_src1;
-    PropertySlot slot(baseValue);
-    JSValuePtr result = baseValue.get(callFrame, ident, slot);
-
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
-
-void Interpreter::cti_op_put_by_id(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    Identifier& ident = *ARG_id2;
-
-    PutPropertySlot slot;
-    ARG_src1.put(callFrame, ident, ARG_src3, slot);
-
-    ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_id_second));
-
-    CHECK_FOR_EXCEPTION_AT_END();
-}
-
-void Interpreter::cti_op_put_by_id_second(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    PutPropertySlot slot;
-    ARG_src1.put(ARG_callFrame, *ARG_id2, ARG_src3, slot);
-    ARG_globalData->interpreter->tryCTICachePutByID(ARG_callFrame, ARG_callFrame->codeBlock(), STUB_RETURN_ADDRESS, ARG_src1, slot);
-    CHECK_FOR_EXCEPTION_AT_END();
-}
-
-void Interpreter::cti_op_put_by_id_fail(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    Identifier& ident = *ARG_id2;
-
-    PutPropertySlot slot;
-    ARG_src1.put(callFrame, ident, ARG_src3, slot);
-
-    CHECK_FOR_EXCEPTION_AT_END();
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    Identifier& ident = *ARG_id2;
-
-    JSValuePtr baseValue = ARG_src1;
-    PropertySlot slot(baseValue);
-    JSValuePtr result = baseValue.get(callFrame, ident, slot);
-
-    ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_second));
-
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_second(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    Identifier& ident = *ARG_id2;
-
-    JSValuePtr baseValue = ARG_src1;
-    PropertySlot slot(baseValue);
-    JSValuePtr result = baseValue.get(callFrame, ident, slot);
-
-    ARG_globalData->interpreter->tryCTICacheGetByID(callFrame, callFrame->codeBlock(), STUB_RETURN_ADDRESS, baseValue, ident, slot);
-
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_self_fail(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    Identifier& ident = *ARG_id2;
-
-    JSValuePtr baseValue = ARG_src1;
-    PropertySlot slot(baseValue);
-    JSValuePtr result = baseValue.get(callFrame, ident, slot);
-
-    CHECK_FOR_EXCEPTION();
-
-    if (baseValue.isCell()
-        && slot.isCacheable()
-        && !asCell(baseValue)->structure()->isDictionary()
-        && slot.slotBase() == baseValue) {
-
-        CodeBlock* codeBlock = callFrame->codeBlock();
-        StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
-
-        ASSERT(slot.slotBase().isObject());
-
-        PolymorphicAccessStructureList* polymorphicStructureList;
-        int listIndex = 1;
-
-        if (stubInfo->opcodeID == op_get_by_id_self) {
-            ASSERT(!stubInfo->stubRoutine);
-            polymorphicStructureList = new PolymorphicAccessStructureList(0, stubInfo->u.getByIdSelf.baseObjectStructure);
-            stubInfo->initGetByIdSelfList(polymorphicStructureList, 2);
-        } else {
-            polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
-            listIndex = stubInfo->u.getByIdSelfList.listSize;
-            stubInfo->u.getByIdSelfList.listSize++;
-        }
-
-        JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), slot.cachedOffset());
-
-        if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
-            ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_generic));
-    } else {
-        ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_generic));
-    }
-    return JSValuePtr::encode(result);
-}
-
-static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex)
-{
-    PolymorphicAccessStructureList* prototypeStructureList = 0;
-    listIndex = 1;
-
-    switch (stubInfo->opcodeID) {
-    case op_get_by_id_proto:
-        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure);
-        stubInfo->stubRoutine = 0;
-        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
-        break;
-    case op_get_by_id_chain:
-        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
-        stubInfo->stubRoutine = 0;
-        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
-        break;
-    case op_get_by_id_proto_list:
-        prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
-        listIndex = stubInfo->u.getByIdProtoList.listSize;
-        stubInfo->u.getByIdProtoList.listSize++;
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-    
-    ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE);
-    return prototypeStructureList;
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_proto_list(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr baseValue = ARG_src1;
-    PropertySlot slot(baseValue);
-    JSValuePtr result = baseValue.get(callFrame, *ARG_id2, slot);
-
-    CHECK_FOR_EXCEPTION();
-
-    if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) {
-        ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail));
-        return JSValuePtr::encode(result);
-    }
-
-    Structure* structure = asCell(baseValue)->structure();
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
-
-    ASSERT(slot.slotBase().isObject());
-    JSObject* slotBaseObject = asObject(slot.slotBase());
-
-    if (slot.slotBase() == baseValue)
-        ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail));
-    else if (slot.slotBase() == asCell(baseValue)->structure()->prototypeForLookup(callFrame)) {
-        // Since we're accessing a prototype in a loop, it's a good bet that it
-        // should not be treated as a dictionary.
-        if (slotBaseObject->structure()->isDictionary()) 
-            slotBaseObject->setStructure(Structure::fromDictionaryTransition(slotBaseObject->structure())); 
-
-        int listIndex;
-        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
-
-        JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), slot.cachedOffset());
-
-        if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
-            ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_list_full));
-    } else if (size_t count = countPrototypeChainEntriesAndCheckForProxies(callFrame, baseValue, slot)) {
-        int listIndex;
-        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
-
-        JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, structure->prototypeChain(callFrame), count, slot.cachedOffset()); 
-
-        if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
-            ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_list_full));
-    } else
-        ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_id_proto_fail));
-
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_proto_list_full(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr baseValue = ARG_src1;
-    PropertySlot slot(baseValue);
-    JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
-
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_proto_fail(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr baseValue = ARG_src1;
-    PropertySlot slot(baseValue);
-    JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
-
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_array_fail(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr baseValue = ARG_src1;
-    PropertySlot slot(baseValue);
-    JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
-
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_id_string_fail(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr baseValue = ARG_src1;
-    PropertySlot slot(baseValue);
-    JSValuePtr result = baseValue.get(ARG_callFrame, *ARG_id2, slot);
-
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-#endif
-
-JSValueEncodedAsPointer* Interpreter::cti_op_instanceof(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr value = ARG_src1;
-    JSValuePtr baseVal = ARG_src2;
-    JSValuePtr proto = ARG_src3;
-
-    // at least one of these checks must have failed to get to the slow case
-    ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
-           || !value.isObject() || !baseVal.isObject() || !proto.isObject() 
-           || (asObject(baseVal)->structure()->typeInfo().flags() & (ImplementsHasInstance | OverridesHasInstance)) != ImplementsHasInstance);
-
-    if (!baseVal.isObject()) {
-        CallFrame* callFrame = ARG_callFrame;
-        CodeBlock* codeBlock = callFrame->codeBlock();
-        unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-        ARG_globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal, vPCIndex, codeBlock);
-        VM_THROW_EXCEPTION();
-    }
-
-    if (!asObject(baseVal)->structure()->typeInfo().implementsHasInstance())
-        return JSValuePtr::encode(jsBoolean(false));
-
-    if (!proto.isObject()) {
-        throwError(callFrame, TypeError, "instanceof called on an object with an invalid prototype property.");
-        VM_THROW_EXCEPTION();
-    }
-        
-    if (!value.isObject())
-        return JSValuePtr::encode(jsBoolean(false));
-
-    JSValuePtr result = jsBoolean(asObject(baseVal)->hasInstance(callFrame, value, proto));
-    CHECK_FOR_EXCEPTION_AT_END();
-
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_del_by_id(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    
-    JSObject* baseObj = ARG_src1.toObject(callFrame);
-
-    JSValuePtr result = jsBoolean(baseObj->deleteProperty(callFrame, *ARG_id2));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_mul(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    double left;
-    double right;
-    if (src1.getNumber(left) && src2.getNumber(right))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, left * right));
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) * src2.toNumber(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSObject* Interpreter::cti_op_new_func(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return ARG_func1->makeFunction(ARG_callFrame, ARG_callFrame->scopeChain());
-}
-
-void* Interpreter::cti_op_call_JSFunction(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-#ifndef NDEBUG
-    CallData callData;
-    ASSERT(ARG_src1.getCallData(callData) == CallTypeJS);
-#endif
-
-    ScopeChainNode* callDataScopeChain = asFunction(ARG_src1)->m_scopeChain.node();
-    CodeBlock* newCodeBlock = &asFunction(ARG_src1)->body()->bytecode(callDataScopeChain);
-
-    if (!newCodeBlock->jitCode())
-        JIT::compile(ARG_globalData, newCodeBlock);
-
-    return newCodeBlock;
-}
-
-VoidPtrPair Interpreter::cti_op_call_arityCheck(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    CodeBlock* newCodeBlock = ARG_codeBlock4;
-    int argCount = ARG_int3;
-
-    ASSERT(argCount != newCodeBlock->m_numParameters);
-
-    CallFrame* oldCallFrame = callFrame->callerFrame();
-
-    if (argCount > newCodeBlock->m_numParameters) {
-        size_t numParameters = newCodeBlock->m_numParameters;
-        Register* r = callFrame->registers() + numParameters;
-
-        Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
-        for (size_t i = 0; i < numParameters; ++i)
-            argv[i + argCount] = argv[i];
-
-        callFrame = CallFrame::create(r);
-        callFrame->setCallerFrame(oldCallFrame);
-    } else {
-        size_t omittedArgCount = newCodeBlock->m_numParameters - argCount;
-        Register* r = callFrame->registers() + omittedArgCount;
-        Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
-        if (!ARG_registerFile->grow(newEnd)) {
-            // Rewind to the previous call frame because op_call already optimistically
-            // moved the call frame forward.
-            ARG_setCallFrame(oldCallFrame);
-            throwStackOverflowError(oldCallFrame, ARG_globalData, ARG_returnAddress2, STUB_RETURN_ADDRESS);
-            RETURN_PAIR(0, 0);
-        }
-
-        Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
-        for (size_t i = 0; i < omittedArgCount; ++i)
-            argv[i] = jsUndefined();
-
-        callFrame = CallFrame::create(r);
-        callFrame->setCallerFrame(oldCallFrame);
-    }
-
-    RETURN_PAIR(newCodeBlock, callFrame);
-}
-
-void* Interpreter::cti_vm_dontLazyLinkCall(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSFunction* callee = asFunction(ARG_src1);
-    CodeBlock* codeBlock = &callee->body()->bytecode(callee->m_scopeChain.node());
-    if (!codeBlock->jitCode())
-        JIT::compile(ARG_globalData, codeBlock);
-
-    ctiPatchCallByReturnAddress(ARG_returnAddress2, ARG_globalData->interpreter->m_ctiVirtualCallLink);
-
-    return codeBlock->jitCode();
-}
-
-void* Interpreter::cti_vm_lazyLinkCall(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSFunction* callee = asFunction(ARG_src1);
-    CodeBlock* codeBlock = &callee->body()->bytecode(callee->m_scopeChain.node());
-    if (!codeBlock->jitCode())
-        JIT::compile(ARG_globalData, codeBlock);
-
-    CallLinkInfo* callLinkInfo = &ARG_callFrame->callerFrame()->codeBlock()->getCallLinkInfo(ARG_returnAddress2);
-    JIT::linkCall(callee, codeBlock, codeBlock->jitCode(), callLinkInfo, ARG_int3);
-
-    return codeBlock->jitCode();
-}
-
-JSObject* Interpreter::cti_op_push_activation(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSActivation* activation = new (ARG_globalData) JSActivation(ARG_callFrame, static_cast<FunctionBodyNode*>(ARG_callFrame->codeBlock()->ownerNode()));
-    ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->copy()->push(activation));
-    return activation;
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_call_NotJSFunction(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr funcVal = ARG_src1;
-
-    CallData callData;
-    CallType callType = funcVal.getCallData(callData);
-
-    ASSERT(callType != CallTypeJS);
-
-    if (callType == CallTypeHost) {
-        int registerOffset = ARG_int2;
-        int argCount = ARG_int3;
-        CallFrame* previousCallFrame = ARG_callFrame;
-        CallFrame* callFrame = CallFrame::create(previousCallFrame->registers() + registerOffset);
-
-        callFrame->init(0, static_cast<Instruction*>(STUB_RETURN_ADDRESS), previousCallFrame->scopeChain(), previousCallFrame, 0, argCount, 0);
-        ARG_setCallFrame(callFrame);
-
-        Register* argv = ARG_callFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
-        ArgList argList(argv + 1, argCount - 1);
-
-        JSValuePtr returnValue;
-        {
-            SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
-
-            // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
-            JSValuePtr thisValue = argv[0].jsValue(callFrame);
-            if (thisValue == jsNull())
-                thisValue = callFrame->globalThisValue();
-
-            returnValue = callData.native.function(callFrame, asObject(funcVal), thisValue, argList);
-        }
-        ARG_setCallFrame(previousCallFrame);
-        CHECK_FOR_EXCEPTION();
-
-        return JSValuePtr::encode(returnValue);
-    }
-
-    ASSERT(callType == CallTypeNone);
-
-    CallFrame* callFrame = ARG_callFrame;
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-    ARG_globalData->exception = createNotAFunctionError(ARG_callFrame, funcVal, vPCIndex, codeBlock);
-    VM_THROW_EXCEPTION();
-}
-
-void Interpreter::cti_op_create_arguments(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    Arguments* arguments = new (ARG_globalData) Arguments(ARG_callFrame);
-    ARG_callFrame->setCalleeArguments(arguments);
-    ARG_callFrame[RegisterFile::ArgumentsRegister] = arguments;
-}
-
-void Interpreter::cti_op_create_arguments_no_params(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    Arguments* arguments = new (ARG_globalData) Arguments(ARG_callFrame, Arguments::NoParameters);
-    ARG_callFrame->setCalleeArguments(arguments);
-    ARG_callFrame[RegisterFile::ArgumentsRegister] = arguments;
-}
-
-void Interpreter::cti_op_tear_off_activation(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain());
-    asActivation(ARG_src1)->copyRegisters(ARG_callFrame->optionalCalleeArguments());
-}
-
-void Interpreter::cti_op_tear_off_arguments(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    ASSERT(ARG_callFrame->codeBlock()->usesArguments() && !ARG_callFrame->codeBlock()->needsFullScopeChain());
-    ARG_callFrame->optionalCalleeArguments()->copyRegisters();
-}
-
-void Interpreter::cti_op_profile_will_call(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    ASSERT(*ARG_profilerReference);
-    (*ARG_profilerReference)->willExecute(ARG_callFrame, ARG_src1);
-}
-
-void Interpreter::cti_op_profile_did_call(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    ASSERT(*ARG_profilerReference);
-    (*ARG_profilerReference)->didExecute(ARG_callFrame, ARG_src1);
-}
-
-void Interpreter::cti_op_ret_scopeChain(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    ASSERT(ARG_callFrame->codeBlock()->needsFullScopeChain());
-    ARG_callFrame->scopeChain()->deref();
-}
-
-JSObject* Interpreter::cti_op_new_array(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    ArgList argList(&ARG_callFrame->registers()[ARG_int1], ARG_int2);
-    return constructArray(ARG_callFrame, argList);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_resolve(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    ScopeChainNode* scopeChain = callFrame->scopeChain();
-
-    ScopeChainIterator iter = scopeChain->begin();
-    ScopeChainIterator end = scopeChain->end();
-    ASSERT(iter != end);
-
-    Identifier& ident = *ARG_id1;
-    do {
-        JSObject* o = *iter;
-        PropertySlot slot(o);
-        if (o->getPropertySlot(callFrame, ident, slot)) {
-            JSValuePtr result = slot.getValue(callFrame, ident);
-            CHECK_FOR_EXCEPTION_AT_END();
-            return JSValuePtr::encode(result);
-        }
-    } while (++iter != end);
-
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-    ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
-    VM_THROW_EXCEPTION();
-}
-
-JSObject* Interpreter::cti_op_construct_JSConstruct(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-#ifndef NDEBUG
-    ConstructData constructData;
-    ASSERT(asFunction(ARG_src1)->getConstructData(constructData) == ConstructTypeJS);
-#endif
-
-    Structure* structure;
-    if (ARG_src4.isObject())
-        structure = asObject(ARG_src4)->inheritorID();
-    else
-        structure = asFunction(ARG_src1)->m_scopeChain.node()->globalObject()->emptyObjectStructure();
-    return new (ARG_globalData) JSObject(structure);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_construct_NotJSConstruct(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr constrVal = ARG_src1;
-    int argCount = ARG_int3;
-    int thisRegister = ARG_int5;
-
-    ConstructData constructData;
-    ConstructType constructType = constrVal.getConstructData(constructData);
-
-    if (constructType == ConstructTypeHost) {
-        ArgList argList(callFrame->registers() + thisRegister + 1, argCount - 1);
-
-        JSValuePtr returnValue;
-        {
-            SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
-            returnValue = constructData.native.function(callFrame, asObject(constrVal), argList);
-        }
-        CHECK_FOR_EXCEPTION();
-
-        return JSValuePtr::encode(returnValue);
-    }
-
-    ASSERT(constructType == ConstructTypeNone);
-
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-    ARG_globalData->exception = createNotAConstructorError(callFrame, constrVal, vPCIndex, codeBlock);
-    VM_THROW_EXCEPTION();
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_val(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    Interpreter* interpreter = ARG_globalData->interpreter;
-
-    JSValuePtr baseValue = ARG_src1;
-    JSValuePtr subscript = ARG_src2;
-
-    JSValuePtr result;
-
-    if (LIKELY(subscript.isUInt32Fast())) {
-        uint32_t i = subscript.getUInt32Fast();
-        if (interpreter->isJSArray(baseValue)) {
-            JSArray* jsArray = asArray(baseValue);
-            if (jsArray->canGetIndex(i))
-                result = jsArray->getIndex(i);
-            else
-                result = jsArray->JSArray::get(callFrame, i);
-        } else if (interpreter->isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
-            result = asString(baseValue)->getIndex(ARG_globalData, i);
-        else if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
-            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
-            ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_val_byte_array));
-            return JSValuePtr::encode(asByteArray(baseValue)->getIndex(callFrame, i));
-        } else
-            result = baseValue.get(callFrame, i);
-    } else {
-        Identifier property(callFrame, subscript.toString(callFrame));
-        result = baseValue.get(callFrame, property);
-    }
-
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_get_by_val_byte_array(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-    
-    CallFrame* callFrame = ARG_callFrame;
-    Interpreter* interpreter = ARG_globalData->interpreter;
-    
-    JSValuePtr baseValue = ARG_src1;
-    JSValuePtr subscript = ARG_src2;
-    
-    JSValuePtr result;
-
-    if (LIKELY(subscript.isUInt32Fast())) {
-        uint32_t i = subscript.getUInt32Fast();
-        if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
-            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
-            return JSValuePtr::encode(asByteArray(baseValue)->getIndex(callFrame, i));
-        }
-
-        result = baseValue.get(callFrame, i);
-        if (!interpreter->isJSByteArray(baseValue))
-            ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_get_by_val));
-    } else {
-        Identifier property(callFrame, subscript.toString(callFrame));
-        result = baseValue.get(callFrame, property);
-    }
-    
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-VoidPtrPair Interpreter::cti_op_resolve_func(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    ScopeChainNode* scopeChain = callFrame->scopeChain();
-
-    ScopeChainIterator iter = scopeChain->begin();
-    ScopeChainIterator end = scopeChain->end();
-
-    // FIXME: add scopeDepthIsZero optimization
-
-    ASSERT(iter != end);
-
-    Identifier& ident = *ARG_id1;
-    JSObject* base;
-    do {
-        base = *iter;
-        PropertySlot slot(base);
-        if (base->getPropertySlot(callFrame, ident, slot)) {            
-            // ECMA 11.2.3 says that if we hit an activation the this value should be null.
-            // However, section 10.2.3 says that in the case where the value provided
-            // by the caller is null, the global object should be used. It also says
-            // that the section does not apply to internal functions, but for simplicity
-            // of implementation we use the global object anyway here. This guarantees
-            // that in host objects you always get a valid object for this.
-            // We also handle wrapper substitution for the global object at the same time.
-            JSObject* thisObj = base->toThisObject(callFrame);
-            JSValuePtr result = slot.getValue(callFrame, ident);
-            CHECK_FOR_EXCEPTION_AT_END();
-
-            RETURN_PAIR(thisObj, JSValuePtr::encode(result));
-        }
-        ++iter;
-    } while (iter != end);
-
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-    ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
-    VM_THROW_EXCEPTION_2();
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_sub(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    double left;
-    double right;
-    if (src1.getNumber(left) && src2.getNumber(right))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, left - right));
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) - src2.toNumber(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-void Interpreter::cti_op_put_by_val(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    Interpreter* interpreter = ARG_globalData->interpreter;
-
-    JSValuePtr baseValue = ARG_src1;
-    JSValuePtr subscript = ARG_src2;
-    JSValuePtr value = ARG_src3;
-
-    if (LIKELY(subscript.isUInt32Fast())) {
-        uint32_t i = subscript.getUInt32Fast();
-        if (interpreter->isJSArray(baseValue)) {
-            JSArray* jsArray = asArray(baseValue);
-            if (jsArray->canSetIndex(i))
-                jsArray->setIndex(i, value);
-            else
-                jsArray->JSArray::put(callFrame, i, value);
-        } else if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
-            JSByteArray* jsByteArray = asByteArray(baseValue);
-            ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_val_byte_array));
-            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
-            if (value.isInt32Fast()) {
-                jsByteArray->setIndex(i, value.getInt32Fast());
-                return;
-            } else {
-                double dValue = 0;
-                if (value.getNumber(dValue)) {
-                    jsByteArray->setIndex(i, dValue);
-                    return;
-                }
-            }
-
-            baseValue.put(callFrame, i, value);
-        } else
-            baseValue.put(callFrame, i, value);
-    } else {
-        Identifier property(callFrame, subscript.toString(callFrame));
-        if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
-            PutPropertySlot slot;
-            baseValue.put(callFrame, property, value, slot);
-        }
-    }
-
-    CHECK_FOR_EXCEPTION_AT_END();
-}
-
-void Interpreter::cti_op_put_by_val_array(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr baseValue = ARG_src1;
-    int i = ARG_int2;
-    JSValuePtr value = ARG_src3;
-
-    ASSERT(ARG_globalData->interpreter->isJSArray(baseValue));
-
-    if (LIKELY(i >= 0))
-        asArray(baseValue)->JSArray::put(callFrame, i, value);
-    else {
-        // This should work since we're re-boxing an immediate unboxed in JIT code.
-        ASSERT(JSValuePtr::makeInt32Fast(i));
-        Identifier property(callFrame, JSValuePtr::makeInt32Fast(i).toString(callFrame));
-        // FIXME: can toString throw an exception here?
-        if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
-            PutPropertySlot slot;
-            baseValue.put(callFrame, property, value, slot);
-        }
-    }
-
-    CHECK_FOR_EXCEPTION_AT_END();
-}
-
-void Interpreter::cti_op_put_by_val_byte_array(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-    
-    CallFrame* callFrame = ARG_callFrame;
-    Interpreter* interpreter = ARG_globalData->interpreter;
-    
-    JSValuePtr baseValue = ARG_src1;
-    JSValuePtr subscript = ARG_src2;
-    JSValuePtr value = ARG_src3;
-    
-    if (LIKELY(subscript.isUInt32Fast())) {
-        uint32_t i = subscript.getUInt32Fast();
-        if (interpreter->isJSByteArray(baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
-            JSByteArray* jsByteArray = asByteArray(baseValue);
-            
-            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
-            if (value.isInt32Fast()) {
-                jsByteArray->setIndex(i, value.getInt32Fast());
-                return;
-            } else {
-                double dValue = 0;                
-                if (value.getNumber(dValue)) {
-                    jsByteArray->setIndex(i, dValue);
-                    return;
-                }
-            }
-        }
-
-        if (!interpreter->isJSByteArray(baseValue))
-            ctiPatchCallByReturnAddress(STUB_RETURN_ADDRESS, reinterpret_cast<void*>(cti_op_put_by_val));
-        baseValue.put(callFrame, i, value);
-    } else {
-        Identifier property(callFrame, subscript.toString(callFrame));
-        if (!ARG_globalData->exception) { // Don't put to an object if toString threw an exception.
-            PutPropertySlot slot;
-            baseValue.put(callFrame, property, value, slot);
-        }
-    }
-    
-    CHECK_FOR_EXCEPTION_AT_END();
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_lesseq(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsBoolean(jsLessEq(callFrame, ARG_src1, ARG_src2));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-int Interpreter::cti_op_loop_if_true(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    bool result = src1.toBoolean(callFrame);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return result;
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_negate(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src = ARG_src1;
-
-    double v;
-    if (src.getNumber(v))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, -v));
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, -src.toNumber(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_resolve_base(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return JSValuePtr::encode(inlineResolveBase(ARG_callFrame, *ARG_id1, ARG_callFrame->scopeChain()));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_resolve_skip(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    ScopeChainNode* scopeChain = callFrame->scopeChain();
-
-    int skip = ARG_int2;
-
-    ScopeChainIterator iter = scopeChain->begin();
-    ScopeChainIterator end = scopeChain->end();
-    ASSERT(iter != end);
-    while (skip--) {
-        ++iter;
-        ASSERT(iter != end);
-    }
-    Identifier& ident = *ARG_id1;
-    do {
-        JSObject* o = *iter;
-        PropertySlot slot(o);
-        if (o->getPropertySlot(callFrame, ident, slot)) {
-            JSValuePtr result = slot.getValue(callFrame, ident);
-            CHECK_FOR_EXCEPTION_AT_END();
-            return JSValuePtr::encode(result);
-        }
-    } while (++iter != end);
-
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-    ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
-    VM_THROW_EXCEPTION();
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_resolve_global(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSGlobalObject* globalObject = asGlobalObject(ARG_src1);
-    Identifier& ident = *ARG_id2;
-    unsigned globalResolveInfoIndex = ARG_int3;
-    ASSERT(globalObject->isGlobalObject());
-
-    PropertySlot slot(globalObject);
-    if (globalObject->getPropertySlot(callFrame, ident, slot)) {
-        JSValuePtr result = slot.getValue(callFrame, ident);
-        if (slot.isCacheable() && !globalObject->structure()->isDictionary() && slot.slotBase() == globalObject) {
-            GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex);
-            if (globalResolveInfo.structure)
-                globalResolveInfo.structure->deref();
-            globalObject->structure()->ref();
-            globalResolveInfo.structure = globalObject->structure();
-            globalResolveInfo.offset = slot.cachedOffset();
-            return JSValuePtr::encode(result);
-        }
-
-        CHECK_FOR_EXCEPTION_AT_END();
-        return JSValuePtr::encode(result);
-    }
-
-    unsigned vPCIndex = callFrame->codeBlock()->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-    ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, callFrame->codeBlock());
-    VM_THROW_EXCEPTION();
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_div(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    double left;
-    double right;
-    if (src1.getNumber(left) && src2.getNumber(right))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, left / right));
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, src1.toNumber(callFrame) / src2.toNumber(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_pre_dec(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr v = ARG_src1;
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, v.toNumber(callFrame) - 1);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-int Interpreter::cti_op_jless(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-    CallFrame* callFrame = ARG_callFrame;
-
-    bool result = jsLess(callFrame, src1, src2);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return result;
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_not(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src = ARG_src1;
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr result = jsBoolean(!src.toBoolean(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-int Interpreter::cti_op_jtrue(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    bool result = src1.toBoolean(callFrame);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return result;
-}
-
-VoidPtrPair Interpreter::cti_op_post_inc(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr v = ARG_src1;
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr number = v.toJSNumber(callFrame);
-    CHECK_FOR_EXCEPTION_AT_END();
-
-    RETURN_PAIR(JSValuePtr::encode(number), JSValuePtr::encode(jsNumber(ARG_globalData, number.uncheckedGetNumber() + 1)));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_eq(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    ASSERT(!JSValuePtr::areBothInt32Fast(src1, src2));
-    JSValuePtr result = jsBoolean(JSValuePtr::equalSlowCaseInline(callFrame, src1, src2));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_lshift(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr val = ARG_src1;
-    JSValuePtr shift = ARG_src2;
-
-    int32_t left;
-    uint32_t right;
-    if (JSValuePtr::areBothInt32Fast(val, shift))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, val.getInt32Fast() << (shift.getInt32Fast() & 0x1f)));
-    if (val.numberToInt32(left) && shift.numberToUInt32(right))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, left << (right & 0x1f)));
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_bitand(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    int32_t left;
-    int32_t right;
-    if (src1.numberToInt32(left) && src2.numberToInt32(right))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, left & right));
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, src1.toInt32(callFrame) & src2.toInt32(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_rshift(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr val = ARG_src1;
-    JSValuePtr shift = ARG_src2;
-
-    int32_t left;
-    uint32_t right;
-    if (JSFastMath::canDoFastRshift(val, shift))
-        return JSValuePtr::encode(JSFastMath::rightShiftImmediateNumbers(val, shift));
-    if (val.numberToInt32(left) && shift.numberToUInt32(right))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, left >> (right & 0x1f)));
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_bitnot(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src = ARG_src1;
-
-    int value;
-    if (src.numberToInt32(value))
-        return JSValuePtr::encode(jsNumber(ARG_globalData, ~value));
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsNumber(ARG_globalData, ~src.toInt32(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-VoidPtrPair Interpreter::cti_op_resolve_with_base(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    ScopeChainNode* scopeChain = callFrame->scopeChain();
-
-    ScopeChainIterator iter = scopeChain->begin();
-    ScopeChainIterator end = scopeChain->end();
-
-    // FIXME: add scopeDepthIsZero optimization
-
-    ASSERT(iter != end);
-
-    Identifier& ident = *ARG_id1;
-    JSObject* base;
-    do {
-        base = *iter;
-        PropertySlot slot(base);
-        if (base->getPropertySlot(callFrame, ident, slot)) {
-            JSValuePtr result = slot.getValue(callFrame, ident);
-            CHECK_FOR_EXCEPTION_AT_END();
-
-            RETURN_PAIR(base, JSValuePtr::encode(result));
-        }
-        ++iter;
-    } while (iter != end);
-
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-    ARG_globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
-    VM_THROW_EXCEPTION_2();
-}
-
-JSObject* Interpreter::cti_op_new_func_exp(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return ARG_funcexp1->makeFunction(ARG_callFrame, ARG_callFrame->scopeChain());
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_mod(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr dividendValue = ARG_src1;
-    JSValuePtr divisorValue = ARG_src2;
-
-    CallFrame* callFrame = ARG_callFrame;
-    double d = dividendValue.toNumber(callFrame);
-    JSValuePtr result = jsNumber(ARG_globalData, fmod(d, divisorValue.toNumber(callFrame)));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_less(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsBoolean(jsLess(callFrame, ARG_src1, ARG_src2));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_neq(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    ASSERT(!JSValuePtr::areBothInt32Fast(src1, src2));
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr result = jsBoolean(!JSValuePtr::equalSlowCaseInline(callFrame, src1, src2));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-VoidPtrPair Interpreter::cti_op_post_dec(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr v = ARG_src1;
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr number = v.toJSNumber(callFrame);
-    CHECK_FOR_EXCEPTION_AT_END();
-
-    RETURN_PAIR(JSValuePtr::encode(number), JSValuePtr::encode(jsNumber(ARG_globalData, number.uncheckedGetNumber() - 1)));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_urshift(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr val = ARG_src1;
-    JSValuePtr shift = ARG_src2;
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    if (JSFastMath::canDoFastUrshift(val, shift))
-        return JSValuePtr::encode(JSFastMath::rightShiftImmediateNumbers(val, shift));
-    else {
-        JSValuePtr result = jsNumber(ARG_globalData, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
-        CHECK_FOR_EXCEPTION_AT_END();
-        return JSValuePtr::encode(result);
-    }
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_bitxor(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr result = jsNumber(ARG_globalData, src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSObject* Interpreter::cti_op_new_regexp(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return new (ARG_globalData) RegExpObject(ARG_callFrame->lexicalGlobalObject()->regExpStructure(), ARG_regexp1);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_bitor(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr result = jsNumber(ARG_globalData, src1.toInt32(callFrame) | src2.toInt32(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_call_eval(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    RegisterFile* registerFile = ARG_registerFile;
-
-    Interpreter* interpreter = ARG_globalData->interpreter;
-    
-    JSValuePtr funcVal = ARG_src1;
-    int registerOffset = ARG_int2;
-    int argCount = ARG_int3;
-
-    Register* newCallFrame = callFrame->registers() + registerOffset;
-    Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
-    JSValuePtr thisValue = argv[0].jsValue(callFrame);
-    JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
-
-    if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
-        JSValuePtr exceptionValue = noValue();
-        JSValuePtr result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
-        if (UNLIKELY(exceptionValue != noValue())) {
-            ARG_globalData->exception = exceptionValue;
-            VM_THROW_EXCEPTION_AT_END();
-        }
-        return JSValuePtr::encode(result);
-    }
-
-    return JSValuePtr::encode(jsImpossibleValue());
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_throw(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    CodeBlock* codeBlock = callFrame->codeBlock();
-
-    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-
-    JSValuePtr exceptionValue = ARG_src1;
-    ASSERT(exceptionValue);
-
-    HandlerInfo* handler = ARG_globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, true);
-
-    if (!handler) {
-        *ARG_exception = exceptionValue;
-        return JSValuePtr::encode(jsNull());
-    }
-
-    ARG_setCallFrame(callFrame);
-    void* catchRoutine = handler->nativeCode;
-    ASSERT(catchRoutine);
-    STUB_SET_RETURN_ADDRESS(catchRoutine);
-    return JSValuePtr::encode(exceptionValue);
-}
-
-JSPropertyNameIterator* Interpreter::cti_op_get_pnames(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return JSPropertyNameIterator::create(ARG_callFrame, ARG_src1);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_next_pname(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSPropertyNameIterator* it = ARG_pni1;
-    JSValuePtr temp = it->next(ARG_callFrame);
-    if (!temp)
-        it->invalidate();
-    return JSValuePtr::encode(temp);
-}
-
-JSObject* Interpreter::cti_op_push_scope(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSObject* o = ARG_src1.toObject(ARG_callFrame);
-    CHECK_FOR_EXCEPTION();
-    ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->push(o));
-    return o;
-}
-
-void Interpreter::cti_op_pop_scope(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    ARG_callFrame->setScopeChain(ARG_callFrame->scopeChain()->pop());
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_typeof(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return JSValuePtr::encode(jsTypeStringForValue(ARG_callFrame, ARG_src1));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_is_undefined(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr v = ARG_src1;
-    return JSValuePtr::encode(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_is_boolean(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return JSValuePtr::encode(jsBoolean(ARG_src1.isBoolean()));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_is_number(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return JSValuePtr::encode(jsBoolean(ARG_src1.isNumber()));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_is_string(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return JSValuePtr::encode(jsBoolean(ARG_globalData->interpreter->isJSString(ARG_src1)));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_is_object(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return JSValuePtr::encode(jsBoolean(jsIsObjectType(ARG_src1)));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_is_function(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    return JSValuePtr::encode(jsBoolean(jsIsFunctionType(ARG_src1)));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_stricteq(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    return JSValuePtr::encode(jsBoolean(JSValuePtr::strictEqual(src1, src2)));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_nstricteq(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src1 = ARG_src1;
-    JSValuePtr src2 = ARG_src2;
-
-    return JSValuePtr::encode(jsBoolean(!JSValuePtr::strictEqual(src1, src2)));
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_to_jsnumber(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr src = ARG_src1;
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr result = src.toJSNumber(callFrame);
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_in(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    JSValuePtr baseVal = ARG_src2;
-
-    if (!baseVal.isObject()) {
-        CallFrame* callFrame = ARG_callFrame;
-        CodeBlock* codeBlock = callFrame->codeBlock();
-        unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
-        ARG_globalData->exception = createInvalidParamError(callFrame, "in", baseVal, vPCIndex, codeBlock);
-        VM_THROW_EXCEPTION();
-    }
-
-    JSValuePtr propName = ARG_src1;
-    JSObject* baseObj = asObject(baseVal);
-
-    uint32_t i;
-    if (propName.getUInt32(i))
-        return JSValuePtr::encode(jsBoolean(baseObj->hasProperty(callFrame, i)));
-
-    Identifier property(callFrame, propName.toString(callFrame));
-    CHECK_FOR_EXCEPTION();
-    return JSValuePtr::encode(jsBoolean(baseObj->hasProperty(callFrame, property)));
-}
-
-JSObject* Interpreter::cti_op_push_new_scope(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSObject* scope = new (ARG_globalData) JSStaticScopeObject(ARG_callFrame, *ARG_id1, ARG_src2, DontDelete);
-
-    CallFrame* callFrame = ARG_callFrame;
-    callFrame->setScopeChain(callFrame->scopeChain()->push(scope));
-    return scope;
-}
-
-void Interpreter::cti_op_jmp_scopes(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    unsigned count = ARG_int1;
-    CallFrame* callFrame = ARG_callFrame;
-
-    ScopeChainNode* tmp = callFrame->scopeChain();
-    while (count--)
-        tmp = tmp->pop();
-    callFrame->setScopeChain(tmp);
-}
-
-void Interpreter::cti_op_put_by_index(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    unsigned property = ARG_int2;
-
-    ARG_src1.put(callFrame, property, ARG_src3);
-}
-
-void* Interpreter::cti_op_switch_imm(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr scrutinee = ARG_src1;
-    unsigned tableIndex = ARG_int2;
-    CallFrame* callFrame = ARG_callFrame;
-    CodeBlock* codeBlock = callFrame->codeBlock();
-
-    if (scrutinee.isInt32Fast())
-        return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.getInt32Fast());
-    else {
-        int32_t value;
-        if (scrutinee.numberToInt32(value))
-            return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(value);
-        else
-            return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault;
-    }
-}
-
-void* Interpreter::cti_op_switch_char(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr scrutinee = ARG_src1;
-    unsigned tableIndex = ARG_int2;
-    CallFrame* callFrame = ARG_callFrame;
-    CodeBlock* codeBlock = callFrame->codeBlock();
-
-    void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault;
-
-    if (scrutinee.isString()) {
-        UString::Rep* value = asString(scrutinee)->value().rep();
-        if (value->size() == 1)
-            result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]);
-    }
-
-    return result;
-}
-
-void* Interpreter::cti_op_switch_string(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    JSValuePtr scrutinee = ARG_src1;
-    unsigned tableIndex = ARG_int2;
-    CallFrame* callFrame = ARG_callFrame;
-    CodeBlock* codeBlock = callFrame->codeBlock();
-
-    void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault;
-
-    if (scrutinee.isString()) {
-        UString::Rep* value = asString(scrutinee)->value().rep();
-        result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value);
-    }
-
-    return result;
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_op_del_by_val(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    JSValuePtr baseValue = ARG_src1;
-    JSObject* baseObj = baseValue.toObject(callFrame); // may throw
-
-    JSValuePtr subscript = ARG_src2;
-    JSValuePtr result;
-    uint32_t i;
-    if (subscript.getUInt32(i))
-        result = jsBoolean(baseObj->deleteProperty(callFrame, i));
-    else {
-        CHECK_FOR_EXCEPTION();
-        Identifier property(callFrame, subscript.toString(callFrame));
-        CHECK_FOR_EXCEPTION();
-        result = jsBoolean(baseObj->deleteProperty(callFrame, property));
-    }
-
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValuePtr::encode(result);
-}
-
-void Interpreter::cti_op_put_getter(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    ASSERT(ARG_src1.isObject());
-    JSObject* baseObj = asObject(ARG_src1);
-    ASSERT(ARG_src3.isObject());
-    baseObj->defineGetter(callFrame, *ARG_id2, asObject(ARG_src3));
-}
-
-void Interpreter::cti_op_put_setter(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    ASSERT(ARG_src1.isObject());
-    JSObject* baseObj = asObject(ARG_src1);
-    ASSERT(ARG_src3.isObject());
-    baseObj->defineSetter(callFrame, *ARG_id2, asObject(ARG_src3));
-}
-
-JSObject* Interpreter::cti_op_new_error(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    unsigned type = ARG_int1;
-    JSValuePtr message = ARG_src2;
-    unsigned bytecodeOffset = ARG_int3;
-
-    unsigned lineNumber = codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset);
-    return Error::create(callFrame, static_cast<ErrorType>(type), message.toString(callFrame), lineNumber, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
-}
-
-void Interpreter::cti_op_debug(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-
-    int debugHookID = ARG_int1;
-    int firstLine = ARG_int2;
-    int lastLine = ARG_int3;
-
-    ARG_globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
-}
-
-JSValueEncodedAsPointer* Interpreter::cti_vm_throw(STUB_ARGS)
-{
-    BEGIN_STUB_FUNCTION();
-
-    CallFrame* callFrame = ARG_callFrame;
-    CodeBlock* codeBlock = callFrame->codeBlock();
-    JSGlobalData* globalData = ARG_globalData;
-
-    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, globalData->exceptionLocation);
-
-    JSValuePtr exceptionValue = globalData->exception;
-    ASSERT(exceptionValue);
-    globalData->exception = noValue();
-
-    HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, false);
-
-    if (!handler) {
-        *ARG_exception = exceptionValue;
-        return JSValuePtr::encode(jsNull());
-    }
-
-    ARG_setCallFrame(callFrame);
-    void* catchRoutine = handler->nativeCode;
-    ASSERT(catchRoutine);
-    STUB_SET_RETURN_ADDRESS(catchRoutine);
-    return JSValuePtr::encode(exceptionValue);
-}
-
-#undef STUB_RETURN_ADDRESS
-#undef STUB_SET_RETURN_ADDRESS
-#undef BEGIN_STUB_FUNCTION
-#undef CHECK_FOR_EXCEPTION
-#undef CHECK_FOR_EXCEPTION_AT_END
-#undef CHECK_FOR_EXCEPTION_VOID
-#undef VM_THROW_EXCEPTION
-#undef VM_THROW_EXCEPTION_2
-#undef VM_THROW_EXCEPTION_AT_END
-
-#endif // ENABLE(JIT)
-
 } // namespace JSC
index 087be106fa58adb4e4f48ff3596b822fa25f254d..f2047e411ccb7902a25a001a96fc884d22ee4ee4 100644 (file)
 #define Interpreter_h
 
 #include "ArgList.h"
+#include "FastAllocBase.h"
+#include "HashMap.h"
 #include "JSCell.h"
 #include "JSValue.h"
+#include "JSObject.h"
 #include "Opcode.h"
 #include "RegisterFile.h"
-#include <wtf/HashMap.h>
 
 namespace JSC {
 
@@ -43,61 +45,15 @@ namespace JSC {
     class FunctionBodyNode;
     class Instruction;
     class InternalFunction;
-    class AssemblerBuffer;
     class JSFunction;
     class JSGlobalObject;
     class ProgramNode;
     class Register;
     class ScopeChainNode;
     class SamplingTool;
+    struct CallFrameClosure;
     struct HandlerInfo;
 
-#if ENABLE(JIT)
-
-#if USE(JIT_STUB_ARGUMENT_VA_LIST)
-    #define STUB_ARGS void* args, ...
-    #define ARGS (reinterpret_cast<void**>(vl_args) - 1)
-#else // JIT_STUB_ARGUMENT_REGISTER or JIT_STUB_ARGUMENT_STACK
-    #define STUB_ARGS void** args
-    #define ARGS (args)
-#endif
-
-#if USE(JIT_STUB_ARGUMENT_REGISTER)
-    #if PLATFORM(X86_64)
-    #define JIT_STUB
-    #elif COMPILER(MSVC)
-    #define JIT_STUB __fastcall
-    #elif COMPILER(GCC)
-    #define JIT_STUB  __attribute__ ((fastcall))
-    #else
-    #error Need to support register calling convention in this compiler
-    #endif
-#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
-    #if COMPILER(MSVC)
-    #define JIT_STUB __cdecl
-    #else
-    #define JIT_STUB
-    #endif
-#endif
-
-// The Mac compilers are fine with this, 
-#if PLATFORM(MAC)
-    struct VoidPtrPair {
-        void* first;
-        void* second;
-    };
-#define RETURN_PAIR(a,b) VoidPtrPair pair = { a, b }; return pair
-#else
-    typedef uint64_t VoidPtrPair;
-    union VoidPtrPairValue {
-        struct { void* first; void* second; } s;
-        VoidPtrPair i;
-    };
-#define RETURN_PAIR(a,b) VoidPtrPairValue pair = {{ a, b }}; return pair.i
-#endif
-
-#endif // ENABLE(JIT)
-
     enum DebugHookID {
         WillExecuteProgram,
         DidExecuteProgram,
@@ -109,16 +65,14 @@ namespace JSC {
 
     // We use a smaller reentrancy limit on iPhone because of the high amount of
     // stack space required on the web thread.
-    enum { MaxReentryDepth = 100 };
+    enum { MaxMainThreadReentryDepth = 100, MaxSecondaryThreadReentryDepth = 32 };
 
-    class Interpreter {
+    class Interpreter : public FastAllocBase {
         friend class JIT;
+        friend class CachedCall;
     public:
         Interpreter();
-        ~Interpreter();
 
-        void initialize(JSGlobalData*);
-        
         RegisterFile& registerFile() { return m_registerFile; }
         
         Opcode getOpcode(OpcodeID id)
@@ -142,238 +96,72 @@ namespace JSC {
 
         bool isOpcode(Opcode);
         
-        JSValuePtr execute(ProgramNode*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValuePtr* exception);
-        JSValuePtr execute(FunctionBodyNode*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValuePtr* exception);
-        JSValuePtr execute(EvalNode* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValuePtr* exception);
+        JSValue execute(ProgramNode*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValue* exception);
+        JSValue execute(FunctionBodyNode*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue* exception);
+        JSValue execute(EvalNode* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception);
 
-        JSValuePtr retrieveArguments(CallFrame*, JSFunction*) const;
-        JSValuePtr retrieveCaller(CallFrame*, InternalFunction*) const;
-        void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValuePtr& function) const;
+        JSValue retrieveArguments(CallFrame*, JSFunction*) const;
+        JSValue retrieveCaller(CallFrame*, InternalFunction*) const;
+        void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const;
         
         void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
-        void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; }
         
-        void startTimeoutCheck()
-        {
-            if (!m_timeoutCheckCount)
-                resetTimeoutCheck();
-            
-            ++m_timeoutCheckCount;
-        }
-        
-        void stopTimeoutCheck()
-        {
-            ASSERT(m_timeoutCheckCount);
-            --m_timeoutCheckCount;
-        }
-
-        inline void initTimeout()
-        {
-            ASSERT(!m_timeoutCheckCount);
-            resetTimeoutCheck();
-            m_timeoutTime = 0;
-            m_timeoutCheckCount = 0;
-        }
-
         void setSampler(SamplingTool* sampler) { m_sampler = sampler; }
         SamplingTool* sampler() { return m_sampler; }
 
-#if ENABLE(JIT)
-
-        static int JIT_STUB cti_timeout_check(STUB_ARGS);
-        static void JIT_STUB cti_register_file_check(STUB_ARGS);
-
-        static JSObject* JIT_STUB cti_op_convert_this(STUB_ARGS);
-        static void JIT_STUB cti_op_end(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_add(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_inc(STUB_ARGS);
-        static int JIT_STUB cti_op_loop_if_less(STUB_ARGS);
-        static int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_new_object(STUB_ARGS);
-        static void JIT_STUB cti_op_put_by_id(STUB_ARGS);
-        static void JIT_STUB cti_op_put_by_id_second(STUB_ARGS);
-        static void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS);
-        static void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_second(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_generic(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_id(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_instanceof(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_mul(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_new_func(STUB_ARGS);
-        static void* JIT_STUB cti_op_call_JSFunction(STUB_ARGS);
-        static VoidPtrPair JIT_STUB cti_op_call_arityCheck(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS);
-        static void JIT_STUB cti_op_create_arguments(STUB_ARGS);
-        static void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS);
-        static void JIT_STUB cti_op_tear_off_activation(STUB_ARGS);
-        static void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS);
-        static void JIT_STUB cti_op_profile_will_call(STUB_ARGS);
-        static void JIT_STUB cti_op_profile_did_call(STUB_ARGS);
-        static void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_new_array(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_global(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_get_by_val_byte_array(STUB_ARGS);
-        static VoidPtrPair JIT_STUB cti_op_resolve_func(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_sub(STUB_ARGS);
-        static void JIT_STUB cti_op_put_by_val(STUB_ARGS);
-        static void JIT_STUB cti_op_put_by_val_array(STUB_ARGS);
-        static void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_lesseq(STUB_ARGS);
-        static int JIT_STUB cti_op_loop_if_true(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_base(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_negate(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_resolve_skip(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_div(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_pre_dec(STUB_ARGS);
-        static int JIT_STUB cti_op_jless(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_not(STUB_ARGS);
-        static int JIT_STUB cti_op_jtrue(STUB_ARGS);
-        static VoidPtrPair JIT_STUB cti_op_post_inc(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_eq(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_lshift(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_bitand(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_rshift(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_bitnot(STUB_ARGS);
-        static VoidPtrPair JIT_STUB cti_op_resolve_with_base(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_mod(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_less(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_neq(STUB_ARGS);
-        static VoidPtrPair JIT_STUB cti_op_post_dec(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_urshift(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_bitxor(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_bitor(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_call_eval(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_throw(STUB_ARGS);
-        static JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_next_pname(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS);
-        static void JIT_STUB cti_op_pop_scope(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_typeof(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_is_undefined(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_is_boolean(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_is_number(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_is_string(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_is_object(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_is_function(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_stricteq(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_nstricteq(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_to_jsnumber(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_in(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS);
-        static void JIT_STUB cti_op_jmp_scopes(STUB_ARGS);
-        static void JIT_STUB cti_op_put_by_index(STUB_ARGS);
-        static void* JIT_STUB cti_op_switch_imm(STUB_ARGS);
-        static void* JIT_STUB cti_op_switch_char(STUB_ARGS);
-        static void* JIT_STUB cti_op_switch_string(STUB_ARGS);
-        static JSValueEncodedAsPointer* JIT_STUB cti_op_del_by_val(STUB_ARGS);
-        static void JIT_STUB cti_op_put_getter(STUB_ARGS);
-        static void JIT_STUB cti_op_put_setter(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_new_error(STUB_ARGS);
-        static void JIT_STUB cti_op_debug(STUB_ARGS);
-
-        static JSValueEncodedAsPointer* JIT_STUB cti_vm_throw(STUB_ARGS);
-        static void* JIT_STUB cti_vm_dontLazyLinkCall(STUB_ARGS);
-        static void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS);
-        static JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS);
-        
-#endif // ENABLE(JIT)
-
-        // Default number of ticks before a timeout check should be done.
-        static const int initialTickCountThreshold = 1024;
-
-        bool isJSArray(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsArrayVptr; }
-        bool isJSString(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsStringVptr; }
-        bool isJSByteArray(JSValuePtr v) { return v.isCell() && v.asCell()->vptr() == m_jsByteArrayVptr; }
+        NEVER_INLINE JSValue callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset, JSValue& exceptionValue);
+        NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValue&, unsigned bytecodeOffset, bool);
+        NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
 
     private:
         enum ExecutionFlag { Normal, InitializeAndReturn };
 
-        NEVER_INLINE JSValuePtr callEval(CallFrame*, RegisterFile*, Register* argv, int argc, int registerOffset, JSValuePtr& exceptionValue);
-        JSValuePtr execute(EvalNode*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValuePtr* exception);
+        CallFrameClosure prepareForRepeatCall(FunctionBodyNode*, CallFrame*, JSFunction*, int argCount, ScopeChainNode*, JSValue* exception);
+        void endRepeatCall(CallFrameClosure&);
+        JSValue execute(CallFrameClosure&, JSValue* exception);
 
-        NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
+        JSValue execute(EvalNode*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValue* exception);
 
-        NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
-        NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
-        NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+#if USE(INTERPRETER)
+        NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValue& exceptionValue);
+        NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValue& exceptionValue);
+        NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValue& exceptionValue);
         NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
-        NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+        NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue);
+        NEVER_INLINE bool resolveBaseAndFunc(CallFrame*, Instruction*, JSValue& exceptionValue);
         NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
 
-        NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValuePtr, unsigned& bytecodeOffset, CodeBlock*&);
-        NEVER_INLINE HandlerInfo* throwException(CallFrame*&, JSValuePtr&, unsigned bytecodeOffset, bool);
-        NEVER_INLINE bool resolveBaseAndFunc(CallFrame*, Instruction*, JSValuePtr& exceptionValue);
+        void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
+        void uncacheGetByID(CodeBlock*, Instruction* vPC);
+        void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const PutPropertySlot&);
+        void uncachePutByID(CodeBlock*, Instruction* vPC);        
+#endif
+
+        NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
 
         static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
 
         static CallFrame* findFunctionCallFrame(CallFrame*, InternalFunction*);
 
-        JSValuePtr privateExecute(ExecutionFlag, RegisterFile*, CallFrame*, JSValuePtr* exception);
+        JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*, JSValue* exception);
 
         void dumpCallFrame(CallFrame*);
         void dumpRegisters(CallFrame*);
-
-        bool checkTimeout(JSGlobalObject*);
-        void resetTimeoutCheck();
-
-        void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot&);
-        void uncacheGetByID(CodeBlock*, Instruction* vPC);
-        void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValuePtr baseValue, const PutPropertySlot&);
-        void uncachePutByID(CodeBlock*, Instruction* vPC);
         
         bool isCallBytecode(Opcode opcode) { return opcode == getOpcode(op_call) || opcode == getOpcode(op_construct) || opcode == getOpcode(op_call_eval); }
 
-#if ENABLE(JIT)
-        static void throwStackOverflowPreviousFrame(CallFrame**, JSGlobalData*, void*& returnAddress);
-
-        void tryCTICacheGetByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot&);
-        void tryCTICachePutByID(CallFrame*, CodeBlock*, void* returnAddress, JSValuePtr baseValue, const PutPropertySlot&);
-#endif
-
         SamplingTool* m_sampler;
 
-#if ENABLE(JIT)
-        RefPtr<ExecutablePool> m_executablePool;
-        void* m_ctiArrayLengthTrampoline;
-        void* m_ctiStringLengthTrampoline;
-        void* m_ctiVirtualCallPreLink;
-        void* m_ctiVirtualCallLink;
-        void* m_ctiVirtualCall;
-#endif
-
         int m_reentryDepth;
-        unsigned m_timeoutTime;
-        unsigned m_timeAtLastCheckTimeout;
-        unsigned m_timeExecuting;
-        unsigned m_timeoutCheckCount;
-        unsigned m_ticksUntilNextTimeoutCheck;
 
         RegisterFile m_registerFile;
         
-        void* m_jsArrayVptr;
-        void* m_jsByteArrayVptr;
-        void* m_jsStringVptr;
-        void* m_jsFunctionVptr;
-
 #if HAVE(COMPUTED_GOTO)
         Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
         HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
 #endif
     };
-
+    
 } // namespace JSC
 
 #endif // Interpreter_h
index ff36bbcb54c3aef86cd1ee8952d90ef60bd58c0d..e1598122f6bbd0bf931a4dcfe7a9f9db1b5525ae 100644 (file)
@@ -30,6 +30,8 @@
 #define Register_h
 
 #include "JSValue.h"
+#include <wtf/Assertions.h>
+#include <wtf/FastAllocBase.h>
 #include <wtf/VectorTraits.h>
 
 namespace JSC {
@@ -46,37 +48,26 @@ namespace JSC {
 
     typedef ExecState CallFrame;
 
-    class Register {
+    class Register : public WTF::FastAllocBase {
     public:
         Register();
-        Register(JSValuePtr);
 
-        JSValuePtr jsValue(CallFrame*) const;
-        JSValuePtr getJSValue() const;
+        Register(const JSValue&);
+        Register& operator=(const JSValue&);
+        JSValue jsValue() const;
 
         bool marked() const;
         void mark();
         
-    private:
-        friend class ExecState;
-        friend class Interpreter;
-
-        // Only CallFrame and Interpreter should use these functions.
-
-        Register(intptr_t);
-
-        Register(JSActivation*);
-        Register(Arguments*);
-        Register(CallFrame*);
-        Register(CodeBlock*);
-        Register(JSFunction*);
-        Register(JSPropertyNameIterator*);
-        Register(ScopeChainNode*);
-        Register(Instruction*);
-
-        intptr_t i() const;
-        void* v() const;
-
+        Register& operator=(JSActivation*);
+        Register& operator=(CallFrame*);
+        Register& operator=(CodeBlock*);
+        Register& operator=(JSFunction*);
+        Register& operator=(JSPropertyNameIterator*);
+        Register& operator=(ScopeChainNode*);
+        Register& operator=(Instruction*);
+
+        int32_t i() const;
         JSActivation* activation() const;
         Arguments* arguments() const;
         CallFrame* callFrame() const;
@@ -86,13 +77,19 @@ namespace JSC {
         ScopeChainNode* scopeChain() const;
         Instruction* vPC() const;
 
+        static Register withInt(int32_t i)
+        {
+            Register r;
+            r.u.i = i;
+            return r;
+        }
+
+    private:
         union {
-            intptr_t i;
-            void* v;
-            JSValueEncodedAsPointer* value;
+            int32_t i;
+            EncodedJSValue value;
 
             JSActivation* activation;
-            Arguments* arguments;
             CallFrame* callFrame;
             CodeBlock* codeBlock;
             JSFunction* function;
@@ -100,194 +97,128 @@ namespace JSC {
             ScopeChainNode* scopeChain;
             Instruction* vPC;
         } u;
-
-#ifndef NDEBUG
-        enum {
-            EmptyType,
-
-            IntType,
-            ValueType,
-
-            ActivationType,
-            ArgumentsType,
-            CallFrameType,
-            CodeBlockType,
-            FunctionType,
-            InstructionType,
-            PropertyNameIteratorType,
-            RegisterType,
-            ScopeChainNodeType
-        } m_type;
-#endif
     };
 
-#ifndef NDEBUG
-    #define SET_TYPE(type) m_type = (type)
-    // FIXME: The CTI code to put value into registers doesn't set m_type.
-    // Once it does, we can turn this assertion back on.
-    #define ASSERT_TYPE(type)
-#else
-    #define SET_TYPE(type)
-    #define ASSERT_TYPE(type)
-#endif
-
     ALWAYS_INLINE Register::Register()
     {
 #ifndef NDEBUG
-        SET_TYPE(EmptyType);
-        u.value = JSValuePtr::encode(noValue());
+        *this = JSValue();
 #endif
     }
 
-    ALWAYS_INLINE Register::Register(JSValuePtr v)
+    ALWAYS_INLINE Register::Register(const JSValue& v)
     {
-        SET_TYPE(ValueType);
-        u.value = JSValuePtr::encode(v);
+        u.value = JSValue::encode(v);
     }
 
-    // This function is scaffolding for legacy clients. It will eventually go away.
-    ALWAYS_INLINE JSValuePtr Register::jsValue(CallFrame*) const
+    ALWAYS_INLINE Register& Register::operator=(const JSValue& v)
     {
-        // Once registers hold doubles, this function will allocate a JSValue*
-        // if the register doesn't hold one already. 
-        ASSERT_TYPE(ValueType);
-        return JSValuePtr::decode(u.value);
+#if ENABLE(JSC_ZOMBIES)
+        ASSERT(!v.isZombie());
+#endif
+        u.value = JSValue::encode(v);
+        return *this;
     }
-    
-    ALWAYS_INLINE JSValuePtr Register::getJSValue() const
+
+    ALWAYS_INLINE JSValue Register::jsValue() const
     {
-        ASSERT_TYPE(JSValueType);
-        return JSValuePtr::decode(u.value);
+        return JSValue::decode(u.value);
     }
     
     ALWAYS_INLINE bool Register::marked() const
     {
-        return getJSValue().marked();
+        return jsValue().marked();
     }
 
     ALWAYS_INLINE void Register::mark()
     {
-        getJSValue().mark();
+        jsValue().mark();
     }
     
     // Interpreter functions
 
-    ALWAYS_INLINE Register::Register(Arguments* arguments)
-    {
-        SET_TYPE(ArgumentsType);
-        u.arguments = arguments;
-    }
-
-    ALWAYS_INLINE Register::Register(JSActivation* activation)
+    ALWAYS_INLINE Register& Register::operator=(JSActivation* activation)
     {
-        SET_TYPE(ActivationType);
         u.activation = activation;
+        return *this;
     }
 
-    ALWAYS_INLINE Register::Register(CallFrame* callFrame)
+    ALWAYS_INLINE Register& Register::operator=(CallFrame* callFrame)
     {
-        SET_TYPE(CallFrameType);
         u.callFrame = callFrame;
+        return *this;
     }
 
-    ALWAYS_INLINE Register::Register(CodeBlock* codeBlock)
+    ALWAYS_INLINE Register& Register::operator=(CodeBlock* codeBlock)
     {
-        SET_TYPE(CodeBlockType);
         u.codeBlock = codeBlock;
+        return *this;
     }
 
-    ALWAYS_INLINE Register::Register(JSFunction* function)
+    ALWAYS_INLINE Register& Register::operator=(JSFunction* function)
     {
-        SET_TYPE(FunctionType);
         u.function = function;
+        return *this;
     }
 
-    ALWAYS_INLINE Register::Register(Instruction* vPC)
+    ALWAYS_INLINE Register& Register::operator=(Instruction* vPC)
     {
-        SET_TYPE(InstructionType);
         u.vPC = vPC;
+        return *this;
     }
 
-    ALWAYS_INLINE Register::Register(ScopeChainNode* scopeChain)
+    ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain)
     {
-        SET_TYPE(ScopeChainNodeType);
         u.scopeChain = scopeChain;
+        return *this;
     }
 
-    ALWAYS_INLINE Register::Register(JSPropertyNameIterator* propertyNameIterator)
+    ALWAYS_INLINE Register& Register::operator=(JSPropertyNameIterator* propertyNameIterator)
     {
-        SET_TYPE(PropertyNameIteratorType);
         u.propertyNameIterator = propertyNameIterator;
+        return *this;
     }
 
-    ALWAYS_INLINE Register::Register(intptr_t i)
-    {
-        SET_TYPE(IntType);
-        u.i = i;
-    }
-
-    ALWAYS_INLINE intptr_t Register::i() const
+    ALWAYS_INLINE int32_t Register::i() const
     {
-        ASSERT_TYPE(IntType);
         return u.i;
     }
     
-    ALWAYS_INLINE void* Register::v() const
-    {
-        return u.v;
-    }
-
     ALWAYS_INLINE JSActivation* Register::activation() const
     {
-        ASSERT_TYPE(ActivationType);
         return u.activation;
     }
     
-    ALWAYS_INLINE Arguments* Register::arguments() const
-    {
-        ASSERT_TYPE(ArgumentsType);
-        return u.arguments;
-    }
-    
     ALWAYS_INLINE CallFrame* Register::callFrame() const
     {
-        ASSERT_TYPE(CallFrameType);
         return u.callFrame;
     }
     
     ALWAYS_INLINE CodeBlock* Register::codeBlock() const
     {
-        ASSERT_TYPE(CodeBlockType);
         return u.codeBlock;
     }
     
     ALWAYS_INLINE JSFunction* Register::function() const
     {
-        ASSERT_TYPE(FunctionType);
         return u.function;
     }
     
     ALWAYS_INLINE JSPropertyNameIterator* Register::propertyNameIterator() const
     {
-        ASSERT_TYPE(PropertyNameIteratorType);
         return u.propertyNameIterator;
     }
     
     ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const
     {
-        ASSERT_TYPE(ScopeChainNodeType);
         return u.scopeChain;
     }
     
     ALWAYS_INLINE Instruction* Register::vPC() const
     {
-        ASSERT_TYPE(InstructionType);
         return u.vPC;
     }
 
-    #undef SET_TYPE
-    #undef ASSERT_TYPE
-
 } // namespace JSC
 
 namespace WTF {
index 50698f5f010ef3191e7a69eeb2cb772d848e3dbc..cfcf1d36277b3d5b06c7b6daf09ee3aeefe80abb 100644 (file)
@@ -42,4 +42,15 @@ RegisterFile::~RegisterFile()
 #endif
 }
 
+void RegisterFile::releaseExcessCapacity()
+{
+#if HAVE(MMAP) && HAVE(MADV_FREE) && !HAVE(VIRTUALALLOC)
+    while (madvise(m_start, (m_max - m_start) * sizeof(Register), MADV_FREE) == -1 && errno == EAGAIN) { }
+#elif HAVE(VIRTUALALLOC)
+    VirtualFree(m_start, (m_max - m_start) * sizeof(Register), MEM_DECOMMIT);
+    m_commitEnd = m_start;
+#endif
+    m_maxUsed = m_start;
+}
+
 } // namespace JSC
index ec190d64497bb9d32ae660be47078ba34d5ae163..3a6e63b9e973a9943544dc46c18c5610062cb977 100644 (file)
 #ifndef RegisterFile_h
 #define RegisterFile_h
 
-#include "Register.h"
 #include "Collector.h"
+#include "ExecutableAllocator.h"
+#include "Register.h"
 #include <wtf/Noncopyable.h>
+#include <wtf/VMTags.h>
 
 #if HAVE(MMAP)
 #include <errno.h>
@@ -111,48 +113,11 @@ namespace JSC {
 
         static const size_t defaultCapacity = 524288;
         static const size_t defaultMaxGlobals = 8192;
-        static const size_t allocationSize = 1 << 14;
-        static const size_t allocationSizeMask = allocationSize - 1;
-
-        RegisterFile(size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals)
-            : m_numGlobals(0)
-            , m_maxGlobals(maxGlobals)
-            , m_start(0)
-            , m_end(0)
-            , m_max(0)
-            , m_buffer(0)
-            , m_globalObject(0)
-        {
-            size_t bufferLength = (capacity + maxGlobals) * sizeof(Register);
-#if HAVE(MMAP)
-            m_buffer = static_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0));
-            if (m_buffer == MAP_FAILED) {
-                fprintf(stderr, "Could not allocate register file: %d\n", errno);
-                CRASH();
-            }
-#elif HAVE(VIRTUALALLOC)
-            // Ensure bufferLength is a multiple of allocation size
-            bufferLength = (bufferLength + allocationSizeMask) & ~allocationSizeMask;
-            m_buffer = static_cast<Register*>(VirtualAlloc(0, bufferLength, MEM_RESERVE, PAGE_READWRITE));
-            if (!m_buffer) {
-                fprintf(stderr, "Could not allocate register file: %d\n", errno);
-                CRASH();
-            }
-            int initialAllocation = (maxGlobals * sizeof(Register) + allocationSizeMask) & ~allocationSizeMask;
-            void* commitCheck = VirtualAlloc(m_buffer, initialAllocation, MEM_COMMIT, PAGE_READWRITE);
-            if (commitCheck != m_buffer) {
-                fprintf(stderr, "Could not allocate register file: %d\n", errno);
-                CRASH();
-            }
-            m_maxCommitted = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_buffer) + initialAllocation);
-#else
-            #error "Don't know how to reserve virtual memory on this platform."
-#endif
-            m_start = m_buffer + maxGlobals;
-            m_end = m_start;
-            m_max = m_start + capacity;
-        }
+        static const size_t commitSize = 1 << 14;
+        // Allow 8k of excess registers before we start trying to reap the registerfile
+        static const ptrdiff_t maxExcessCapacity = 8 * 1024;
 
+        RegisterFile(size_t capacity = defaultCapacity, size_t maxGlobals = defaultMaxGlobals);
         ~RegisterFile();
 
         Register* start() const { return m_start; }
@@ -162,31 +127,8 @@ namespace JSC {
         void setGlobalObject(JSGlobalObject* globalObject) { m_globalObject = globalObject; }
         JSGlobalObject* globalObject() { return m_globalObject; }
 
-        void shrink(Register* newEnd)
-        {
-            if (newEnd < m_end)
-                m_end = newEnd;
-        }
-
-        bool grow(Register* newEnd)
-        {
-            if (newEnd > m_end) {
-                if (newEnd > m_max)
-                    return false;
-#if !HAVE(MMAP) && HAVE(VIRTUALALLOC)
-                if (newEnd > m_maxCommitted) {
-                    ptrdiff_t additionalAllocation = ((reinterpret_cast<char*>(newEnd)  - reinterpret_cast<char*>(m_maxCommitted)) + allocationSizeMask) & ~allocationSizeMask;
-                    if (!VirtualAlloc(m_maxCommitted, additionalAllocation, MEM_COMMIT, PAGE_READWRITE)) {
-                        fprintf(stderr, "Could not allocate register file: %d\n", errno);
-                        CRASH();
-                    }
-                    m_maxCommitted = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_maxCommitted) + additionalAllocation);
-                }
-#endif
-                m_end = newEnd;
-            }
-            return true;
-        }
+        bool grow(Register* newEnd);
+        void shrink(Register* newEnd);
         
         void setNumGlobals(size_t numGlobals) { m_numGlobals = numGlobals; }
         int numGlobals() const { return m_numGlobals; }
@@ -198,19 +140,118 @@ namespace JSC {
         void markCallFrames(Heap* heap) { heap->markConservatively(m_start, m_end); }
 
     private:
+        void releaseExcessCapacity();
         size_t m_numGlobals;
         const size_t m_maxGlobals;
         Register* m_start;
         Register* m_end;
         Register* m_max;
         Register* m_buffer;
+        Register* m_maxUsed;
+
 #if HAVE(VIRTUALALLOC)
-        Register* m_maxCommitted;
+        Register* m_commitEnd;
 #endif
 
         JSGlobalObject* m_globalObject; // The global object whose vars are currently stored in the register file.
     };
 
+    // FIXME: Add a generic getpagesize() to WTF, then move this function to WTF as well.
+    inline bool isPageAligned(size_t size) { return size != 0 && size % (8 * 1024) == 0; }
+
+    inline RegisterFile::RegisterFile(size_t capacity, size_t maxGlobals)
+        : m_numGlobals(0)
+        , m_maxGlobals(maxGlobals)
+        , m_start(0)
+        , m_end(0)
+        , m_max(0)
+        , m_buffer(0)
+        , m_globalObject(0)
+    {
+        // Verify that our values will play nice with mmap and VirtualAlloc.
+        ASSERT(isPageAligned(maxGlobals));
+        ASSERT(isPageAligned(capacity));
+
+        size_t bufferLength = (capacity + maxGlobals) * sizeof(Register);
+    #if HAVE(MMAP)
+        m_buffer = static_cast<Register*>(mmap(0, bufferLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, VM_TAG_FOR_REGISTERFILE_MEMORY, 0));
+        if (m_buffer == MAP_FAILED) {
+#if PLATFORM(WINCE)
+            fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
+#else
+            fprintf(stderr, "Could not allocate register file: %d\n", errno);
+#endif
+            CRASH();
+        }
+    #elif HAVE(VIRTUALALLOC)
+        m_buffer = static_cast<Register*>(VirtualAlloc(0, roundUpAllocationSize(bufferLength, commitSize), MEM_RESERVE, PAGE_READWRITE));
+        if (!m_buffer) {
+#if PLATFORM(WINCE)
+            fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
+#else
+            fprintf(stderr, "Could not allocate register file: %d\n", errno);
+#endif
+            CRASH();
+        }
+        size_t committedSize = roundUpAllocationSize(maxGlobals * sizeof(Register), commitSize);
+        void* commitCheck = VirtualAlloc(m_buffer, committedSize, MEM_COMMIT, PAGE_READWRITE);
+        if (commitCheck != m_buffer) {
+#if PLATFORM(WINCE)
+            fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
+#else
+            fprintf(stderr, "Could not allocate register file: %d\n", errno);
+#endif
+            CRASH();
+        }
+        m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_buffer) + committedSize);
+    #else
+        #error "Don't know how to reserve virtual memory on this platform."
+    #endif
+        m_start = m_buffer + maxGlobals;
+        m_end = m_start;
+        m_maxUsed = m_end;
+        m_max = m_start + capacity;
+    }
+
+    inline void RegisterFile::shrink(Register* newEnd)
+    {
+        if (newEnd >= m_end)
+            return;
+        m_end = newEnd;
+        if (m_end == m_start && (m_maxUsed - m_start) > maxExcessCapacity)
+            releaseExcessCapacity();
+    }
+
+    inline bool RegisterFile::grow(Register* newEnd)
+    {
+        if (newEnd < m_end)
+            return true;
+
+        if (newEnd > m_max)
+            return false;
+
+#if !HAVE(MMAP) && HAVE(VIRTUALALLOC)
+        if (newEnd > m_commitEnd) {
+            size_t size = roundUpAllocationSize(reinterpret_cast<char*>(newEnd) - reinterpret_cast<char*>(m_commitEnd), commitSize);
+            if (!VirtualAlloc(m_commitEnd, size, MEM_COMMIT, PAGE_READWRITE)) {
+#if PLATFORM(WINCE)
+                fprintf(stderr, "Could not allocate register file: %d\n", GetLastError());
+#else
+                fprintf(stderr, "Could not allocate register file: %d\n", errno);
+#endif
+                CRASH();
+            }
+            m_commitEnd = reinterpret_cast<Register*>(reinterpret_cast<char*>(m_commitEnd) + size);
+        }
+#endif
+
+        if (newEnd > m_maxUsed)
+            m_maxUsed = newEnd;
+
+        m_end = newEnd;
+        return true;
+    }
+
 } // namespace JSC
 
 #endif // RegisterFile_h
index 154125642e1f8eb5b0996216cd10e2c87674cab5..5223bf38fcd7f7f5aa1e126e52783afe08ab4b94 100644 (file)
 #ifndef ExecutableAllocator_h
 #define ExecutableAllocator_h
 
-#if ENABLE(ASSEMBLER)
-
+#include <limits>
 #include <wtf/Assertions.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
+#include <wtf/UnusedParam.h>
 #include <wtf/Vector.h>
 
-#include <limits>
+#include <libkern/OSCacheControl.h>
+#include <sys/mman.h>
 
 #define JIT_ALLOCATOR_PAGE_SIZE (ExecutableAllocator::pageSize)
 #define JIT_ALLOCATOR_LARGE_ALLOC_SIZE (ExecutableAllocator::pageSize * 4)
 
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+#define PROTECTION_FLAGS_RW (PROT_READ | PROT_WRITE)
+#define PROTECTION_FLAGS_RX (PROT_READ | PROT_EXEC)
+#define INITIAL_PROTECTION_FLAGS PROTECTION_FLAGS_RX
+#else
+#define INITIAL_PROTECTION_FLAGS (PROT_READ | PROT_WRITE | PROT_EXEC)
+#endif
+
+namespace JSC {
+
+inline size_t roundUpAllocationSize(size_t request, size_t granularity)
+{
+    if ((std::numeric_limits<size_t>::max() - granularity) <= request)
+        CRASH(); // Allocation is too large
+    
+    // Round up to next page boundary
+    size_t size = request + (granularity - 1);
+    size = size & ~(granularity - 1);
+    ASSERT(size >= request);
+    return size;
+}
+
+}
+
+#if ENABLE(ASSEMBLER)
+
 namespace JSC {
 
 class ExecutablePool : public RefCounted<ExecutablePool> {
@@ -86,18 +113,6 @@ private:
     static Allocation systemAlloc(size_t n);
     static void systemRelease(const Allocation& alloc);
 
-    inline size_t roundUpAllocationSize(size_t request, size_t granularity)
-    {
-        if ((std::numeric_limits<size_t>::max() - granularity) <= request)
-            CRASH(); // Allocation is too large
-        
-        // Round up to next page boundary
-        size_t size = request + (granularity - 1);
-        size = size & ~(granularity - 1);
-        ASSERT(size >= request);
-        return size;
-    }
-
     ExecutablePool(size_t n);
 
     void* poolAllocate(size_t n);
@@ -108,6 +123,8 @@ private:
 };
 
 class ExecutableAllocator {
+    enum ProtectionSeting { Writable, Executable };
+
 public:
     static size_t pageSize;
     ExecutableAllocator()
@@ -137,7 +154,42 @@ public:
         return pool.release();
     }
 
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+    static void makeWritable(void* start, size_t size)
+    {
+        reprotectRegion(start, size, Writable);
+    }
+
+    static void makeExecutable(void* start, size_t size)
+    {
+        reprotectRegion(start, size, Executable);
+    }
+#else
+    static void makeWritable(void*, size_t) {}
+    static void makeExecutable(void*, size_t) {}
+#endif
+
+
+#if PLATFORM(X86) || PLATFORM(X86_64)
+    static void cacheFlush(void*, size_t)
+    {
+    }
+#elif PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE)
+    static void cacheFlush(void* code, size_t size)
+    {
+        sys_dcache_flush(code, size);
+        sys_icache_invalidate(code, size);
+    }
+#else
+#error "ExecutableAllocator::cacheFlush not implemented on this platform."
+#endif
+
 private:
+
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+    static void reprotectRegion(void*, size_t, ProtectionSeting);
+#endif
+
     RefPtr<ExecutablePool> m_smallAllocationPool;
     static void intializePageSize();
 };
@@ -173,7 +225,6 @@ inline void* ExecutablePool::poolAllocate(size_t n)
 }
 
 }
-
 #endif // ENABLE(ASSEMBLER)
 
 #endif // !defined(ExecutableAllocator)
diff --git a/jit/ExecutableAllocatorFixedVMPool.cpp b/jit/ExecutableAllocatorFixedVMPool.cpp
new file mode 100644 (file)
index 0000000..7682b9c
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+
+#include "ExecutableAllocator.h"
+
+#include <errno.h>
+
+#if ENABLE(ASSEMBLER) && PLATFORM(MAC) && PLATFORM(X86_64)
+
+#include "TCSpinLock.h"
+#include <mach/mach_init.h>
+#include <mach/vm_map.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <wtf/AVLTree.h>
+#include <wtf/VMTags.h>
+
+using namespace WTF;
+
+namespace JSC {
+
+#define TWO_GB (2u * 1024u * 1024u * 1024u)
+#define SIXTEEN_MB (16u * 1024u * 1024u)
+
+// FreeListEntry describes a free chunk of memory, stored in the freeList.
+struct FreeListEntry {
+    FreeListEntry(void* pointer, size_t size)
+        : pointer(pointer)
+        , size(size)
+        , nextEntry(0)
+        , less(0)
+        , greater(0)
+        , balanceFactor(0)
+    {
+    }
+
+    // All entries of the same size share a single entry
+    // in the AVLTree, and are linked together in a linked
+    // list, using nextEntry.
+    void* pointer;
+    size_t size;
+    FreeListEntry* nextEntry;
+
+    // These fields are used by AVLTree.
+    FreeListEntry* less;
+    FreeListEntry* greater;
+    int balanceFactor;
+};
+
+// Abstractor class for use in AVLTree.
+// Nodes in the AVLTree are of type FreeListEntry, keyed on
+// (and thus sorted by) their size.
+struct AVLTreeAbstractorForFreeList {
+    typedef FreeListEntry* handle;
+    typedef int32_t size;
+    typedef size_t key;
+
+    handle get_less(handle h) { return h->less; }
+    void set_less(handle h, handle lh) { h->less = lh; }
+    handle get_greater(handle h) { return h->greater; }
+    void set_greater(handle h, handle gh) { h->greater = gh; }
+    int get_balance_factor(handle h) { return h->balanceFactor; }
+    void set_balance_factor(handle h, int bf) { h->balanceFactor = bf; }
+
+    static handle null() { return 0; }
+
+    int compare_key_key(key va, key vb) { return va - vb; }
+    int compare_key_node(key k, handle h) { return compare_key_key(k, h->size); }
+    int compare_node_node(handle h1, handle h2) { return compare_key_key(h1->size, h2->size); }
+};
+
+// Used to reverse sort an array of FreeListEntry pointers.
+static int reverseSortFreeListEntriesByPointer(const void* leftPtr, const void* rightPtr)
+{
+    FreeListEntry* left = *(FreeListEntry**)leftPtr;
+    FreeListEntry* right = *(FreeListEntry**)rightPtr;
+
+    return (intptr_t)(right->pointer) - (intptr_t)(left->pointer);
+}
+
+// Used to reverse sort an array of pointers.
+static int reverseSortCommonSizedAllocations(const void* leftPtr, const void* rightPtr)
+{
+    void* left = *(void**)leftPtr;
+    void* right = *(void**)rightPtr;
+
+    return (intptr_t)right - (intptr_t)left;
+}
+
+class FixedVMPoolAllocator
+{
+    // The free list is stored in a sorted tree.
+    typedef AVLTree<AVLTreeAbstractorForFreeList, 40> SizeSortedFreeTree;
+
+    // Use madvise as apropriate to prevent freed pages from being spilled,
+    // and to attempt to ensure that used memory is reported correctly.
+#if HAVE(MADV_FREE_REUSE)
+    void release(void* position, size_t size)
+    {
+        while (madvise(position, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
+    }
+
+    void reuse(void* position, size_t size)
+    {
+        while (madvise(position, size, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
+    }
+#elif HAVE(MADV_DONTNEED)
+    void release(void* position, size_t size)
+    {
+        while (madvise(position, size, MADV_DONTNEED) == -1 && errno == EAGAIN) { }
+    }
+
+    void reuse(void*, size_t) {}
+#else
+    void release(void*, size_t) {}
+    void reuse(void*, size_t) {}
+#endif
+
+    // All addition to the free list should go through this method, rather than
+    // calling insert directly, to avoid multiple entries beging added with the
+    // same key.  All nodes being added should be singletons, they should not
+    // already be a part of a chain.
+    void addToFreeList(FreeListEntry* entry)
+    {
+        ASSERT(!entry->nextEntry);
+
+        if (entry->size == m_commonSize) {
+            m_commonSizedAllocations.append(entry->pointer);
+            delete entry;
+        } else if (FreeListEntry* entryInFreeList = m_freeList.search(entry->size, m_freeList.EQUAL)) {
+            // m_freeList already contain an entry for this size - insert this node into the chain.
+            entry->nextEntry = entryInFreeList->nextEntry;
+            entryInFreeList->nextEntry = entry;
+        } else
+            m_freeList.insert(entry);
+    }
+
+    // We do not attempt to coalesce addition, which may lead to fragmentation;
+    // instead we periodically perform a sweep to try to coalesce neigboring
+    // entries in m_freeList.  Presently this is triggered at the point 16MB
+    // of memory has been released.
+    void coalesceFreeSpace()
+    {
+        Vector<FreeListEntry*> freeListEntries;
+        SizeSortedFreeTree::Iterator iter;
+        iter.start_iter_least(m_freeList);
+
+        // Empty m_freeList into a Vector.
+        for (FreeListEntry* entry; (entry = *iter); ++iter) {
+            // Each entry in m_freeList might correspond to multiple
+            // free chunks of memory (of the same size).  Walk the chain
+            // (this is likely of couse only be one entry long!) adding
+            // each entry to the Vector (at reseting the next in chain
+            // pointer to separate each node out).
+            FreeListEntry* next;
+            do {
+                next = entry->nextEntry;
+                entry->nextEntry = 0;
+                freeListEntries.append(entry);
+            } while ((entry = next));
+        }
+        // All entries are now in the Vector; purge the tree.
+        m_freeList.purge();
+
+        // Reverse-sort the freeListEntries and m_commonSizedAllocations Vectors.
+        // We reverse-sort so that we can logically work forwards through memory,
+        // whilst popping items off the end of the Vectors using last() and removeLast().
+        qsort(freeListEntries.begin(), freeListEntries.size(), sizeof(FreeListEntry*), reverseSortFreeListEntriesByPointer);
+        qsort(m_commonSizedAllocations.begin(), m_commonSizedAllocations.size(), sizeof(void*), reverseSortCommonSizedAllocations);
+
+        // The entries from m_commonSizedAllocations that cannot be
+        // coalesced into larger chunks will be temporarily stored here.
+        Vector<void*> newCommonSizedAllocations;
+
+        // Keep processing so long as entries remain in either of the vectors.
+        while (freeListEntries.size() || m_commonSizedAllocations.size()) {
+            // We're going to try to find a FreeListEntry node that we can coalesce onto.
+            FreeListEntry* coalescionEntry = 0;
+
+            // Is the lowest addressed chunk of free memory of common-size, or is it in the free list?
+            if (m_commonSizedAllocations.size() && (!freeListEntries.size() || (m_commonSizedAllocations.last() < freeListEntries.last()->pointer))) {
+                // Pop an item from the m_commonSizedAllocations vector - this is the lowest
+                // addressed free chunk.  Find out the begin and end addresses of the memory chunk.
+                void* begin = m_commonSizedAllocations.last();
+                void* end = (void*)((intptr_t)begin + m_commonSize);
+                m_commonSizedAllocations.removeLast();
+
+                // Try to find another free chunk abutting onto the end of the one we have already found.
+                if (freeListEntries.size() && (freeListEntries.last()->pointer == end)) {
+                    // There is an existing FreeListEntry for the next chunk of memory!
+                    // we can reuse this.  Pop it off the end of m_freeList.
+                    coalescionEntry = freeListEntries.last();
+                    freeListEntries.removeLast();
+                    // Update the existing node to include the common-sized chunk that we also found. 
+                    coalescionEntry->pointer = (void*)((intptr_t)coalescionEntry->pointer - m_commonSize);
+                    coalescionEntry->size += m_commonSize;
+                } else if (m_commonSizedAllocations.size() && (m_commonSizedAllocations.last() == end)) {
+                    // There is a second common-sized chunk that can be coalesced.
+                    // Allocate a new node.
+                    m_commonSizedAllocations.removeLast();
+                    coalescionEntry = new FreeListEntry(begin, 2 * m_commonSize);
+                } else {
+                    // Nope - this poor little guy is all on his own. :-(
+                    // Add him into the newCommonSizedAllocations vector for now, we're
+                    // going to end up adding him back into the m_commonSizedAllocations
+                    // list when we're done.
+                    newCommonSizedAllocations.append(begin);
+                    continue;
+                }
+            } else {
+                ASSERT(freeListEntries.size());
+                ASSERT(!m_commonSizedAllocations.size() || (freeListEntries.last()->pointer < m_commonSizedAllocations.last()));
+                // The lowest addressed item is from m_freeList; pop it from the Vector.
+                coalescionEntry = freeListEntries.last();
+                freeListEntries.removeLast();
+            }
+            
+            // Right, we have a FreeListEntry, we just need check if there is anything else
+            // to coalesce onto the end.
+            ASSERT(coalescionEntry);
+            while (true) {
+                // Calculate the end address of the chunk we have found so far.
+                void* end = (void*)((intptr_t)coalescionEntry->pointer - coalescionEntry->size);
+
+                // Is there another chunk adjacent to the one we already have?
+                if (freeListEntries.size() && (freeListEntries.last()->pointer == end)) {
+                    // Yes - another FreeListEntry -pop it from the list.
+                    FreeListEntry* coalescee = freeListEntries.last();
+                    freeListEntries.removeLast();
+                    // Add it's size onto our existing node.
+                    coalescionEntry->size += coalescee->size;
+                    delete coalescee;
+                } else if (m_commonSizedAllocations.size() && (m_commonSizedAllocations.last() == end)) {
+                    // We can coalesce the next common-sized chunk.
+                    m_commonSizedAllocations.removeLast();
+                    coalescionEntry->size += m_commonSize;
+                } else
+                    break; // Nope, nothing to be added - stop here.
+            }
+
+            // We've coalesced everything we can onto the current chunk.
+            // Add it back into m_freeList.
+            addToFreeList(coalescionEntry);
+        }
+
+        // All chunks of free memory larger than m_commonSize should be
+        // back in m_freeList by now.  All that remains to be done is to
+        // copy the contents on the newCommonSizedAllocations back into
+        // the m_commonSizedAllocations Vector.
+        ASSERT(m_commonSizedAllocations.size() == 0);
+        m_commonSizedAllocations.append(newCommonSizedAllocations);
+    }
+
+public:
+
+    FixedVMPoolAllocator(size_t commonSize, size_t totalHeapSize)
+        : m_commonSize(commonSize)
+        , m_countFreedSinceLastCoalesce(0)
+        , m_totalHeapSize(totalHeapSize)
+    {
+        // Cook up an address to allocate at, using the following recipe:
+        //   17 bits of zero, stay in userspace kids.
+        //   26 bits of randomness for ASLR.
+        //   21 bits of zero, at least stay aligned within one level of the pagetables.
+        //
+        // But! - as a temporary workaround for some plugin problems (rdar://problem/6812854),
+        // for now instead of 2^26 bits of ASLR lets stick with 25 bits of randomization plus
+        // 2^24, which should put up somewhere in the middle of usespace (in the address range
+        // 0x200000000000 .. 0x5fffffffffff).
+        intptr_t randomLocation = arc4random() & ((1 << 25) - 1);
+        randomLocation += (1 << 24);
+        randomLocation <<= 21;
+        m_base = mmap(reinterpret_cast<void*>(randomLocation), m_totalHeapSize, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0);
+        if (!m_base)
+            CRASH();
+
+        // For simplicity, we keep all memory in m_freeList in a 'released' state.
+        // This means that we can simply reuse all memory when allocating, without
+        // worrying about it's previous state, and also makes coalescing m_freeList
+        // simpler since we need not worry about the possibility of coalescing released
+        // chunks with non-released ones.
+        release(m_base, m_totalHeapSize);
+        m_freeList.insert(new FreeListEntry(m_base, m_totalHeapSize));
+    }
+
+    void* alloc(size_t size)
+    {
+        void* result;
+
+        // Freed allocations of the common size are not stored back into the main
+        // m_freeList, but are instead stored in a separate vector.  If the request
+        // is for a common sized allocation, check this list.
+        if ((size == m_commonSize) && m_commonSizedAllocations.size()) {
+            result = m_commonSizedAllocations.last();
+            m_commonSizedAllocations.removeLast();
+        } else {
+            // Serach m_freeList for a suitable sized chunk to allocate memory from.
+            FreeListEntry* entry = m_freeList.search(size, m_freeList.GREATER_EQUAL);
+
+            // This would be bad news.
+            if (!entry) {
+                // Errk!  Lets take a last-ditch desparation attempt at defragmentation...
+                coalesceFreeSpace();
+                // Did that free up a large enough chunk?
+                entry = m_freeList.search(size, m_freeList.GREATER_EQUAL);
+                // No?...  *BOOM!*
+                if (!entry)
+                    CRASH();
+            }
+            ASSERT(entry->size != m_commonSize);
+
+            // Remove the entry from m_freeList.  But! -
+            // Each entry in the tree may represent a chain of multiple chunks of the
+            // same size, and we only want to remove one on them.  So, if this entry
+            // does have a chain, just remove the first-but-one item from the chain.
+            if (FreeListEntry* next = entry->nextEntry) {
+                // We're going to leave 'entry' in the tree; remove 'next' from its chain.
+                entry->nextEntry = next->nextEntry;
+                next->nextEntry = 0;
+                entry = next;
+            } else
+                m_freeList.remove(entry->size);
+
+            // Whoo!, we have a result!
+            ASSERT(entry->size >= size);
+            result = entry->pointer;
+
+            // If the allocation exactly fits the chunk we found in the,
+            // m_freeList then the FreeListEntry node is no longer needed.
+            if (entry->size == size)
+                delete entry;
+            else {
+                // There is memory left over, and it is not of the common size.
+                // We can reuse the existing FreeListEntry node to add this back
+                // into m_freeList.
+                entry->pointer = (void*)((intptr_t)entry->pointer + size);
+                entry->size -= size;
+                addToFreeList(entry);
+            }
+        }
+
+        // Call reuse to report to the operating system that this memory is in use.
+        ASSERT(isWithinVMPool(result, size));
+        reuse(result, size);
+        return result;
+    }
+
+    void free(void* pointer, size_t size)
+    {
+        // Call release to report to the operating system that this
+        // memory is no longer in use, and need not be paged out.
+        ASSERT(isWithinVMPool(pointer, size));
+        release(pointer, size);
+
+        // Common-sized allocations are stored in the m_commonSizedAllocations
+        // vector; all other freed chunks are added to m_freeList.
+        if (size == m_commonSize)
+            m_commonSizedAllocations.append(pointer);
+        else
+            addToFreeList(new FreeListEntry(pointer, size));
+
+        // Do some housekeeping.  Every time we reach a point that
+        // 16MB of allocations have been freed, sweep m_freeList
+        // coalescing any neighboring fragments.
+        m_countFreedSinceLastCoalesce += size;
+        if (m_countFreedSinceLastCoalesce >= SIXTEEN_MB) {
+            m_countFreedSinceLastCoalesce = 0;
+            coalesceFreeSpace();
+        }
+    }
+
+private:
+
+#ifndef NDEBUG
+    bool isWithinVMPool(void* pointer, size_t size)
+    {
+        return pointer >= m_base && (reinterpret_cast<char*>(pointer) + size <= reinterpret_cast<char*>(m_base) + m_totalHeapSize);
+    }
+#endif
+
+    // Freed space from the most common sized allocations will be held in this list, ...
+    const size_t m_commonSize;
+    Vector<void*> m_commonSizedAllocations;
+
+    // ... and all other freed allocations are held in m_freeList.
+    SizeSortedFreeTree m_freeList;
+
+    // This is used for housekeeping, to trigger defragmentation of the freed lists.
+    size_t m_countFreedSinceLastCoalesce;
+
+    void* m_base;
+    size_t m_totalHeapSize;
+};
+
+void ExecutableAllocator::intializePageSize()
+{
+    ExecutableAllocator::pageSize = getpagesize();
+}
+
+static FixedVMPoolAllocator* allocator = 0;
+static SpinLock spinlock = SPINLOCK_INITIALIZER;
+
+ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t size)
+{
+  SpinLockHolder lock_holder(&spinlock);
+
+    if (!allocator)
+        allocator = new FixedVMPoolAllocator(JIT_ALLOCATOR_LARGE_ALLOC_SIZE, TWO_GB);
+    ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(allocator->alloc(size)), size};
+    return alloc;
+}
+
+void ExecutablePool::systemRelease(const ExecutablePool::Allocation& allocation) 
+{
+  SpinLockHolder lock_holder(&spinlock);
+
+    ASSERT(allocator);
+    allocator->free(allocation.pages, allocation.size);
+}
+
+}
+
+#endif // HAVE(ASSEMBLER)
index 21955d7829dfc3eb3dcdf1c0f39fd8928add7f60..4bd5a2c6e90eef766ccfb7999bf4f6a60e51d48d 100644 (file)
 
 #include <sys/mman.h>
 #include <unistd.h>
+#include <wtf/VMTags.h>
 
 namespace JSC {
 
+#if !(PLATFORM(MAC) && PLATFORM(X86_64))
+
 void ExecutableAllocator::intializePageSize()
 {
     ExecutableAllocator::pageSize = getpagesize();
@@ -41,16 +44,39 @@ void ExecutableAllocator::intializePageSize()
 
 ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t n)
 {
-    ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(mmap(NULL, n, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0)), n};
+    ExecutablePool::Allocation alloc = { reinterpret_cast<char*>(mmap(NULL, n, INITIAL_PROTECTION_FLAGS, MAP_PRIVATE | MAP_ANON, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0)), n };
     return alloc;
 }
 
-void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc) 
+void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc)
 { 
     int result = munmap(alloc.pages, alloc.size);
     ASSERT_UNUSED(result, !result);
 }
 
+#endif // !(PLATFORM(MAC) && PLATFORM(X86_64))
+
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+void ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSeting setting)
+{
+    if (!pageSize)
+        intializePageSize();
+
+    // Calculate the start of the page containing this region,
+    // and account for this extra memory within size.
+    intptr_t startPtr = reinterpret_cast<intptr_t>(start);
+    intptr_t pageStartPtr = startPtr & ~(pageSize - 1);
+    void* pageStart = reinterpret_cast<void*>(pageStartPtr);
+    size += (startPtr - pageStartPtr);
+
+    // Round size up
+    size += (pageSize - 1);
+    size &= ~(pageSize - 1);
+
+    mprotect(pageStart, size, (setting == Writable) ? PROTECTION_FLAGS_RW : PROTECTION_FLAGS_RX);
+}
+#endif
+
 }
 
 #endif // HAVE(ASSEMBLER)
index 7467f81a65e23e94d4e389d0bdddf35a5bbf4d86..a9ba7d0ea1bc2e52311c4feea19e33d90dc518f5 100644 (file)
@@ -51,6 +51,10 @@ void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc)
     VirtualFree(alloc.pages, 0, MEM_RELEASE); 
 }
 
+#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
+#error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform."
+#endif
+
 }
 
 #endif // HAVE(ASSEMBLER)
index 5640c8af26831680c6358cf4b881cc693ebd286d..74d7312317690d80e0416fb1de918d74765ef000 100644 (file)
 #include "config.h"
 #include "JIT.h"
 
+// This probably does not belong here; adding here for now as a quick Windows build fix.
+#if ENABLE(ASSEMBLER) && PLATFORM(X86) && !PLATFORM(MAC)
+#include "MacroAssembler.h"
+JSC::MacroAssemblerX86Common::SSE2CheckState JSC::MacroAssemblerX86Common::s_sse2CheckState = NotCheckedSSE2;
+#endif
+
 #if ENABLE(JIT)
 
 #include "CodeBlock.h"
+#include "Interpreter.h"
 #include "JITInlineMethods.h"
+#include "JITStubs.h"
+#include "JITStubCall.h"
 #include "JSArray.h"
 #include "JSFunction.h"
-#include "Interpreter.h"
+#include "LinkBuffer.h"
+#include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
 
@@ -44,170 +54,22 @@ using namespace std;
 
 namespace JSC {
 
-#if COMPILER(GCC) && PLATFORM(X86)
-
-COMPILE_ASSERT(STUB_ARGS_code == 0x0C, STUB_ARGS_code_is_0x0C);
-COMPILE_ASSERT(STUB_ARGS_callFrame == 0x0E, STUB_ARGS_callFrame_is_0x0E);
-
-#if PLATFORM(DARWIN)
-#define SYMBOL_STRING(name) "_" #name
-#else
-#define SYMBOL_STRING(name) #name
-#endif
-
-asm(
-".globl " SYMBOL_STRING(ctiTrampoline) "\n"
-SYMBOL_STRING(ctiTrampoline) ":" "\n"
-    "pushl %ebp" "\n"
-    "movl %esp, %ebp" "\n"
-    "pushl %esi" "\n"
-    "pushl %edi" "\n"
-    "pushl %ebx" "\n"
-    "subl $0x1c, %esp" "\n"
-    "movl $512, %esi" "\n"
-    "movl 0x38(%esp), %edi" "\n" // Ox38 = 0x0E * 4, 0x0E = STUB_ARGS_callFrame (see assertion above)
-    "call *0x30(%esp)" "\n" // Ox30 = 0x0C * 4, 0x0C = STUB_ARGS_code (see assertion above)
-    "addl $0x1c, %esp" "\n"
-    "popl %ebx" "\n"
-    "popl %edi" "\n"
-    "popl %esi" "\n"
-    "popl %ebp" "\n"
-    "ret" "\n"
-);
-
-asm(
-".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
-SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
-#if USE(JIT_STUB_ARGUMENT_VA_LIST)
-    "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPvz) "\n"
-#else
-#if USE(JIT_STUB_ARGUMENT_REGISTER)
-    "movl %esp, %ecx" "\n"
-#else // JIT_STUB_ARGUMENT_STACK
-    "movl %esp, 0(%esp)" "\n"
-#endif
-    "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPPv) "\n"
-#endif
-    "addl $0x1c, %esp" "\n"
-    "popl %ebx" "\n"
-    "popl %edi" "\n"
-    "popl %esi" "\n"
-    "popl %ebp" "\n"
-    "ret" "\n"
-);
-    
-#elif COMPILER(GCC) && PLATFORM(X86_64)
-
-COMPILE_ASSERT(STUB_ARGS_code == 0x10, STUB_ARGS_code_is_0x10);
-COMPILE_ASSERT(STUB_ARGS_callFrame == 0x12, STUB_ARGS_callFrame_is_0x12);
-
-#if PLATFORM(DARWIN)
-#define SYMBOL_STRING(name) "_" #name
-#else
-#define SYMBOL_STRING(name) #name
-#endif
-
-asm(
-".globl " SYMBOL_STRING(ctiTrampoline) "\n"
-SYMBOL_STRING(ctiTrampoline) ":" "\n"
-    "pushq %rbp" "\n"
-    "movq %rsp, %rbp" "\n"
-    "pushq %r12" "\n"
-    "pushq %r13" "\n"
-    "pushq %r14" "\n"
-    "pushq %r15" "\n"
-    "pushq %rbx" "\n"
-    "subq $0x48, %rsp" "\n"
-    "movq $512, %r12" "\n"
-    "movq $0xFFFF000000000000, %r14" "\n"
-    "movq $0xFFFF000000000002, %r15" "\n"
-    "movq 0x90(%rsp), %r13" "\n" // Ox90 = 0x12 * 8, 0x12 = STUB_ARGS_callFrame (see assertion above)
-    "call *0x80(%rsp)" "\n" // Ox80 = 0x10 * 8, 0x10 = STUB_ARGS_code (see assertion above)
-    "addq $0x48, %rsp" "\n"
-    "popq %rbx" "\n"
-    "popq %r15" "\n"
-    "popq %r14" "\n"
-    "popq %r13" "\n"
-    "popq %r12" "\n"
-    "popq %rbp" "\n"
-    "ret" "\n"
-);
-
-asm(
-".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
-SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
-#if USE(JIT_STUB_ARGUMENT_REGISTER)
-    "movq %rsp, %rdi" "\n"
-    "call " SYMBOL_STRING(_ZN3JSC11Interpreter12cti_vm_throwEPPv) "\n"
-#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
-#error "JIT_STUB_ARGUMENT configuration not supported."
-#endif
-    "addq $0x48, %rsp" "\n"
-    "popq %rbx" "\n"
-    "popq %r15" "\n"
-    "popq %r14" "\n"
-    "popq %r13" "\n"
-    "popq %r12" "\n"
-    "popq %rbp" "\n"
-    "ret" "\n"
-);
-    
-#elif COMPILER(MSVC)
-
-extern "C" {
-    
-    __declspec(naked) JSValueEncodedAsPointer* ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValuePtr* exception, Profiler**, JSGlobalData*)
-    {
-        __asm {
-            push ebp;
-            mov ebp, esp;
-            push esi;
-            push edi;
-            push ebx;
-            sub esp, 0x1c;
-            mov esi, 512;
-            mov ecx, esp;
-            mov edi, [esp + 0x38];
-            call [esp + 0x30]; // Ox30 = 0x0C * 4, 0x0C = STUB_ARGS_code (see assertion above)
-            add esp, 0x1c;
-            pop ebx;
-            pop edi;
-            pop esi;
-            pop ebp;
-            ret;
-        }
-    }
-    
-    __declspec(naked) void ctiVMThrowTrampoline()
-    {
-        __asm {
-#if USE(JIT_STUB_ARGUMENT_REGISTER)
-            mov ecx, esp;
-#else // JIT_STUB_ARGUMENT_VA_LIST or JIT_STUB_ARGUMENT_STACK
-#error "JIT_STUB_ARGUMENT configuration not supported."
-#endif
-            call JSC::Interpreter::cti_vm_throw;
-            add esp, 0x1c;
-            pop ebx;
-            pop edi;
-            pop esi;
-            pop ebp;
-            ret;
-        }
-    }
-    
+void ctiPatchNearCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction)
+{
+    RepatchBuffer repatchBuffer(codeblock);
+    repatchBuffer.relinkNearCallerToTrampoline(returnAddress, newCalleeFunction);
 }
 
-#endif
-
-void ctiSetReturnAddress(void** where, void* what)
+void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction)
 {
-    *where = what;
+    RepatchBuffer repatchBuffer(codeblock);
+    repatchBuffer.relinkCallerToTrampoline(returnAddress, newCalleeFunction);
 }
 
-void ctiPatchCallByReturnAddress(void* where, void* what)
+void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction)
 {
-    MacroAssembler::Jump::patch(where, what);
+    RepatchBuffer repatchBuffer(codeblock);
+    repatchBuffer.relinkCallerToFunction(returnAddress, newCalleeFunction);
 }
 
 JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)
@@ -217,97 +79,92 @@ JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock)
     , m_labels(codeBlock ? codeBlock->instructions().size() : 0)
     , m_propertyAccessCompilationInfo(codeBlock ? codeBlock->numberOfStructureStubInfos() : 0)
     , m_callStructureStubCompilationInfo(codeBlock ? codeBlock->numberOfCallLinkInfos() : 0)
+    , m_bytecodeIndex((unsigned)-1)
+#if USE(JSVALUE32_64)
+    , m_jumpTargetIndex(0)
+    , m_mappedBytecodeIndex((unsigned)-1)
+    , m_mappedVirtualRegisterIndex((unsigned)-1)
+    , m_mappedTag((RegisterID)-1)
+    , m_mappedPayload((RegisterID)-1)
+#else
     , m_lastResultBytecodeRegister(std::numeric_limits<int>::max())
     , m_jumpTargetsPosition(0)
+#endif
 {
 }
 
-void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqType type)
+#if USE(JSVALUE32_64)
+void JIT::emitTimeoutCheck()
 {
-    unsigned dst = currentInstruction[1].u.operand;
-    unsigned src1 = currentInstruction[2].u.operand;
-    unsigned src2 = currentInstruction[3].u.operand;
-
-    emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx);
-
-#if USE(ALTERNATE_JSIMMEDIATE)
-    // Jump to a slow case if either operand is a number, or if both are JSCell*s.
-    move(X86::eax, X86::ecx);
-    orPtr(X86::edx, X86::ecx);
-    addSlowCase(emitJumpIfJSCell(X86::ecx));
-    addSlowCase(emitJumpIfImmediateNumber(X86::ecx));
-
-    if (type == OpStrictEq)
-        sete32(X86::edx, X86::eax);
-    else
-        setne32(X86::edx, X86::eax);
-    emitTagAsBoolImmediate(X86::eax);
-#else
-    bool negated = (type == OpNStrictEq);
-
-    // Check that both are immediates, if so check if they're equal
-    Jump firstNotImmediate = emitJumpIfJSCell(X86::eax);
-    Jump secondNotImmediate = emitJumpIfJSCell(X86::edx);
-    Jump bothWereImmediatesButNotEqual = jnePtr(X86::edx, X86::eax);
-
-    // They are equal - set the result to true. (Or false, if negated).
-    move(ImmPtr(JSValuePtr::encode(jsBoolean(!negated))), X86::eax);
-    Jump bothWereImmediatesAndEqual = jump();
-
-    // eax was not an immediate, we haven't yet checked edx.
-    // If edx is also a JSCell, or is 0, then jump to a slow case,
-    // otherwise these values are not equal.
-    firstNotImmediate.link(this);
-    emitJumpSlowCaseIfJSCell(X86::edx);
-    addSlowCase(jePtr(X86::edx, ImmPtr(JSValuePtr::encode(js0()))));
-    Jump firstWasNotImmediate = jump();
-
-    // eax was an immediate, but edx wasn't.
-    // If eax is 0 jump to a slow case, otherwise these values are not equal.
-    secondNotImmediate.link(this);
-    addSlowCase(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0()))));
-
-    // We get here if the two values are different immediates, or one is 0 and the other is a JSCell.
-    // Vaelues are not equal, set the result to false.
-    bothWereImmediatesButNotEqual.link(this);
-    firstWasNotImmediate.link(this);
-    move(ImmPtr(JSValuePtr::encode(jsBoolean(negated))), X86::eax);
-    
-    bothWereImmediatesAndEqual.link(this);
-#endif
-
-    emitPutVirtualRegister(dst);
+    Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister);
+    JITStubCall stubCall(this, cti_timeout_check);
+    stubCall.addArgument(regT1, regT0); // save last result registers.
+    stubCall.call(timeoutCheckRegister);
+    stubCall.getArgument(0, regT1, regT0); // reload last result registers.
+    skipTimeout.link(this);
 }
-
-void JIT::emitSlowScriptCheck()
+#else
+void JIT::emitTimeoutCheck()
 {
-    Jump skipTimeout = jnzSub32(Imm32(1), timeoutCheckRegister);
-    emitCTICall(Interpreter::cti_timeout_check);
-    move(X86::eax, timeoutCheckRegister);
+    Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister);
+    JITStubCall(this, cti_timeout_check).call(timeoutCheckRegister);
     skipTimeout.link(this);
 
     killLastResultRegister();
 }
-
+#endif
 
 #define NEXT_OPCODE(name) \
     m_bytecodeIndex += OPCODE_LENGTH(name); \
     break;
 
-#define CTI_COMPILE_BINARY_OP(name) \
+#if USE(JSVALUE32_64)
+#define DEFINE_BINARY_OP(name) \
+    case name: { \
+        JITStubCall stubCall(this, cti_##name); \
+        stubCall.addArgument(currentInstruction[2].u.operand); \
+        stubCall.addArgument(currentInstruction[3].u.operand); \
+        stubCall.call(currentInstruction[1].u.operand); \
+        NEXT_OPCODE(name); \
+    }
+
+#define DEFINE_UNARY_OP(name) \
+    case name: { \
+        JITStubCall stubCall(this, cti_##name); \
+        stubCall.addArgument(currentInstruction[2].u.operand); \
+        stubCall.call(currentInstruction[1].u.operand); \
+        NEXT_OPCODE(name); \
+    }
+
+#else // USE(JSVALUE32_64)
+
+#define DEFINE_BINARY_OP(name) \
+    case name: { \
+        JITStubCall stubCall(this, cti_##name); \
+        stubCall.addArgument(currentInstruction[2].u.operand, regT2); \
+        stubCall.addArgument(currentInstruction[3].u.operand, regT2); \
+        stubCall.call(currentInstruction[1].u.operand); \
+        NEXT_OPCODE(name); \
+    }
+
+#define DEFINE_UNARY_OP(name) \
+    case name: { \
+        JITStubCall stubCall(this, cti_##name); \
+        stubCall.addArgument(currentInstruction[2].u.operand, regT2); \
+        stubCall.call(currentInstruction[1].u.operand); \
+        NEXT_OPCODE(name); \
+    }
+#endif // USE(JSVALUE32_64)
+
+#define DEFINE_OP(name) \
     case name: { \
-        emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); \
-        emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx); \
-        emitCTICall(Interpreter::cti_##name); \
-        emitPutVirtualRegister(currentInstruction[1].u.operand); \
+        emit_##name(currentInstruction); \
         NEXT_OPCODE(name); \
     }
 
-#define CTI_COMPILE_UNARY_OP(name) \
+#define DEFINE_SLOWCASE_OP(name) \
     case name: { \
-        emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); \
-        emitCTICall(Interpreter::cti_##name); \
-        emitPutVirtualRegister(currentInstruction[1].u.operand); \
+        emitSlow_##name(currentInstruction, iter); \
         NEXT_OPCODE(name); \
     }
 
@@ -315,9 +172,10 @@ void JIT::privateCompileMainPass()
 {
     Instruction* instructionsBegin = m_codeBlock->instructions().begin();
     unsigned instructionCount = m_codeBlock->instructions().size();
-    unsigned propertyAccessInstructionIndex = 0;
-    unsigned globalResolveInfoIndex = 0;
-    unsigned callLinkInfoIndex = 0;
+
+    m_propertyAccessInstructionIndex = 0;
+    m_globalResolveInfoIndex = 0;
+    m_callLinkInfoIndex = 0;
 
     for (m_bytecodeIndex = 0; m_bytecodeIndex < instructionCount; ) {
         Instruction* currentInstruction = instructionsBegin + m_bytecodeIndex;
@@ -328,917 +186,133 @@ void JIT::privateCompileMainPass()
             sampleInstruction(currentInstruction);
 #endif
 
-        m_labels[m_bytecodeIndex] = label();
-        OpcodeID opcodeID = m_interpreter->getOpcodeID(currentInstruction->u.opcode);
-
-        switch (opcodeID) {
-        case op_mov: {
-            emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_mov);
-        }
-        case op_add: {
-            compileFastArith_op_add(currentInstruction);
-            NEXT_OPCODE(op_add);
-        }
-        case op_end: {
-            if (m_codeBlock->needsFullScopeChain())
-                emitCTICall(Interpreter::cti_op_end);
-            emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
-            push(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register))));
-            ret();
-            NEXT_OPCODE(op_end);
-        }
-        case op_jmp: {
-            unsigned target = currentInstruction[1].u.operand;
-            addJump(jump(), target + 1);
-            NEXT_OPCODE(op_jmp);
-        }
-        case op_pre_inc: {
-            compileFastArith_op_pre_inc(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_pre_inc);
-        }
-        case op_loop: {
-            emitSlowScriptCheck();
-
-            unsigned target = currentInstruction[1].u.operand;
-            addJump(jump(), target + 1);
-            NEXT_OPCODE(op_end);
-        }
-        case op_loop_if_less: {
-            emitSlowScriptCheck();
-
-            unsigned op1 = currentInstruction[1].u.operand;
-            unsigned op2 = currentInstruction[2].u.operand;
-            unsigned target = currentInstruction[3].u.operand;
-            if (isOperandConstantImmediateInt(op2)) {
-                emitGetVirtualRegister(op1, X86::eax);
-                emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
-                int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
-                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
+#if !USE(JSVALUE32_64)
+        if (m_labels[m_bytecodeIndex].isUsed())
+            killLastResultRegister();
 #endif
-                addJump(jl32(X86::eax, Imm32(op2imm)), target + 3);
-            } else {
-                emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
-                emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-                emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
-                addJump(jl32(X86::eax, X86::edx), target + 3);
-            }
-            NEXT_OPCODE(op_loop_if_less);
-        }
-        case op_loop_if_lesseq: {
-            emitSlowScriptCheck();
-
-            unsigned op1 = currentInstruction[1].u.operand;
-            unsigned op2 = currentInstruction[2].u.operand;
-            unsigned target = currentInstruction[3].u.operand;
-            if (isOperandConstantImmediateInt(op2)) {
-                emitGetVirtualRegister(op1, X86::eax);
-                emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
-                int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
-                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
-#endif
-                addJump(jle32(X86::eax, Imm32(op2imm)), target + 3);
-            } else {
-                emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
-                emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-                emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
-                addJump(jle32(X86::eax, X86::edx), target + 3);
-            }
-            NEXT_OPCODE(op_loop_if_less);
-        }
-        case op_new_object: {
-            emitCTICall(Interpreter::cti_op_new_object);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_new_object);
-        }
-        case op_put_by_id: {
-            compilePutByIdHotPath(currentInstruction[1].u.operand, &(m_codeBlock->identifier(currentInstruction[2].u.operand)), currentInstruction[3].u.operand, propertyAccessInstructionIndex++);
-            NEXT_OPCODE(op_put_by_id);
-        }
-        case op_get_by_id: {
-            compileGetByIdHotPath(currentInstruction[1].u.operand, currentInstruction[2].u.operand, &(m_codeBlock->identifier(currentInstruction[3].u.operand)), propertyAccessInstructionIndex++);
-            NEXT_OPCODE(op_get_by_id);
-        }
-        case op_instanceof: {
-            emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax); // value
-            emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx); // baseVal
-            emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // proto
-
-            // check if any are immediates
-            move(X86::eax, X86::ebx);
-            orPtr(X86::ecx, X86::ebx);
-            orPtr(X86::edx, X86::ebx);
-            emitJumpSlowCaseIfNotJSCell(X86::ebx);
-
-            // check that all are object type - this is a bit of a bithack to avoid excess branching;
-            // we check that the sum of the three type codes from Structures is exactly 3 * ObjectType,
-            // this works because NumberType and StringType are smaller
-            move(Imm32(3 * ObjectType), X86::ebx);
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::eax);
-            loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
-            loadPtr(Address(X86::edx, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
-            sub32(Address(X86::eax, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
-            sub32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
-            addSlowCase(jne32(Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx));
-
-            // check that baseVal's flags include ImplementsHasInstance but not OverridesHasInstance
-            load32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), X86::ecx);
-            and32(Imm32(ImplementsHasInstance | OverridesHasInstance), X86::ecx);
-            addSlowCase(jne32(X86::ecx, Imm32(ImplementsHasInstance)));
-
-            emitGetVirtualRegister(currentInstruction[2].u.operand, X86::ecx); // reload value
-            emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // reload proto
-
-            // optimistically load true result
-            move(ImmPtr(JSValuePtr::encode(jsBoolean(true))), X86::eax);
-
-            Label loop(this);
-
-            // load value's prototype
-            loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
-            loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
-
-            Jump exit = jePtr(X86::ecx, X86::edx);
-
-            jnePtr(X86::ecx, ImmPtr(JSValuePtr::encode(jsNull())), loop);
-
-            move(ImmPtr(JSValuePtr::encode(jsBoolean(false))), X86::eax);
-
-            exit.link(this);
-
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-
-            NEXT_OPCODE(op_instanceof);
-        }
-        case op_del_by_id: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
-            emitPutJITStubArgConstant(ident, 2);
-            emitCTICall(Interpreter::cti_op_del_by_id);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_del_by_id);
-        }
-        case op_mul: {
-            compileFastArith_op_mul(currentInstruction);
-            NEXT_OPCODE(op_mul);
-        }
-        case op_new_func: {
-            FuncDeclNode* func = m_codeBlock->function(currentInstruction[2].u.operand);
-            emitPutJITStubArgConstant(func, 1);
-            emitCTICall(Interpreter::cti_op_new_func);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_new_func);
-        }
-        case op_call: {
-            compileOpCall(opcodeID, currentInstruction, callLinkInfoIndex++);
-            NEXT_OPCODE(op_call);
-        }
-        case op_call_eval: {
-            compileOpCall(opcodeID, currentInstruction, callLinkInfoIndex++);
-            NEXT_OPCODE(op_call_eval);
-        }
-        case op_construct: {
-            compileOpCall(opcodeID, currentInstruction, callLinkInfoIndex++);
-            NEXT_OPCODE(op_construct);
-        }
-        case op_get_global_var: {
-            JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[2].u.jsCell);
-            move(ImmPtr(globalObject), X86::eax);
-            emitGetVariableObjectRegister(X86::eax, currentInstruction[3].u.operand, X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_get_global_var);
-        }
-        case op_put_global_var: {
-            emitGetVirtualRegister(currentInstruction[3].u.operand, X86::edx);
-            JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[1].u.jsCell);
-            move(ImmPtr(globalObject), X86::eax);
-            emitPutVariableObjectRegister(X86::edx, X86::eax, currentInstruction[2].u.operand);
-            NEXT_OPCODE(op_put_global_var);
-        }
-        case op_get_scoped_var: {
-            int skip = currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain();
-
-            emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::eax);
-            while (skip--)
-                loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, next)), X86::eax);
-
-            loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, object)), X86::eax);
-            emitGetVariableObjectRegister(X86::eax, currentInstruction[2].u.operand, X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_get_scoped_var);
-        }
-        case op_put_scoped_var: {
-            int skip = currentInstruction[2].u.operand + m_codeBlock->needsFullScopeChain();
-
-            emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::edx);
-            emitGetVirtualRegister(currentInstruction[3].u.operand, X86::eax);
-            while (skip--)
-                loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, next)), X86::edx);
-
-            loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, object)), X86::edx);
-            emitPutVariableObjectRegister(X86::eax, X86::edx, currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_put_scoped_var);
-        }
-        case op_tear_off_activation: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
-            emitCTICall(Interpreter::cti_op_tear_off_activation);
-            NEXT_OPCODE(op_tear_off_activation);
-        }
-        case op_tear_off_arguments: {
-            emitCTICall(Interpreter::cti_op_tear_off_arguments);
-            NEXT_OPCODE(op_tear_off_arguments);
-        }
-        case op_ret: {
-            // We could JIT generate the deref, only calling out to C when the refcount hits zero.
-            if (m_codeBlock->needsFullScopeChain())
-                emitCTICall(Interpreter::cti_op_ret_scopeChain);
-
-            // Return the result in %eax.
-            emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
-
-            // Grab the return address.
-            emitGetFromCallFrameHeader(RegisterFile::ReturnPC, X86::edx);
-
-            // Restore our caller's "r".
-            emitGetFromCallFrameHeader(RegisterFile::CallerFrame, callFrameRegister);
-
-            // Return.
-            push(X86::edx);
-            ret();
-
-            NEXT_OPCODE(op_ret);
-        }
-        case op_new_array: {
-            emitPutJITStubArgConstant(currentInstruction[2].u.operand, 1);
-            emitPutJITStubArgConstant(currentInstruction[3].u.operand, 2);
-            emitCTICall(Interpreter::cti_op_new_array);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_new_array);
-        }
-        case op_resolve: {
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
-            emitPutJITStubArgConstant(ident, 1);
-            emitCTICall(Interpreter::cti_op_resolve);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_resolve);
-        }
-        case op_construct_verify: {
-            emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
 
-            emitJumpSlowCaseIfNotJSCell(X86::eax);
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
-            addSlowCase(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
+        m_labels[m_bytecodeIndex] = label();
 
-            NEXT_OPCODE(op_construct_verify);
-        }
-        case op_get_by_val: {
-            emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
-            emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
-#if USE(ALTERNATE_JSIMMEDIATE)
-            // This is technically incorrect - we're zero-extending an int32.  On the hot path this doesn't matter.
-            // We check the value as if it was a uint32 against the m_fastAccessCutoff - which will always fail if
-            // number was signed since m_fastAccessCutoff is always less than intmax (since the total allocation
-            // size is always less than 4Gb).  As such zero extending wil have been correct (and extending the value
-            // to 64-bits is necessary since it's used in the address calculation.  We zero extend rather than sign
-            // extending since it makes it easier to re-tag the value in the slow case.
-            zeroExtend32ToPtr(X86::edx, X86::edx);
-#else
-            emitFastArithImmToInt(X86::edx);
+        switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
+        DEFINE_BINARY_OP(op_del_by_val)
+#if !USE(JSVALUE32_64)
+        DEFINE_BINARY_OP(op_div)
 #endif
-            emitJumpSlowCaseIfNotJSCell(X86::eax);
-            addSlowCase(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
-
-            // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
-            addSlowCase(jae32(X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff))));
-
-            // Get the value from the vector
-            loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_get_by_val);
-        }
-        case op_resolve_func: {
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
-            emitPutJITStubArgConstant(ident, 1);
-            emitCTICall(Interpreter::cti_op_resolve_func);
-            emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_resolve_func);
-        }
-        case op_sub: {
-            compileFastArith_op_sub(currentInstruction);
-            NEXT_OPCODE(op_sub);
-        }
-        case op_put_by_val: {
-            emitGetVirtualRegisters(currentInstruction[1].u.operand, X86::eax, currentInstruction[2].u.operand, X86::edx);
-            emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
-#if USE(ALTERNATE_JSIMMEDIATE)
-            // See comment in op_get_by_val.
-            zeroExtend32ToPtr(X86::edx, X86::edx);
-#else
-            emitFastArithImmToInt(X86::edx);
+        DEFINE_BINARY_OP(op_in)
+        DEFINE_BINARY_OP(op_less)
+        DEFINE_BINARY_OP(op_lesseq)
+        DEFINE_BINARY_OP(op_urshift)
+        DEFINE_UNARY_OP(op_get_pnames)
+        DEFINE_UNARY_OP(op_is_boolean)
+        DEFINE_UNARY_OP(op_is_function)
+        DEFINE_UNARY_OP(op_is_number)
+        DEFINE_UNARY_OP(op_is_object)
+        DEFINE_UNARY_OP(op_is_string)
+        DEFINE_UNARY_OP(op_is_undefined)
+#if !USE(JSVALUE32_64)
+        DEFINE_UNARY_OP(op_negate)
 #endif
-            emitJumpSlowCaseIfNotJSCell(X86::eax);
-            addSlowCase(jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
-
-            // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
-            Jump inFastVector = jb32(X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff)));
-            // No; oh well, check if the access if within the vector - if so, we may still be okay.
-            addSlowCase(jae32(X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength))));
-
-            // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
-            // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. 
-            addSlowCase(jzPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0]))));
-
-            // All good - put the value into the array.
-            inFastVector.link(this);
-            emitGetVirtualRegister(currentInstruction[3].u.operand, X86::eax);
-            storePtr(X86::eax, BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])));
-            NEXT_OPCODE(op_put_by_val);
-        }
-        CTI_COMPILE_BINARY_OP(op_lesseq)
-        case op_loop_if_true: {
-            emitSlowScriptCheck();
-
-            unsigned target = currentInstruction[2].u.operand;
-            emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
-
-            Jump isZero = jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0())));
-            addJump(emitJumpIfImmediateInteger(X86::eax), target + 2);
-
-            addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
-            addSlowCase(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
-
-            isZero.link(this);
-            NEXT_OPCODE(op_loop_if_true);
-        };
-        case op_resolve_base: {
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
-            emitPutJITStubArgConstant(ident, 1);
-            emitCTICall(Interpreter::cti_op_resolve_base);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_resolve_base);
-        }
-        case op_negate: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
-            emitCTICall(Interpreter::cti_op_negate);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_negate);
-        }
-        case op_resolve_skip: {
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
-            emitPutJITStubArgConstant(ident, 1);
-            emitPutJITStubArgConstant(currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain(), 2);
-            emitCTICall(Interpreter::cti_op_resolve_skip);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_resolve_skip);
-        }
-        case op_resolve_global: {
-            // Fast case
-            void* globalObject = currentInstruction[2].u.jsCell;
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
-            
-            unsigned currentIndex = globalResolveInfoIndex++;
-            void* structureAddress = &(m_codeBlock->globalResolveInfo(currentIndex).structure);
-            void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);
-
-            // Check Structure of global object
-            move(ImmPtr(globalObject), X86::eax);
-            loadPtr(structureAddress, X86::edx);
-            Jump noMatch = jnePtr(X86::edx, Address(X86::eax, FIELD_OFFSET(JSCell, m_structure))); // Structures don't match
-
-            // Load cached property
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSGlobalObject, m_propertyStorage)), X86::eax);
-            load32(offsetAddr, X86::edx);
-            loadPtr(BaseIndex(X86::eax, X86::edx, ScalePtr), X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            Jump end = jump();
-
-            // Slow case
-            noMatch.link(this);
-            emitPutJITStubArgConstant(globalObject, 1);
-            emitPutJITStubArgConstant(ident, 2);
-            emitPutJITStubArgConstant(currentIndex, 3);
-            emitCTICall(Interpreter::cti_op_resolve_global);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            end.link(this);
-            NEXT_OPCODE(op_resolve_global);
-        }
-        CTI_COMPILE_BINARY_OP(op_div)
-        case op_pre_dec: {
-            compileFastArith_op_pre_dec(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_pre_dec);
-        }
-        case op_jnless: {
-            unsigned op1 = currentInstruction[1].u.operand;
-            unsigned op2 = currentInstruction[2].u.operand;
-            unsigned target = currentInstruction[3].u.operand;
-            if (isOperandConstantImmediateInt(op2)) {
-                emitGetVirtualRegister(op1, X86::eax);
-                emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
-                int32_t op2imm = getConstantOperandImmediateInt(op2);
-#else
-                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
+        DEFINE_UNARY_OP(op_typeof)
+
+        DEFINE_OP(op_add)
+        DEFINE_OP(op_bitand)
+        DEFINE_OP(op_bitnot)
+        DEFINE_OP(op_bitor)
+        DEFINE_OP(op_bitxor)
+        DEFINE_OP(op_call)
+        DEFINE_OP(op_call_eval)
+        DEFINE_OP(op_call_varargs)
+        DEFINE_OP(op_catch)
+        DEFINE_OP(op_construct)
+        DEFINE_OP(op_construct_verify)
+        DEFINE_OP(op_convert_this)
+        DEFINE_OP(op_init_arguments)
+        DEFINE_OP(op_create_arguments)
+        DEFINE_OP(op_debug)
+        DEFINE_OP(op_del_by_id)
+#if USE(JSVALUE32_64)
+        DEFINE_OP(op_div)
 #endif
-                addJump(jge32(X86::eax, Imm32(op2imm)), target + 3);
-            } else {
-                emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
-                emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-                emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
-                addJump(jge32(X86::eax, X86::edx), target + 3);
-            }
-            NEXT_OPCODE(op_jnless);
-        }
-        case op_not: {
-            emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
-            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
-            addSlowCase(jnzPtr(X86::eax, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
-            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_not);
-        }
-        case op_jfalse: {
-            unsigned target = currentInstruction[2].u.operand;
-            emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
-
-            addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0()))), target + 2);
-            Jump isNonZero = emitJumpIfImmediateInteger(X86::eax);
-
-            addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))), target + 2);
-            addSlowCase(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))));
-
-            isNonZero.link(this);
-            NEXT_OPCODE(op_jfalse);
-        };
-        case op_jeq_null: {
-            unsigned src = currentInstruction[1].u.operand;
-            unsigned target = currentInstruction[2].u.operand;
-
-            emitGetVirtualRegister(src, X86::eax);
-            Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
-
-            // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
-            addJump(jnz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
-            Jump wasNotImmediate = jump();
-
-            // Now handle the immediate cases - undefined & null
-            isImmediate.link(this);
-            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
-            addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);            
-
-            wasNotImmediate.link(this);
-            NEXT_OPCODE(op_jeq_null);
-        };
-        case op_jneq_null: {
-            unsigned src = currentInstruction[1].u.operand;
-            unsigned target = currentInstruction[2].u.operand;
-
-            emitGetVirtualRegister(src, X86::eax);
-            Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
-
-            // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
-            addJump(jz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
-            Jump wasNotImmediate = jump();
-
-            // Now handle the immediate cases - undefined & null
-            isImmediate.link(this);
-            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
-            addJump(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);            
-
-            wasNotImmediate.link(this);
-            NEXT_OPCODE(op_jneq_null);
-        }
-        case op_post_inc: {
-            compileFastArith_op_post_inc(currentInstruction[1].u.operand, currentInstruction[2].u.operand);
-            NEXT_OPCODE(op_post_inc);
-        }
-        case op_unexpected_load: {
-            JSValuePtr v = m_codeBlock->unexpectedConstant(currentInstruction[2].u.operand);
-            move(ImmPtr(JSValuePtr::encode(v)), X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_unexpected_load);
-        }
-        case op_jsr: {
-            int retAddrDst = currentInstruction[1].u.operand;
-            int target = currentInstruction[2].u.operand;
-            DataLabelPtr storeLocation = storePtrWithPatch(Address(callFrameRegister, sizeof(Register) * retAddrDst));
-            addJump(jump(), target + 2);
-            m_jsrSites.append(JSRInfo(storeLocation, label()));
-            NEXT_OPCODE(op_jsr);
-        }
-        case op_sret: {
-            jump(Address(callFrameRegister, sizeof(Register) * currentInstruction[1].u.operand));
-            NEXT_OPCODE(op_sret);
-        }
-        case op_eq: {
-            emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
-            emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
-            sete32(X86::edx, X86::eax);
-            emitTagAsBoolImmediate(X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_eq);
-        }
-        case op_lshift: {
-            compileFastArith_op_lshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);
-            NEXT_OPCODE(op_lshift);
-        }
-        case op_bitand: {
-            compileFastArith_op_bitand(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);
-            NEXT_OPCODE(op_bitand);
-        }
-        case op_rshift: {
-            compileFastArith_op_rshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);
-            NEXT_OPCODE(op_rshift);
-        }
-        case op_bitnot: {
-            emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
-            emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
-            not32(X86::eax);
-            emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
-#else
-            xorPtr(Imm32(~JSImmediate::TagTypeNumber), X86::eax);
+        DEFINE_OP(op_end)
+        DEFINE_OP(op_enter)
+        DEFINE_OP(op_enter_with_activation)
+        DEFINE_OP(op_eq)
+        DEFINE_OP(op_eq_null)
+        DEFINE_OP(op_get_by_id)
+        DEFINE_OP(op_get_by_val)
+        DEFINE_OP(op_get_global_var)
+        DEFINE_OP(op_get_scoped_var)
+        DEFINE_OP(op_instanceof)
+        DEFINE_OP(op_jeq_null)
+        DEFINE_OP(op_jfalse)
+        DEFINE_OP(op_jmp)
+        DEFINE_OP(op_jmp_scopes)
+        DEFINE_OP(op_jneq_null)
+        DEFINE_OP(op_jneq_ptr)
+        DEFINE_OP(op_jnless)
+        DEFINE_OP(op_jnlesseq)
+        DEFINE_OP(op_jsr)
+        DEFINE_OP(op_jtrue)
+        DEFINE_OP(op_load_varargs)
+        DEFINE_OP(op_loop)
+        DEFINE_OP(op_loop_if_less)
+        DEFINE_OP(op_loop_if_lesseq)
+        DEFINE_OP(op_loop_if_true)
+        DEFINE_OP(op_lshift)
+        DEFINE_OP(op_method_check)
+        DEFINE_OP(op_mod)
+        DEFINE_OP(op_mov)
+        DEFINE_OP(op_mul)
+#if USE(JSVALUE32_64)
+        DEFINE_OP(op_negate)
 #endif
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_bitnot);
-        }
-        case op_resolve_with_base: {
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
-            emitPutJITStubArgConstant(ident, 1);
-            emitCTICall(Interpreter::cti_op_resolve_with_base);
-            emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_resolve_with_base);
-        }
-        case op_new_func_exp: {
-            FuncExprNode* func = m_codeBlock->functionExpression(currentInstruction[2].u.operand);
-            emitPutJITStubArgConstant(func, 1);
-            emitCTICall(Interpreter::cti_op_new_func_exp);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_new_func_exp);
-        }
-        case op_mod: {
-            compileFastArith_op_mod(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand);
-            NEXT_OPCODE(op_mod);
-        }
-        case op_jtrue: {
-            unsigned target = currentInstruction[2].u.operand;
-            emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
-
-            Jump isZero = jePtr(X86::eax, ImmPtr(JSValuePtr::encode(js0())));
-            addJump(emitJumpIfImmediateInteger(X86::eax), target + 2);
-
-            addJump(jePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
-            addSlowCase(jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
+        DEFINE_OP(op_neq)
+        DEFINE_OP(op_neq_null)
+        DEFINE_OP(op_new_array)
+        DEFINE_OP(op_new_error)
+        DEFINE_OP(op_new_func)
+        DEFINE_OP(op_new_func_exp)
+        DEFINE_OP(op_new_object)
+        DEFINE_OP(op_new_regexp)
+        DEFINE_OP(op_next_pname)
+        DEFINE_OP(op_not)
+        DEFINE_OP(op_nstricteq)
+        DEFINE_OP(op_pop_scope)
+        DEFINE_OP(op_post_dec)
+        DEFINE_OP(op_post_inc)
+        DEFINE_OP(op_pre_dec)
+        DEFINE_OP(op_pre_inc)
+        DEFINE_OP(op_profile_did_call)
+        DEFINE_OP(op_profile_will_call)
+        DEFINE_OP(op_push_new_scope)
+        DEFINE_OP(op_push_scope)
+        DEFINE_OP(op_put_by_id)
+        DEFINE_OP(op_put_by_index)
+        DEFINE_OP(op_put_by_val)
+        DEFINE_OP(op_put_getter)
+        DEFINE_OP(op_put_global_var)
+        DEFINE_OP(op_put_scoped_var)
+        DEFINE_OP(op_put_setter)
+        DEFINE_OP(op_resolve)
+        DEFINE_OP(op_resolve_base)
+        DEFINE_OP(op_resolve_global)
+        DEFINE_OP(op_resolve_skip)
+        DEFINE_OP(op_resolve_with_base)
+        DEFINE_OP(op_ret)
+        DEFINE_OP(op_rshift)
+        DEFINE_OP(op_sret)
+        DEFINE_OP(op_strcat)
+        DEFINE_OP(op_stricteq)
+        DEFINE_OP(op_sub)
+        DEFINE_OP(op_switch_char)
+        DEFINE_OP(op_switch_imm)
+        DEFINE_OP(op_switch_string)
+        DEFINE_OP(op_tear_off_activation)
+        DEFINE_OP(op_tear_off_arguments)
+        DEFINE_OP(op_throw)
+        DEFINE_OP(op_to_jsnumber)
+        DEFINE_OP(op_to_primitive)
 
-            isZero.link(this);
-            NEXT_OPCODE(op_jtrue);
-        }
-        CTI_COMPILE_BINARY_OP(op_less)
-        case op_neq: {
-            emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
-            emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
-            setne32(X86::edx, X86::eax);
-            emitTagAsBoolImmediate(X86::eax);
-
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-
-            NEXT_OPCODE(op_neq);
-        }
-        case op_post_dec: {
-            compileFastArith_op_post_dec(currentInstruction[1].u.operand, currentInstruction[2].u.operand);
-            NEXT_OPCODE(op_post_dec);
-        }
-        CTI_COMPILE_BINARY_OP(op_urshift)
-        case op_bitxor: {
-            emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
-            emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
-            xorPtr(X86::edx, X86::eax);
-            emitFastArithReTagImmediate(X86::eax, X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_bitxor);
-        }
-        case op_new_regexp: {
-            RegExp* regExp = m_codeBlock->regexp(currentInstruction[2].u.operand);
-            emitPutJITStubArgConstant(regExp, 1);
-            emitCTICall(Interpreter::cti_op_new_regexp);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_new_regexp);
-        }
-        case op_bitor: {
-            emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
-            emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
-            orPtr(X86::edx, X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_bitor);
-        }
-        case op_throw: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
-            emitCTICall(Interpreter::cti_op_throw);
-#if PLATFORM(X86_64)
-            addPtr(Imm32(0x48), X86::esp);
-            pop(X86::ebx);
-            pop(X86::r15);
-            pop(X86::r14);
-            pop(X86::r13);
-            pop(X86::r12);
-            pop(X86::ebp);
-            ret();
-#else
-            addPtr(Imm32(0x1c), X86::esp);
-            pop(X86::ebx);
-            pop(X86::edi);
-            pop(X86::esi);
-            pop(X86::ebp);
-            ret();
-#endif
-            NEXT_OPCODE(op_throw);
-        }
-        case op_get_pnames: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
-            emitCTICall(Interpreter::cti_op_get_pnames);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_get_pnames);
-        }
-        case op_next_pname: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
-            unsigned target = currentInstruction[3].u.operand;
-            emitCTICall(Interpreter::cti_op_next_pname);
-            Jump endOfIter = jzPtr(X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            addJump(jump(), target + 3);
-            endOfIter.link(this);
-            NEXT_OPCODE(op_next_pname);
-        }
-        case op_push_scope: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
-            emitCTICall(Interpreter::cti_op_push_scope);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_push_scope);
-        }
-        case op_pop_scope: {
-            emitCTICall(Interpreter::cti_op_pop_scope);
-            NEXT_OPCODE(op_pop_scope);
-        }
-        CTI_COMPILE_UNARY_OP(op_typeof)
-        CTI_COMPILE_UNARY_OP(op_is_undefined)
-        CTI_COMPILE_UNARY_OP(op_is_boolean)
-        CTI_COMPILE_UNARY_OP(op_is_number)
-        CTI_COMPILE_UNARY_OP(op_is_string)
-        CTI_COMPILE_UNARY_OP(op_is_object)
-        CTI_COMPILE_UNARY_OP(op_is_function)
-        case op_stricteq: {
-            compileOpStrictEq(currentInstruction, OpStrictEq);
-            NEXT_OPCODE(op_stricteq);
-        }
-        case op_nstricteq: {
-            compileOpStrictEq(currentInstruction, OpNStrictEq);
-            NEXT_OPCODE(op_nstricteq);
-        }
-        case op_to_jsnumber: {
-            int srcVReg = currentInstruction[2].u.operand;
-            emitGetVirtualRegister(srcVReg, X86::eax);
-            
-            Jump wasImmediate = emitJumpIfImmediateInteger(X86::eax);
-
-            emitJumpSlowCaseIfNotJSCell(X86::eax, srcVReg);
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
-            addSlowCase(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), Imm32(NumberType)));
-            
-            wasImmediate.link(this);
-
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_to_jsnumber);
-        }
-        CTI_COMPILE_BINARY_OP(op_in)
-        case op_push_new_scope: {
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
-            emitPutJITStubArgConstant(ident, 1);
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
-            emitCTICall(Interpreter::cti_op_push_new_scope);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_push_new_scope);
-        }
-        case op_catch: {
-            emitGetCTIParam(STUB_ARGS_callFrame, callFrameRegister);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_catch);
-        }
-        case op_jmp_scopes: {
-            unsigned count = currentInstruction[1].u.operand;
-            emitPutJITStubArgConstant(count, 1);
-            emitCTICall(Interpreter::cti_op_jmp_scopes);
-            unsigned target = currentInstruction[2].u.operand;
-            addJump(jump(), target + 2);
-            NEXT_OPCODE(op_jmp_scopes);
-        }
-        case op_put_by_index: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
-            emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2);
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
-            emitCTICall(Interpreter::cti_op_put_by_index);
-            NEXT_OPCODE(op_put_by_index);
-        }
-        case op_switch_imm: {
-            unsigned tableIndex = currentInstruction[1].u.operand;
-            unsigned defaultOffset = currentInstruction[2].u.operand;
-            unsigned scrutinee = currentInstruction[3].u.operand;
-
-            // create jump table for switch destinations, track this switch statement.
-            SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTable(tableIndex);
-            m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Immediate));
-            jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
-
-            emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
-            emitPutJITStubArgConstant(tableIndex, 2);
-            emitCTICall(Interpreter::cti_op_switch_imm);
-            jump(X86::eax);
-            NEXT_OPCODE(op_switch_imm);
-        }
-        case op_switch_char: {
-            unsigned tableIndex = currentInstruction[1].u.operand;
-            unsigned defaultOffset = currentInstruction[2].u.operand;
-            unsigned scrutinee = currentInstruction[3].u.operand;
-
-            // create jump table for switch destinations, track this switch statement.
-            SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTable(tableIndex);
-            m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Character));
-            jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
-
-            emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
-            emitPutJITStubArgConstant(tableIndex, 2);
-            emitCTICall(Interpreter::cti_op_switch_char);
-            jump(X86::eax);
-            NEXT_OPCODE(op_switch_char);
-        }
-        case op_switch_string: {
-            unsigned tableIndex = currentInstruction[1].u.operand;
-            unsigned defaultOffset = currentInstruction[2].u.operand;
-            unsigned scrutinee = currentInstruction[3].u.operand;
-
-            // create jump table for switch destinations, track this switch statement.
-            StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex);
-            m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset));
-
-            emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
-            emitPutJITStubArgConstant(tableIndex, 2);
-            emitCTICall(Interpreter::cti_op_switch_string);
-            jump(X86::eax);
-            NEXT_OPCODE(op_switch_string);
-        }
-        case op_del_by_val: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
-            emitCTICall(Interpreter::cti_op_del_by_val);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_del_by_val);
-        }
-        case op_put_getter: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
-            emitPutJITStubArgConstant(ident, 2);
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
-            emitCTICall(Interpreter::cti_op_put_getter);
-            NEXT_OPCODE(op_put_getter);
-        }
-        case op_put_setter: {
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
-            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
-            emitPutJITStubArgConstant(ident, 2);
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
-            emitCTICall(Interpreter::cti_op_put_setter);
-            NEXT_OPCODE(op_put_setter);
-        }
-        case op_new_error: {
-            JSValuePtr message = m_codeBlock->unexpectedConstant(currentInstruction[3].u.operand);
-            emitPutJITStubArgConstant(currentInstruction[2].u.operand, 1);
-            emitPutJITStubArgConstant(JSValuePtr::encode(message), 2);
-            emitPutJITStubArgConstant(m_bytecodeIndex, 3);
-            emitCTICall(Interpreter::cti_op_new_error);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_new_error);
-        }
-        case op_debug: {
-            emitPutJITStubArgConstant(currentInstruction[1].u.operand, 1);
-            emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2);
-            emitPutJITStubArgConstant(currentInstruction[3].u.operand, 3);
-            emitCTICall(Interpreter::cti_op_debug);
-            NEXT_OPCODE(op_debug);
-        }
-        case op_eq_null: {
-            unsigned dst = currentInstruction[1].u.operand;
-            unsigned src1 = currentInstruction[2].u.operand;
-
-            emitGetVirtualRegister(src1, X86::eax);
-            Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
-
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
-            setnz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
-
-            Jump wasNotImmediate = jump();
-
-            isImmediate.link(this);
-
-            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
-            sete32(Imm32(JSImmediate::FullTagTypeNull), X86::eax);
-
-            wasNotImmediate.link(this);
-
-            emitTagAsBoolImmediate(X86::eax);
-            emitPutVirtualRegister(dst);
-
-            NEXT_OPCODE(op_eq_null);
-        }
-        case op_neq_null: {
-            unsigned dst = currentInstruction[1].u.operand;
-            unsigned src1 = currentInstruction[2].u.operand;
-
-            emitGetVirtualRegister(src1, X86::eax);
-            Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
-
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
-            setz32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
-
-            Jump wasNotImmediate = jump();
-
-            isImmediate.link(this);
-
-            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
-            setne32(Imm32(JSImmediate::FullTagTypeNull), X86::eax);
-
-            wasNotImmediate.link(this);
-
-            emitTagAsBoolImmediate(X86::eax);
-            emitPutVirtualRegister(dst);
-
-            NEXT_OPCODE(op_neq_null);
-        }
-        case op_enter: {
-            // Even though CTI doesn't use them, we initialize our constant
-            // registers to zap stale pointers, to avoid unnecessarily prolonging
-            // object lifetime and increasing GC pressure.
-            size_t count = m_codeBlock->m_numVars + m_codeBlock->numberOfConstantRegisters();
-            for (size_t j = 0; j < count; ++j)
-                emitInitRegister(j);
-
-            NEXT_OPCODE(op_enter);
-        }
-        case op_enter_with_activation: {
-            // Even though CTI doesn't use them, we initialize our constant
-            // registers to zap stale pointers, to avoid unnecessarily prolonging
-            // object lifetime and increasing GC pressure.
-            size_t count = m_codeBlock->m_numVars + m_codeBlock->numberOfConstantRegisters();
-            for (size_t j = 0; j < count; ++j)
-                emitInitRegister(j);
-
-            emitCTICall(Interpreter::cti_op_push_activation);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-
-            NEXT_OPCODE(op_enter_with_activation);
-        }
-        case op_create_arguments: {
-            if (m_codeBlock->m_numParameters == 1)
-                emitCTICall(Interpreter::cti_op_create_arguments_no_params);
-            else
-                emitCTICall(Interpreter::cti_op_create_arguments);
-            NEXT_OPCODE(op_create_arguments);
-        }
-        case op_convert_this: {
-            emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
-
-            emitJumpSlowCaseIfNotJSCell(X86::eax);
-            loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
-            addSlowCase(jnz32(Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
-
-            NEXT_OPCODE(op_convert_this);
-        }
-        case op_profile_will_call: {
-            emitGetCTIParam(STUB_ARGS_profilerReference, X86::eax);
-            Jump noProfiler = jzPtr(Address(X86::eax));
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::eax);
-            emitCTICall(Interpreter::cti_op_profile_will_call);
-            noProfiler.link(this);
-
-            NEXT_OPCODE(op_profile_will_call);
-        }
-        case op_profile_did_call: {
-            emitGetCTIParam(STUB_ARGS_profilerReference, X86::eax);
-            Jump noProfiler = jzPtr(Address(X86::eax));
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::eax);
-            emitCTICall(Interpreter::cti_op_profile_did_call);
-            noProfiler.link(this);
-
-            NEXT_OPCODE(op_profile_did_call);
-        }
         case op_get_array_length:
         case op_get_by_id_chain:
         case op_get_by_id_generic:
@@ -1254,11 +328,11 @@ void JIT::privateCompileMainPass()
         }
     }
 
-    ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfStructureStubInfos());
-    ASSERT(callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
+    ASSERT(m_propertyAccessInstructionIndex == m_codeBlock->numberOfStructureStubInfos());
+    ASSERT(m_callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
 
 #ifndef NDEBUG
-    // reset this, in order to guard it's use with asserts
+    // Reset this, in order to guard its use with ASSERTs.
     m_bytecodeIndex = (unsigned)-1;
 #endif
 }
@@ -1275,12 +349,17 @@ void JIT::privateCompileLinkPass()
 void JIT::privateCompileSlowCases()
 {
     Instruction* instructionsBegin = m_codeBlock->instructions().begin();
-    unsigned propertyAccessInstructionIndex = 0;
-    unsigned callLinkInfoIndex = 0;
+
+    m_propertyAccessInstructionIndex = 0;
+#if USE(JSVALUE32_64)
+    m_globalResolveInfoIndex = 0;
+#endif
+    m_callLinkInfoIndex = 0;
 
     for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end();) {
-        // FIXME: enable peephole optimizations for slow cases when applicable
+#if !USE(JSVALUE32_64)
         killLastResultRegister();
+#endif
 
         m_bytecodeIndex = iter->to;
 #ifndef NDEBUG
@@ -1288,316 +367,56 @@ void JIT::privateCompileSlowCases()
 #endif
         Instruction* currentInstruction = instructionsBegin + m_bytecodeIndex;
 
-        switch (OpcodeID opcodeID = m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
-        case op_convert_this: {
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-            emitPutJITStubArg(X86::eax, 1);
-            emitCTICall(Interpreter::cti_op_convert_this);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_convert_this);
-        }
-        case op_add: {
-            compileFastArithSlow_op_add(currentInstruction, iter);
-            NEXT_OPCODE(op_add);
-        }
-        case op_construct_verify: {
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-            emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-
-            NEXT_OPCODE(op_construct_verify);
-        }
-        case op_get_by_val: {
-            // The slow case that handles accesses to arrays (below) may jump back up to here. 
-            Label beginGetByValSlow(this);
-
-            Jump notImm = getSlowCase(iter);
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-            emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
-            notImm.link(this);
-            emitPutJITStubArg(X86::eax, 1);
-            emitPutJITStubArg(X86::edx, 2);
-            emitCTICall(Interpreter::cti_op_get_by_val);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
-
-            // This is slow case that handles accesses to arrays above the fast cut-off.
-            // First, check if this is an access to the vector
-            linkSlowCase(iter);
-            jae32(X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength)), beginGetByValSlow);
-
-            // okay, missed the fast region, but it is still in the vector.  Get the value.
-            loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::ecx);
-            // Check whether the value loaded is zero; if so we need to return undefined.
-            jzPtr(X86::ecx, beginGetByValSlow);
-            move(X86::ecx, X86::eax);
-            emitPutVirtualRegister(currentInstruction[1].u.operand, X86::eax);
-
-            NEXT_OPCODE(op_get_by_val);
-        }
-        case op_sub: {
-            compileFastArithSlow_op_sub(currentInstruction, iter);
-            NEXT_OPCODE(op_sub);
-        }
-        case op_rshift: {
-            compileFastArithSlow_op_rshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter);
-            NEXT_OPCODE(op_rshift);
-        }
-        case op_lshift: {
-            compileFastArithSlow_op_lshift(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter);
-            NEXT_OPCODE(op_lshift);
-        }
-        case op_loop_if_less: {
-            unsigned op2 = currentInstruction[2].u.operand;
-            unsigned target = currentInstruction[3].u.operand;
-            if (isOperandConstantImmediateInt(op2)) {
-                linkSlowCase(iter);
-                emitPutJITStubArg(X86::eax, 1);
-                emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-                emitCTICall(Interpreter::cti_op_loop_if_less);
-                emitJumpSlowToHot(jnz32(X86::eax), target + 3);
-            } else {
-                linkSlowCase(iter);
-                linkSlowCase(iter);
-                emitPutJITStubArg(X86::eax, 1);
-                emitPutJITStubArg(X86::edx, 2);
-                emitCTICall(Interpreter::cti_op_loop_if_less);
-                emitJumpSlowToHot(jnz32(X86::eax), target + 3);
-            }
-            NEXT_OPCODE(op_loop_if_less);
-        }
-        case op_put_by_id: {
-            compilePutByIdSlowCase(currentInstruction[1].u.operand, &(m_codeBlock->identifier(currentInstruction[2].u.operand)), currentInstruction[3].u.operand, iter, propertyAccessInstructionIndex++);
-            NEXT_OPCODE(op_put_by_id);
-        }
-        case op_get_by_id: {
-            compileGetByIdSlowCase(currentInstruction[1].u.operand, currentInstruction[2].u.operand, &(m_codeBlock->identifier(currentInstruction[3].u.operand)), iter, propertyAccessInstructionIndex++);
-            NEXT_OPCODE(op_get_by_id);
-        }
-        case op_loop_if_lesseq: {
-            unsigned op2 = currentInstruction[2].u.operand;
-            unsigned target = currentInstruction[3].u.operand;
-            if (isOperandConstantImmediateInt(op2)) {
-                linkSlowCase(iter);
-                emitPutJITStubArg(X86::eax, 1);
-                emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, X86::ecx);
-                emitCTICall(Interpreter::cti_op_loop_if_lesseq);
-                emitJumpSlowToHot(jnz32(X86::eax), target + 3);
-            } else {
-                linkSlowCase(iter);
-                linkSlowCase(iter);
-                emitPutJITStubArg(X86::eax, 1);
-                emitPutJITStubArg(X86::edx, 2);
-                emitCTICall(Interpreter::cti_op_loop_if_lesseq);
-                emitJumpSlowToHot(jnz32(X86::eax), target + 3);
-            }
-            NEXT_OPCODE(op_loop_if_lesseq);
-        }
-        case op_pre_inc: {
-            compileFastArithSlow_op_pre_inc(currentInstruction[1].u.operand, iter);
-            NEXT_OPCODE(op_pre_inc);
-        }
-        case op_put_by_val: {
-            // Normal slow cases - either is not an immediate imm, or is an array.
-            Jump notImm = getSlowCase(iter);
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-            emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
-            notImm.link(this);
-            emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx);
-            emitPutJITStubArg(X86::eax, 1);
-            emitPutJITStubArg(X86::edx, 2);
-            emitPutJITStubArg(X86::ecx, 3);
-            emitCTICall(Interpreter::cti_op_put_by_val);
-            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_put_by_val));
-
-            // slow cases for immediate int accesses to arrays
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-            emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx);
-            emitPutJITStubArg(X86::eax, 1);
-            emitPutJITStubArg(X86::edx, 2);
-            emitPutJITStubArg(X86::ecx, 3);
-            emitCTICall(Interpreter::cti_op_put_by_val_array);
-
-            NEXT_OPCODE(op_put_by_val);
-        }
-        case op_loop_if_true: {
-            linkSlowCase(iter);
-            emitPutJITStubArg(X86::eax, 1);
-            emitCTICall(Interpreter::cti_op_jtrue);
-            unsigned target = currentInstruction[2].u.operand;
-            emitJumpSlowToHot(jnz32(X86::eax), target + 2);
-            NEXT_OPCODE(op_loop_if_true);
-        }
-        case op_pre_dec: {
-            compileFastArithSlow_op_pre_dec(currentInstruction[1].u.operand, iter);
-            NEXT_OPCODE(op_pre_dec);
-        }
-        case op_jnless: {
-            unsigned op2 = currentInstruction[2].u.operand;
-            unsigned target = currentInstruction[3].u.operand;
-            if (isOperandConstantImmediateInt(op2)) {
-                linkSlowCase(iter);
-                emitPutJITStubArg(X86::eax, 1);
-                emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, X86::ecx);
-                emitCTICall(Interpreter::cti_op_jless);
-                emitJumpSlowToHot(jz32(X86::eax), target + 3);
-            } else {
-                linkSlowCase(iter);
-                linkSlowCase(iter);
-                emitPutJITStubArg(X86::eax, 1);
-                emitPutJITStubArg(X86::edx, 2);
-                emitCTICall(Interpreter::cti_op_jless);
-                emitJumpSlowToHot(jz32(X86::eax), target + 3);
-            }
-            NEXT_OPCODE(op_jnless);
-        }
-        case op_not: {
-            linkSlowCase(iter);
-            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
-            emitPutJITStubArg(X86::eax, 1);
-            emitCTICall(Interpreter::cti_op_not);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_not);
-        }
-        case op_jfalse: {
-            linkSlowCase(iter);
-            emitPutJITStubArg(X86::eax, 1);
-            emitCTICall(Interpreter::cti_op_jtrue);
-            unsigned target = currentInstruction[2].u.operand;
-            emitJumpSlowToHot(jz32(X86::eax), target + 2); // inverted!
-            NEXT_OPCODE(op_jfalse);
-        }
-        case op_post_inc: {
-            compileFastArithSlow_op_post_inc(currentInstruction[1].u.operand, currentInstruction[2].u.operand, iter);
-            NEXT_OPCODE(op_post_inc);
-        }
-        case op_bitnot: {
-            linkSlowCase(iter);
-            emitPutJITStubArg(X86::eax, 1);
-            emitCTICall(Interpreter::cti_op_bitnot);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_bitnot);
-        }
-        case op_bitand: {
-            compileFastArithSlow_op_bitand(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter);
-            NEXT_OPCODE(op_bitand);
-        }
-        case op_jtrue: {
-            linkSlowCase(iter);
-            emitPutJITStubArg(X86::eax, 1);
-            emitCTICall(Interpreter::cti_op_jtrue);
-            unsigned target = currentInstruction[2].u.operand;
-            emitJumpSlowToHot(jnz32(X86::eax), target + 2);
-            NEXT_OPCODE(op_jtrue);
-        }
-        case op_post_dec: {
-            compileFastArithSlow_op_post_dec(currentInstruction[1].u.operand, currentInstruction[2].u.operand, iter);
-            NEXT_OPCODE(op_post_dec);
-        }
-        case op_bitxor: {
-            linkSlowCase(iter);
-            emitPutJITStubArg(X86::eax, 1);
-            emitPutJITStubArg(X86::edx, 2);
-            emitCTICall(Interpreter::cti_op_bitxor);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_bitxor);
-        }
-        case op_bitor: {
-            linkSlowCase(iter);
-            emitPutJITStubArg(X86::eax, 1);
-            emitPutJITStubArg(X86::edx, 2);
-            emitCTICall(Interpreter::cti_op_bitor);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_bitor);
-        }
-        case op_eq: {
-            linkSlowCase(iter);
-            emitPutJITStubArg(X86::eax, 1);
-            emitPutJITStubArg(X86::edx, 2);
-            emitCTICall(Interpreter::cti_op_eq);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_eq);
-        }
-        case op_neq: {
-            linkSlowCase(iter);
-            emitPutJITStubArg(X86::eax, 1);
-            emitPutJITStubArg(X86::edx, 2);
-            emitCTICall(Interpreter::cti_op_neq);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_neq);
-        }
-        case op_stricteq: {
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-#if !USE(ALTERNATE_JSIMMEDIATE)
-            linkSlowCase(iter);
+        switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
+        DEFINE_SLOWCASE_OP(op_add)
+        DEFINE_SLOWCASE_OP(op_bitand)
+        DEFINE_SLOWCASE_OP(op_bitnot)
+        DEFINE_SLOWCASE_OP(op_bitor)
+        DEFINE_SLOWCASE_OP(op_bitxor)
+        DEFINE_SLOWCASE_OP(op_call)
+        DEFINE_SLOWCASE_OP(op_call_eval)
+        DEFINE_SLOWCASE_OP(op_call_varargs)
+        DEFINE_SLOWCASE_OP(op_construct)
+        DEFINE_SLOWCASE_OP(op_construct_verify)
+        DEFINE_SLOWCASE_OP(op_convert_this)
+#if USE(JSVALUE32_64)
+        DEFINE_SLOWCASE_OP(op_div)
 #endif
-            emitPutJITStubArg(X86::eax, 1);
-            emitPutJITStubArg(X86::edx, 2);
-            emitCTICall(Interpreter::cti_op_stricteq);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_stricteq);
-        }
-        case op_nstricteq: {
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-#if !USE(ALTERNATE_JSIMMEDIATE)
-            linkSlowCase(iter);
+        DEFINE_SLOWCASE_OP(op_eq)
+        DEFINE_SLOWCASE_OP(op_get_by_id)
+        DEFINE_SLOWCASE_OP(op_get_by_val)
+        DEFINE_SLOWCASE_OP(op_instanceof)
+        DEFINE_SLOWCASE_OP(op_jfalse)
+        DEFINE_SLOWCASE_OP(op_jnless)
+        DEFINE_SLOWCASE_OP(op_jnlesseq)
+        DEFINE_SLOWCASE_OP(op_jtrue)
+        DEFINE_SLOWCASE_OP(op_loop_if_less)
+        DEFINE_SLOWCASE_OP(op_loop_if_lesseq)
+        DEFINE_SLOWCASE_OP(op_loop_if_true)
+        DEFINE_SLOWCASE_OP(op_lshift)
+        DEFINE_SLOWCASE_OP(op_method_check)
+        DEFINE_SLOWCASE_OP(op_mod)
+        DEFINE_SLOWCASE_OP(op_mul)
+#if USE(JSVALUE32_64)
+        DEFINE_SLOWCASE_OP(op_negate)
 #endif
-            emitPutJITStubArg(X86::eax, 1);
-            emitPutJITStubArg(X86::edx, 2);
-            emitCTICall(Interpreter::cti_op_nstricteq);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_nstricteq);
-        }
-        case op_instanceof: {
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-            linkSlowCase(iter);
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
-            emitPutJITStubArgFromVirtualRegister(currentInstruction[4].u.operand, 3, X86::ecx);
-            emitCTICall(Interpreter::cti_op_instanceof);
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_instanceof);
-        }
-        case op_mod: {
-            compileFastArithSlow_op_mod(currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, iter);
-            NEXT_OPCODE(op_mod);
-        }
-        case op_mul: {
-            compileFastArithSlow_op_mul(currentInstruction, iter);
-            NEXT_OPCODE(op_mul);
-        }
-
-        case op_call: {
-            compileOpCallSlowCase(currentInstruction, iter, callLinkInfoIndex++, opcodeID);
-            NEXT_OPCODE(op_call);
-        }
-        case op_call_eval: {
-            compileOpCallSlowCase(currentInstruction, iter, callLinkInfoIndex++, opcodeID);
-            NEXT_OPCODE(op_call_eval);
-        }
-        case op_construct: {
-            compileOpCallSlowCase(currentInstruction, iter, callLinkInfoIndex++, opcodeID);
-            NEXT_OPCODE(op_construct);
-        }
-        case op_to_jsnumber: {
-            linkSlowCaseIfNotJSCell(iter, currentInstruction[2].u.operand);
-            linkSlowCase(iter);
-
-            emitPutJITStubArg(X86::eax, 1);
-            emitCTICall(Interpreter::cti_op_to_jsnumber);
-
-            emitPutVirtualRegister(currentInstruction[1].u.operand);
-            NEXT_OPCODE(op_to_jsnumber);
-        }
-
+        DEFINE_SLOWCASE_OP(op_neq)
+        DEFINE_SLOWCASE_OP(op_not)
+        DEFINE_SLOWCASE_OP(op_nstricteq)
+        DEFINE_SLOWCASE_OP(op_post_dec)
+        DEFINE_SLOWCASE_OP(op_post_inc)
+        DEFINE_SLOWCASE_OP(op_pre_dec)
+        DEFINE_SLOWCASE_OP(op_pre_inc)
+        DEFINE_SLOWCASE_OP(op_put_by_id)
+        DEFINE_SLOWCASE_OP(op_put_by_val)
+#if USE(JSVALUE32_64)
+        DEFINE_SLOWCASE_OP(op_resolve_global)
+#endif
+        DEFINE_SLOWCASE_OP(op_rshift)
+        DEFINE_SLOWCASE_OP(op_stricteq)
+        DEFINE_SLOWCASE_OP(op_sub)
+        DEFINE_SLOWCASE_OP(op_to_jsnumber)
+        DEFINE_SLOWCASE_OP(op_to_primitive)
         default:
             ASSERT_NOT_REACHED();
         }
@@ -1609,12 +428,12 @@ void JIT::privateCompileSlowCases()
     }
 
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
-    ASSERT(propertyAccessInstructionIndex == m_codeBlock->numberOfStructureStubInfos());
+    ASSERT(m_propertyAccessInstructionIndex == m_codeBlock->numberOfStructureStubInfos());
 #endif
-    ASSERT(callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
+    ASSERT(m_callLinkInfoIndex == m_codeBlock->numberOfCallLinkInfos());
 
 #ifndef NDEBUG
-    // reset this, in order to guard it's use with asserts
+    // Reset this, in order to guard its use with ASSERTs.
     m_bytecodeIndex = (unsigned)-1;
 #endif
 }
@@ -1627,8 +446,8 @@ void JIT::privateCompile()
 #endif
 
     // Could use a pop_m, but would need to offset the following instruction if so.
-    pop(X86::ecx);
-    emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC);
+    preserveReturnAddressAfterCall(regT2);
+    emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
 
     Jump slowRegisterFileCheck;
     Label afterRegisterFileCheck;
@@ -1636,10 +455,10 @@ void JIT::privateCompile()
         // In the case of a fast linked call, we do not set this up in the caller.
         emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock);
 
-        emitGetCTIParam(STUB_ARGS_registerFile, X86::eax);
-        addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, X86::edx);
-        
-        slowRegisterFileCheck = jg32(X86::edx, Address(X86::eax, FIELD_OFFSET(RegisterFile, m_end)));
+        peek(regT0, OBJECT_OFFSETOF(JITStackFrame, registerFile) / sizeof (void*));
+        addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1);
+
+        slowRegisterFileCheck = branchPtr(Above, regT1, Address(regT0, OBJECT_OFFSETOF(RegisterFile, m_end)));
         afterRegisterFileCheck = label();
     }
 
@@ -1649,25 +468,17 @@ void JIT::privateCompile()
 
     if (m_codeBlock->codeType() == FunctionCode) {
         slowRegisterFileCheck.link(this);
-        m_bytecodeIndex = 0; // emitCTICall will add to the map, but doesn't actually need this...
-        emitCTICall(Interpreter::cti_register_file_check);
+        m_bytecodeIndex = 0;
+        JITStubCall(this, cti_register_file_check).call();
 #ifndef NDEBUG
-        // reset this, in order to guard it's use with asserts
-        m_bytecodeIndex = (unsigned)-1;
+        m_bytecodeIndex = (unsigned)-1; // Reset this, in order to guard its use with ASSERTs.
 #endif
         jump(afterRegisterFileCheck);
     }
 
     ASSERT(m_jmpTable.isEmpty());
 
-    RefPtr<ExecutablePool> allocator = m_globalData->poolForSize(m_assembler.size());
-    void* code = m_assembler.executableCopy(allocator.get());
-    JITCodeRef codeRef(code, allocator);
-#ifndef NDEBUG
-    codeRef.codeSize = m_assembler.size();
-#endif
-
-    PatchBuffer patchBuffer(code);
+    LinkBuffer patchBuffer(this, m_globalData->executableAllocator.poolForSize(m_assembler.size()));
 
     // Translate vPC offsets into addresses in JIT generated code, for switch tables.
     for (unsigned i = 0; i < m_switches.size(); ++i) {
@@ -1678,266 +489,123 @@ void JIT::privateCompile()
             ASSERT(record.type == SwitchRecord::Immediate || record.type == SwitchRecord::Character); 
             ASSERT(record.jumpTable.simpleJumpTable->branchOffsets.size() == record.jumpTable.simpleJumpTable->ctiOffsets.size());
 
-            record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
+            record.jumpTable.simpleJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
 
             for (unsigned j = 0; j < record.jumpTable.simpleJumpTable->branchOffsets.size(); ++j) {
                 unsigned offset = record.jumpTable.simpleJumpTable->branchOffsets[j];
-                record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault;
+                record.jumpTable.simpleJumpTable->ctiOffsets[j] = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.simpleJumpTable->ctiDefault;
             }
         } else {
             ASSERT(record.type == SwitchRecord::String);
 
-            record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
+            record.jumpTable.stringJumpTable->ctiDefault = patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + record.defaultOffset]);
 
             StringJumpTable::StringOffsetTable::iterator end = record.jumpTable.stringJumpTable->offsetTable.end();            
             for (StringJumpTable::StringOffsetTable::iterator it = record.jumpTable.stringJumpTable->offsetTable.begin(); it != end; ++it) {
                 unsigned offset = it->second.branchOffset;
-                it->second.ctiOffset = offset ? patchBuffer.addressOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault;
+                it->second.ctiOffset = offset ? patchBuffer.locationOf(m_labels[bytecodeIndex + 3 + offset]) : record.jumpTable.stringJumpTable->ctiDefault;
             }
         }
     }
 
     for (size_t i = 0; i < m_codeBlock->numberOfExceptionHandlers(); ++i) {
         HandlerInfo& handler = m_codeBlock->exceptionHandler(i);
-        handler.nativeCode = patchBuffer.addressOf(m_labels[handler.target]);
+        handler.nativeCode = patchBuffer.locationOf(m_labels[handler.target]);
     }
 
     for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
         if (iter->to)
-            patchBuffer.link(iter->from, iter->to);
+            patchBuffer.link(iter->from, FunctionPtr(iter->to));
     }
 
     if (m_codeBlock->hasExceptionInfo()) {
-        m_codeBlock->pcVector().reserveCapacity(m_calls.size());
+        m_codeBlock->callReturnIndexVector().reserveCapacity(m_calls.size());
         for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter)
-            m_codeBlock->pcVector().append(PC(reinterpret_cast<void**>(patchBuffer.addressOf(iter->from)) - reinterpret_cast<void**>(code), iter->bytecodeIndex));
+            m_codeBlock->callReturnIndexVector().append(CallReturnOffsetToBytecodeIndex(patchBuffer.returnAddressOffset(iter->from), iter->bytecodeIndex));
     }
 
     // Link absolute addresses for jsr
     for (Vector<JSRInfo>::iterator iter = m_jsrSites.begin(); iter != m_jsrSites.end(); ++iter)
-        patchBuffer.setPtr(iter->storeLocation, patchBuffer.addressOf(iter->target));
+        patchBuffer.patch(iter->storeLocation, patchBuffer.locationOf(iter->target).executableAddress());
 
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
     for (unsigned i = 0; i < m_codeBlock->numberOfStructureStubInfos(); ++i) {
         StructureStubInfo& info = m_codeBlock->structureStubInfo(i);
-#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
-        info.callReturnLocation = patchBuffer.addressOf(m_propertyAccessCompilationInfo[i].callReturnLocation);
-        info.hotPathBegin = patchBuffer.addressOf(m_propertyAccessCompilationInfo[i].hotPathBegin);
-#else
-        info.callReturnLocation = 0;
-        info.hotPathBegin = 0;
-#endif
+        info.callReturnLocation = patchBuffer.locationOf(m_propertyAccessCompilationInfo[i].callReturnLocation);
+        info.hotPathBegin = patchBuffer.locationOf(m_propertyAccessCompilationInfo[i].hotPathBegin);
     }
+#endif
+#if ENABLE(JIT_OPTIMIZE_CALL)
     for (unsigned i = 0; i < m_codeBlock->numberOfCallLinkInfos(); ++i) {
         CallLinkInfo& info = m_codeBlock->callLinkInfo(i);
-#if ENABLE(JIT_OPTIMIZE_CALL)
-        info.callReturnLocation = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].callReturnLocation);
-        info.hotPathBegin = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].hotPathBegin);
-        info.hotPathOther = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].hotPathOther);
-        info.coldPathOther = patchBuffer.addressOf(m_callStructureStubCompilationInfo[i].coldPathOther);
-#else
-        info.callReturnLocation = 0;
-        info.hotPathBegin = 0;
-        info.hotPathOther = 0;
-        info.coldPathOther = 0;
+        info.ownerCodeBlock = m_codeBlock;
+        info.callReturnLocation = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].callReturnLocation);
+        info.hotPathBegin = patchBuffer.locationOf(m_callStructureStubCompilationInfo[i].hotPathBegin);
+        info.hotPathOther = patchBuffer.locationOfNearCall(m_callStructureStubCompilationInfo[i].hotPathOther);
+    }
 #endif
+    unsigned methodCallCount = m_methodCallCompilationInfo.size();
+    m_codeBlock->addMethodCallLinkInfos(methodCallCount);
+    for (unsigned i = 0; i < methodCallCount; ++i) {
+        MethodCallLinkInfo& info = m_codeBlock->methodCallLinkInfo(i);
+        info.structureLabel = patchBuffer.locationOf(m_methodCallCompilationInfo[i].structureToCompare);
+        info.callReturnLocation = m_codeBlock->structureStubInfo(m_methodCallCompilationInfo[i].propertyAccessIndex).callReturnLocation;
     }
 
-    m_codeBlock->setJITCode(codeRef);
+    m_codeBlock->setJITCode(patchBuffer.finalizeCode());
 }
 
-void JIT::privateCompileCTIMachineTrampolines()
+#if !USE(JSVALUE32_64)
+void JIT::emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst)
 {
-#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
-    // (1) The first function provides fast property access for array length
-    Label arrayLengthBegin = align();
-
-    // Check eax is an array
-    Jump array_failureCases1 = emitJumpIfNotJSCell(X86::eax);
-    Jump array_failureCases2 = jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr));
-
-    // Checks out okay! - get the length from the storage
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::eax);
-    load32(Address(X86::eax, FIELD_OFFSET(ArrayStorage, m_length)), X86::eax);
-
-    Jump array_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt));
-
-    // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
-    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
-
-    ret();
-
-    // (2) The second function provides fast property access for string length
-    Label stringLengthBegin = align();
-
-    // Check eax is a string
-    Jump string_failureCases1 = emitJumpIfNotJSCell(X86::eax);
-    Jump string_failureCases2 = jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsStringVptr));
-
-    // Checks out okay! - get the length from the Ustring.
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSString, m_value) + FIELD_OFFSET(UString, m_rep)), X86::eax);
-    load32(Address(X86::eax, FIELD_OFFSET(UString::Rep, len)), X86::eax);
-
-    Jump string_failureCases3 = ja32(X86::eax, Imm32(JSImmediate::maxImmediateInt));
+    loadPtr(Address(variableObject, OBJECT_OFFSETOF(JSVariableObject, d)), dst);
+    loadPtr(Address(dst, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), dst);
+    loadPtr(Address(dst, index * sizeof(Register)), dst);
+}
 
-    // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
-    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
-    
-    ret();
+void JIT::emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index)
+{
+    loadPtr(Address(variableObject, OBJECT_OFFSETOF(JSVariableObject, d)), variableObject);
+    loadPtr(Address(variableObject, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), variableObject);
+    storePtr(src, Address(variableObject, index * sizeof(Register)));
+}
 #endif
 
-    // (3) Trampolines for the slow cases of op_call / op_call_eval / op_construct.
-    
-    Label virtualCallPreLinkBegin = align();
-
-    // Load the callee CodeBlock* into eax
-    loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
-    loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
-    Jump hasCodeBlock1 = jnzPtr(X86::eax);
-    pop(X86::ebx);
-    restoreArgumentReference();
-    Jump callJSFunction1 = call();
-    emitGetJITStubArg(1, X86::ecx);
-    emitGetJITStubArg(3, X86::edx);
-    push(X86::ebx);
-    hasCodeBlock1.link(this);
-
-    // Check argCount matches callee arity.
-    Jump arityCheckOkay1 = je32(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
-    pop(X86::ebx);
-    emitPutJITStubArg(X86::ebx, 2);
-    emitPutJITStubArg(X86::eax, 4);
-    restoreArgumentReference();
-    Jump callArityCheck1 = call();
-    move(X86::edx, callFrameRegister);
-    emitGetJITStubArg(1, X86::ecx);
-    emitGetJITStubArg(3, X86::edx);
-    push(X86::ebx);
-    arityCheckOkay1.link(this);
-    
-    compileOpCallInitializeCallFrame();
-
-    pop(X86::ebx);
-    emitPutJITStubArg(X86::ebx, 2);
-    restoreArgumentReference();
-    Jump callDontLazyLinkCall = call();
-    push(X86::ebx);
-
-    jump(X86::eax);
-
-    Label virtualCallLinkBegin = align();
-
-    // Load the callee CodeBlock* into eax
-    loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
-    loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
-    Jump hasCodeBlock2 = jnzPtr(X86::eax);
-    pop(X86::ebx);
-    restoreArgumentReference();
-    Jump callJSFunction2 = call();
-    emitGetJITStubArg(1, X86::ecx);
-    emitGetJITStubArg(3, X86::edx);
-    push(X86::ebx);
-    hasCodeBlock2.link(this);
-
-    // Check argCount matches callee arity.
-    Jump arityCheckOkay2 = je32(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
-    pop(X86::ebx);
-    emitPutJITStubArg(X86::ebx, 2);
-    emitPutJITStubArg(X86::eax, 4);
-    restoreArgumentReference();
-    Jump callArityCheck2 = call();
-    move(X86::edx, callFrameRegister);
-    emitGetJITStubArg(1, X86::ecx);
-    emitGetJITStubArg(3, X86::edx);
-    push(X86::ebx);
-    arityCheckOkay2.link(this);
-
-    compileOpCallInitializeCallFrame();
-
-    pop(X86::ebx);
-    emitPutJITStubArg(X86::ebx, 2);
-    restoreArgumentReference();
-    Jump callLazyLinkCall = call();
-    push(X86::ebx);
-
-    jump(X86::eax);
-
-    Label virtualCallBegin = align();
-
-    // Load the callee CodeBlock* into eax
-    loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
-    loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
-    Jump hasCodeBlock3 = jnzPtr(X86::eax);
-    pop(X86::ebx);
-    restoreArgumentReference();
-    Jump callJSFunction3 = call();
-    emitGetJITStubArg(1, X86::ecx);
-    emitGetJITStubArg(3, X86::edx);
-    push(X86::ebx);
-    hasCodeBlock3.link(this);
-
-    // Check argCount matches callee arity.
-    Jump arityCheckOkay3 = je32(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
-    pop(X86::ebx);
-    emitPutJITStubArg(X86::ebx, 2);
-    emitPutJITStubArg(X86::eax, 4);
-    restoreArgumentReference();
-    Jump callArityCheck3 = call();
-    move(X86::edx, callFrameRegister);
-    emitGetJITStubArg(1, X86::ecx);
-    emitGetJITStubArg(3, X86::edx);
-    push(X86::ebx);
-    arityCheckOkay3.link(this);
-
-    compileOpCallInitializeCallFrame();
-
-    // load ctiCode from the new codeBlock.
-    loadPtr(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_jitCode)), X86::eax);
-
-    jump(X86::eax);
-
-    // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
-    m_interpreter->m_executablePool = m_globalData->poolForSize(m_assembler.size());
-    void* code = m_assembler.executableCopy(m_interpreter->m_executablePool.get());
-    PatchBuffer patchBuffer(code);
-
-#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
-    patchBuffer.link(array_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
-    patchBuffer.link(array_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
-    patchBuffer.link(array_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
-    patchBuffer.link(string_failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
-    patchBuffer.link(string_failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
-    patchBuffer.link(string_failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_string_fail));
-
-    m_interpreter->m_ctiArrayLengthTrampoline = patchBuffer.addressOf(arrayLengthBegin);
-    m_interpreter->m_ctiStringLengthTrampoline = patchBuffer.addressOf(stringLengthBegin);
+#if ENABLE(JIT_OPTIMIZE_CALL)
+void JIT::unlinkCall(CallLinkInfo* callLinkInfo)
+{
+    // When the JSFunction is deleted the pointer embedded in the instruction stream will no longer be valid
+    // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive
+    // match).  Reset the check so it no longer matches.
+    RepatchBuffer repatchBuffer(callLinkInfo->ownerCodeBlock);
+#if USE(JSVALUE32_64)
+    repatchBuffer.repatch(callLinkInfo->hotPathBegin, 0);
+#else
+    repatchBuffer.repatch(callLinkInfo->hotPathBegin, JSValue::encode(JSValue()));
 #endif
-    patchBuffer.link(callArityCheck1, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
-    patchBuffer.link(callArityCheck2, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
-    patchBuffer.link(callArityCheck3, reinterpret_cast<void*>(Interpreter::cti_op_call_arityCheck));
-    patchBuffer.link(callJSFunction1, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
-    patchBuffer.link(callJSFunction2, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
-    patchBuffer.link(callJSFunction3, reinterpret_cast<void*>(Interpreter::cti_op_call_JSFunction));
-    patchBuffer.link(callDontLazyLinkCall, reinterpret_cast<void*>(Interpreter::cti_vm_dontLazyLinkCall));
-    patchBuffer.link(callLazyLinkCall, reinterpret_cast<void*>(Interpreter::cti_vm_lazyLinkCall));
-
-    m_interpreter->m_ctiVirtualCallPreLink = patchBuffer.addressOf(virtualCallPreLinkBegin);
-    m_interpreter->m_ctiVirtualCallLink = patchBuffer.addressOf(virtualCallLinkBegin);
-    m_interpreter->m_ctiVirtualCall = patchBuffer.addressOf(virtualCallBegin);
 }
 
-void JIT::emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst)
+void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JITCode& code, CallLinkInfo* callLinkInfo, int callerArgCount, JSGlobalData* globalData)
 {
-    loadPtr(Address(variableObject, FIELD_OFFSET(JSVariableObject, d)), dst);
-    loadPtr(Address(dst, FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers)), dst);
-    loadPtr(Address(dst, index * sizeof(Register)), dst);
-}
+    ASSERT(calleeCodeBlock);
+    RepatchBuffer repatchBuffer(callerCodeBlock);
 
-void JIT::emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index)
-{
-    loadPtr(Address(variableObject, FIELD_OFFSET(JSVariableObject, d)), variableObject);
-    loadPtr(Address(variableObject, FIELD_OFFSET(JSVariableObject::JSVariableObjectData, registers)), variableObject);
-    storePtr(src, Address(variableObject, index * sizeof(Register)));
+    // Currently we only link calls with the exact number of arguments.
+    // If this is a native call calleeCodeBlock is null so the number of parameters is unimportant
+    if (callerArgCount == calleeCodeBlock->m_numParameters || calleeCodeBlock->codeType() == NativeCode) {
+        ASSERT(!callLinkInfo->isLinked());
+    
+        if (calleeCodeBlock)
+            calleeCodeBlock->addCaller(callLinkInfo);
+    
+        repatchBuffer.repatch(callLinkInfo->hotPathBegin, callee);
+        repatchBuffer.relink(callLinkInfo->hotPathOther, code.addressForCall());
+    }
+
+    // patch the call so we do not continue to try to link.
+    repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs.ctiVirtualCall());
 }
+#endif // ENABLE(JIT_OPTIMIZE_CALL)
 
 } // namespace JSC
 
index d13fbb50b5adf5cf5e887e7e24cfcd300571a3e7..040f842e3d2078829b7ff38622aa77f4c07023f2 100644 (file)
--- a/jit/JIT.h
+++ b/jit/JIT.h
 #define JIT_h
 
 #include <wtf/Platform.h>
-#include <bytecode/SamplingTool.h>
 
 #if ENABLE(JIT)
 
-#define WTF_USE_CTI_REPATCH_PIC 1
+// We've run into some problems where changing the size of the class JIT leads to
+// performance fluctuations.  Try forcing alignment in an attempt to stabalize this.
+#if COMPILER(GCC)
+#define JIT_CLASS_ALIGNMENT __attribute__ ((aligned (32)))
+#else
+#define JIT_CLASS_ALIGNMENT
+#endif
 
+#include "CodeBlock.h"
 #include "Interpreter.h"
+#include "JITCode.h"
+#include "JITStubs.h"
 #include "Opcode.h"
 #include "RegisterFile.h"
 #include "MacroAssembler.h"
 #include "Profiler.h"
+#include <bytecode/SamplingTool.h>
 #include <wtf/AlwaysInline.h>
 #include <wtf/Vector.h>
 
-#if PLATFORM(X86_64)
-#define STUB_ARGS_offset 0x10
-#else
-#define STUB_ARGS_offset 0x0C
-#endif
-
-#define STUB_ARGS_code (STUB_ARGS_offset)
-#define STUB_ARGS_registerFile (STUB_ARGS_offset + 1)
-#define STUB_ARGS_callFrame (STUB_ARGS_offset + 2)
-#define STUB_ARGS_exception (STUB_ARGS_offset + 3)
-#define STUB_ARGS_profilerReference (STUB_ARGS_offset + 4)
-#define STUB_ARGS_globalData (STUB_ARGS_offset + 5)
-
-#define ARG_callFrame static_cast<CallFrame*>(ARGS[STUB_ARGS_callFrame])
-#define ARG_registerFile static_cast<RegisterFile*>(ARGS[STUB_ARGS_registerFile])
-#define ARG_exception static_cast<JSValuePtr*>(ARGS[STUB_ARGS_exception])
-#define ARG_profilerReference static_cast<Profiler**>(ARGS[STUB_ARGS_profilerReference])
-#define ARG_globalData static_cast<JSGlobalData*>(ARGS[STUB_ARGS_globalData])
-
-#define ARG_setCallFrame(newCallFrame) (ARGS[STUB_ARGS_callFrame] = (newCallFrame))
-
-#define ARG_src1 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[1]))
-#define ARG_src2 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[2]))
-#define ARG_src3 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[3]))
-#define ARG_src4 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[4]))
-#define ARG_src5 JSValuePtr::decode(static_cast<JSValueEncodedAsPointer*>(ARGS[5]))
-#define ARG_id1 static_cast<Identifier*>(ARGS[1])
-#define ARG_id2 static_cast<Identifier*>(ARGS[2])
-#define ARG_id3 static_cast<Identifier*>(ARGS[3])
-#define ARG_id4 static_cast<Identifier*>(ARGS[4])
-#define ARG_int1 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[1]))
-#define ARG_int2 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[2]))
-#define ARG_int3 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[3]))
-#define ARG_int4 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[4]))
-#define ARG_int5 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[5]))
-#define ARG_int6 static_cast<int32_t>(reinterpret_cast<intptr_t>(ARGS[6]))
-#define ARG_func1 static_cast<FuncDeclNode*>(ARGS[1])
-#define ARG_funcexp1 static_cast<FuncExprNode*>(ARGS[1])
-#define ARG_regexp1 static_cast<RegExp*>(ARGS[1])
-#define ARG_pni1 static_cast<JSPropertyNameIterator*>(ARGS[1])
-#define ARG_returnAddress2 static_cast<void*>(ARGS[2])
-#define ARG_codeBlock4 static_cast<CodeBlock*>(ARGS[4])
-
-#define STUB_RETURN_ADDRESS_SLOT (ARGS[-1])
-
 namespace JSC {
 
     class CodeBlock;
+    class JIT;
     class JSPropertyNameIterator;
     class Interpreter;
     class Register;
@@ -104,16 +69,8 @@ namespace JSC {
     struct PolymorphicAccessStructureList;
     struct StructureStubInfo;
 
-    typedef JSValueEncodedAsPointer* (JIT_STUB *CTIHelper_j)(STUB_ARGS);
-    typedef JSObject* (JIT_STUB *CTIHelper_o)(STUB_ARGS);
-    typedef JSPropertyNameIterator* (JIT_STUB *CTIHelper_p)(STUB_ARGS);
-    typedef void (JIT_STUB *CTIHelper_v)(STUB_ARGS);
-    typedef void* (JIT_STUB *CTIHelper_s)(STUB_ARGS);
-    typedef int (JIT_STUB *CTIHelper_b)(STUB_ARGS);
-    typedef VoidPtrPair (JIT_STUB *CTIHelper_2)(STUB_ARGS);
-
     struct CallRecord {
-        MacroAssembler::Jump from;
+        MacroAssembler::Call from;
         unsigned bytecodeIndex;
         void* to;
 
@@ -121,7 +78,7 @@ namespace JSC {
         {
         }
 
-        CallRecord(MacroAssembler::Jump from, unsigned bytecodeIndex, void* to = 0)
+        CallRecord(MacroAssembler::Call from, unsigned bytecodeIndex, void* to = 0)
             : from(from)
             , bytecodeIndex(bytecodeIndex)
             , to(to)
@@ -188,44 +145,105 @@ namespace JSC {
     };
 
     struct PropertyStubCompilationInfo {
-        MacroAssembler::Jump callReturnLocation;
+        MacroAssembler::Call callReturnLocation;
         MacroAssembler::Label hotPathBegin;
     };
 
     struct StructureStubCompilationInfo {
         MacroAssembler::DataLabelPtr hotPathBegin;
-        MacroAssembler::Jump hotPathOther;
-        MacroAssembler::Jump callReturnLocation;
-        MacroAssembler::Label coldPathOther;
+        MacroAssembler::Call hotPathOther;
+        MacroAssembler::Call callReturnLocation;
     };
 
-    extern "C" {
-        JSValueEncodedAsPointer* ctiTrampoline(
-#if PLATFORM(X86_64)
-            // FIXME: (bug #22910) this will force all arguments onto the stack (regparm(0) does not appear to have any effect).
-            // We can allow register passing here, and move the writes of these values into the trampoline.
-            void*, void*, void*, void*, void*, void*,
-#endif
-            void* code, RegisterFile*, CallFrame*, JSValuePtr* exception, Profiler**, JSGlobalData*);
-        void ctiVMThrowTrampoline();
+    struct MethodCallCompilationInfo {
+        MethodCallCompilationInfo(unsigned propertyAccessIndex)
+            : propertyAccessIndex(propertyAccessIndex)
+        {
+        }
+
+        MacroAssembler::DataLabelPtr structureToCompare;
+        unsigned propertyAccessIndex;
     };
 
-    void ctiSetReturnAddress(void** where, void* what);
-    void ctiPatchCallByReturnAddress(void* where, void* what);
+    // Near calls can only be patched to other JIT code, regular calls can be patched to JIT code or relinked to stub functions.
+    void ctiPatchNearCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction);
+    void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction);
+    void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction);
 
     class JIT : private MacroAssembler {
+        friend class JITStubCall;
+
         using MacroAssembler::Jump;
         using MacroAssembler::JumpList;
         using MacroAssembler::Label;
 
+        // NOTES:
+        //
+        // regT0 has two special meanings.  The return value from a stub
+        // call will always be in regT0, and by default (unless
+        // a register is specified) emitPutVirtualRegister() will store
+        // the value from regT0.
+        //
+        // regT3 is required to be callee-preserved.
+        //
+        // tempRegister2 is has no such dependencies.  It is important that
+        // on x86/x86-64 it is ecx for performance reasons, since the
+        // MacroAssembler will need to plant register swaps if it is not -
+        // however the code will still function correctly.
 #if PLATFORM(X86_64)
+        static const RegisterID returnValueRegister = X86::eax;
+        static const RegisterID cachedResultRegister = X86::eax;
+        static const RegisterID firstArgumentRegister = X86::edi;
+
         static const RegisterID timeoutCheckRegister = X86::r12;
         static const RegisterID callFrameRegister = X86::r13;
         static const RegisterID tagTypeNumberRegister = X86::r14;
         static const RegisterID tagMaskRegister = X86::r15;
-#else
+
+        static const RegisterID regT0 = X86::eax;
+        static const RegisterID regT1 = X86::edx;
+        static const RegisterID regT2 = X86::ecx;
+        static const RegisterID regT3 = X86::ebx;
+
+        static const FPRegisterID fpRegT0 = X86::xmm0;
+        static const FPRegisterID fpRegT1 = X86::xmm1;
+        static const FPRegisterID fpRegT2 = X86::xmm2;
+#elif PLATFORM(X86)
+        static const RegisterID returnValueRegister = X86::eax;
+        static const RegisterID cachedResultRegister = X86::eax;
+        // On x86 we always use fastcall conventions = but on
+        // OS X if might make more sense to just use regparm.
+        static const RegisterID firstArgumentRegister = X86::ecx;
+
         static const RegisterID timeoutCheckRegister = X86::esi;
         static const RegisterID callFrameRegister = X86::edi;
+
+        static const RegisterID regT0 = X86::eax;
+        static const RegisterID regT1 = X86::edx;
+        static const RegisterID regT2 = X86::ecx;
+        static const RegisterID regT3 = X86::ebx;
+
+        static const FPRegisterID fpRegT0 = X86::xmm0;
+        static const FPRegisterID fpRegT1 = X86::xmm1;
+        static const FPRegisterID fpRegT2 = X86::xmm2;
+#elif PLATFORM_ARM_ARCH(7)
+        static const RegisterID returnValueRegister = ARM::r0;
+        static const RegisterID cachedResultRegister = ARM::r0;
+        static const RegisterID firstArgumentRegister = ARM::r0;
+
+        static const RegisterID regT0 = ARM::r0;
+        static const RegisterID regT1 = ARM::r1;
+        static const RegisterID regT2 = ARM::r2;
+        static const RegisterID regT3 = ARM::r4;
+
+        static const RegisterID callFrameRegister = ARM::r5;
+        static const RegisterID timeoutCheckRegister = ARM::r6;
+
+        static const FPRegisterID fpRegT0 = ARM::d0;
+        static const FPRegisterID fpRegT1 = ARM::d1;
+        static const FPRegisterID fpRegT2 = ARM::d2;
+#else
+    #error "JIT not supported on this platform."
 #endif
 
         static const int patchGetByIdDefaultStructure = -1;
@@ -233,50 +251,6 @@ namespace JSC {
         // will compress the displacement, and we may not be able to fit a patched offset.
         static const int patchGetByIdDefaultOffset = 256;
 
-#if USE(JIT_STUB_ARGUMENT_REGISTER)
-#if PLATFORM(X86_64)
-        static const int ctiArgumentInitSize = 6;
-#else
-        static const int ctiArgumentInitSize = 2;
-#endif
-#elif USE(JIT_STUB_ARGUMENT_STACK)
-        static const int ctiArgumentInitSize = 4;
-#else // JIT_STUB_ARGUMENT_VA_LIST
-        static const int ctiArgumentInitSize = 0;
-#endif
-
-#if PLATFORM(X86_64)
-        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
-        static const int patchOffsetPutByIdStructure = 10;
-        static const int patchOffsetPutByIdPropertyMapOffset = 31;
-        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
-        static const int patchOffsetGetByIdStructure = 10;
-        static const int patchOffsetGetByIdBranchToSlowCase = 20;
-        static const int patchOffsetGetByIdPropertyMapOffset = 31;
-        static const int patchOffsetGetByIdPutResult = 31;
-#if ENABLE(OPCODE_SAMPLING)
-        static const int patchOffsetGetByIdSlowCaseCall = 53 + ctiArgumentInitSize;
-#else
-        static const int patchOffsetGetByIdSlowCaseCall = 30 + ctiArgumentInitSize;
-#endif
-        static const int patchOffsetOpCallCompareToJump = 9;
-#else
-        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
-        static const int patchOffsetPutByIdStructure = 7;
-        static const int patchOffsetPutByIdPropertyMapOffset = 22;
-        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
-        static const int patchOffsetGetByIdStructure = 7;
-        static const int patchOffsetGetByIdBranchToSlowCase = 13;
-        static const int patchOffsetGetByIdPropertyMapOffset = 22;
-        static const int patchOffsetGetByIdPutResult = 22;
-#if ENABLE(OPCODE_SAMPLING)
-        static const int patchOffsetGetByIdSlowCaseCall = 31 + ctiArgumentInitSize;
-#else
-        static const int patchOffsetGetByIdSlowCaseCall = 21 + ctiArgumentInitSize;
-#endif
-        static const int patchOffsetOpCallCompareToJump = 6;
-#endif
-
     public:
         static void compile(JSGlobalData* globalData, CodeBlock* codeBlock)
         {
@@ -284,19 +258,12 @@ namespace JSC {
             jit.privateCompile();
         }
 
-        static void compileGetByIdSelf(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
-        {
-            JIT jit(globalData, codeBlock);
-            jit.privateCompileGetByIdSelf(stubInfo, structure, cachedOffset, returnAddress);
-        }
-
-        static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, void* returnAddress)
+        static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress)
         {
             JIT jit(globalData, codeBlock);
             jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, cachedOffset, returnAddress, callFrame);
         }
 
-#if USE(CTI_REPATCH_PIC)
         static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset)
         {
             JIT jit(globalData, codeBlock);
@@ -312,142 +279,177 @@ namespace JSC {
             JIT jit(globalData, codeBlock);
             jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, cachedOffset, callFrame);
         }
-#endif
 
-        static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, void* returnAddress)
+        static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress)
         {
             JIT jit(globalData, codeBlock);
             jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, cachedOffset, returnAddress, callFrame);
         }
-
-        static void compilePutByIdReplace(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
-        {
-            JIT jit(globalData, codeBlock);
-            jit.privateCompilePutByIdReplace(stubInfo, structure, cachedOffset, returnAddress);
-        }
         
-        static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, void* returnAddress)
+        static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress)
         {
             JIT jit(globalData, codeBlock);
             jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress);
         }
 
-        static void compileCTIMachineTrampolines(JSGlobalData* globalData)
+        static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
         {
             JIT jit(globalData);
-            jit.privateCompileCTIMachineTrampolines();
+            jit.privateCompileCTIMachineTrampolines(executablePool, globalData, ctiStringLengthTrampoline, ctiVirtualCallPreLink, ctiVirtualCallLink, ctiVirtualCall, ctiNativeCallThunk);
         }
 
-        static void patchGetByIdSelf(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
-        static void patchPutByIdReplace(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
+        static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
+        static void patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
+        static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*);
 
-        static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, void* returnAddress)
+        static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
         {
             JIT jit(globalData, codeBlock);
             return jit.privateCompilePatchGetArrayLength(returnAddress);
         }
 
-        static void linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount);
+        static void linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, JITCode&, CallLinkInfo*, int callerArgCount, JSGlobalData*);
         static void unlinkCall(CallLinkInfo*);
 
-        inline static JSValuePtr execute(void* code, RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData, JSValuePtr* exception)
-        {
-            return JSValuePtr::decode(ctiTrampoline(
-#if PLATFORM(X86_64)
-                0, 0, 0, 0, 0, 0,
-#endif
-                code, registerFile, callFrame, exception, Profiler::enabledProfilerReference(), globalData));
-        }
-
     private:
+        struct JSRInfo {
+            DataLabelPtr storeLocation;
+            Label target;
+
+            JSRInfo(DataLabelPtr storeLocation, Label targetLocation)
+                : storeLocation(storeLocation)
+                , target(targetLocation)
+            {
+            }
+        };
+
         JIT(JSGlobalData*, CodeBlock* = 0);
 
         void privateCompileMainPass();
         void privateCompileLinkPass();
         void privateCompileSlowCases();
         void privateCompile();
-        void privateCompileGetByIdSelf(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
-        void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, size_t cachedOffset, void* returnAddress, CallFrame* callFrame);
-#if USE(CTI_REPATCH_PIC)
+        void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
         void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, size_t cachedOffset);
         void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame);
         void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame);
-#endif
-        void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, size_t cachedOffset, void* returnAddress, CallFrame* callFrame);
-        void privateCompilePutByIdReplace(StructureStubInfo*, Structure*, size_t cachedOffset, void* returnAddress);
-        void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, void* returnAddress);
+        void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
+        void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress);
 
-        void privateCompileCTIMachineTrampolines();
-        void privateCompilePatchGetArrayLength(void* returnAddress);
+        void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk);
+        void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
 
         void addSlowCase(Jump);
+        void addSlowCase(JumpList);
         void addJump(Jump, int);
         void emitJumpSlowToHot(Jump, int);
 
-        void compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned propertyAccessInstructionIndex);
-        void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex);
-        void compilePutByIdHotPath(int baseVReg, Identifier* ident, int valueVReg, unsigned propertyAccessInstructionIndex);
-        void compilePutByIdSlowCase(int baseVReg, Identifier* ident, int valueVReg, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex);
         void compileOpCall(OpcodeID, Instruction* instruction, unsigned callLinkInfoIndex);
+        void compileOpCallVarargs(Instruction* instruction);
         void compileOpCallInitializeCallFrame();
         void compileOpCallSetupArgs(Instruction*);
-        void compileOpCallEvalSetupArgs(Instruction*);
+        void compileOpCallVarargsSetupArgs(Instruction*);
         void compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex, OpcodeID opcodeID);
+        void compileOpCallVarargsSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter);
         void compileOpConstructSetupArgs(Instruction*);
+
         enum CompileOpStrictEqType { OpStrictEq, OpNStrictEq };
         void compileOpStrictEq(Instruction* instruction, CompileOpStrictEqType type);
-        void putDoubleResultToJSNumberCellOrJSImmediate(X86Assembler::XMMRegisterID xmmSource, RegisterID jsNumberCell, unsigned dst, X86Assembler::JmpSrc* wroteJSNumberCell, X86Assembler::XMMRegisterID tempXmm, RegisterID tempReg1, RegisterID tempReg2);
-
-        void compileFastArith_op_add(Instruction*);
-        void compileFastArith_op_sub(Instruction*);
-        void compileFastArith_op_mul(Instruction*);
-        void compileFastArith_op_mod(unsigned result, unsigned op1, unsigned op2);
-        void compileFastArith_op_bitand(unsigned result, unsigned op1, unsigned op2);
-        void compileFastArith_op_lshift(unsigned result, unsigned op1, unsigned op2);
-        void compileFastArith_op_rshift(unsigned result, unsigned op1, unsigned op2);
-        void compileFastArith_op_pre_inc(unsigned srcDst);
-        void compileFastArith_op_pre_dec(unsigned srcDst);
-        void compileFastArith_op_post_inc(unsigned result, unsigned srcDst);
-        void compileFastArith_op_post_dec(unsigned result, unsigned srcDst);
-        void compileFastArithSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_mod(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_bitand(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_lshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_rshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_pre_inc(unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_pre_dec(unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_post_inc(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
-        void compileFastArithSlow_op_post_dec(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator&);
-#if ENABLE(JIT_OPTIMIZE_ARITHMETIC)
-        void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);
-        void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);
-#endif
 
-        void emitGetVirtualRegister(int src, RegisterID dst);
-        void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2);
-        void emitPutVirtualRegister(unsigned dst, RegisterID from = X86::eax);
+#if USE(JSVALUE32_64)
+        Address tagFor(unsigned index, RegisterID base = callFrameRegister);
+        Address payloadFor(unsigned index, RegisterID base = callFrameRegister);
+        Address addressFor(unsigned index, RegisterID base = callFrameRegister);
+
+        bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant);
+        bool isOperandConstantImmediateDouble(unsigned src);
+
+        void emitLoadTag(unsigned index, RegisterID tag);
+        void emitLoadPayload(unsigned index, RegisterID payload);
+
+        void emitLoad(const JSValue& v, RegisterID tag, RegisterID payload);
+        void emitLoad(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister);
+        void emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1, unsigned index2, RegisterID tag2, RegisterID payload2);
+        void emitLoadDouble(unsigned index, FPRegisterID value);
+        void emitLoadInt32ToDouble(unsigned index, FPRegisterID value);
+
+        void emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base = callFrameRegister);
+        void emitStore(unsigned index, const JSValue constant, RegisterID base = callFrameRegister);
+        void emitStoreInt32(unsigned index, RegisterID payload, bool indexIsInt32 = false);
+        void emitStoreInt32(unsigned index, Imm32 payload, bool indexIsInt32 = false);
+        void emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell = false);
+        void emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool = false);
+        void emitStoreDouble(unsigned index, FPRegisterID value);
+
+        bool isLabeled(unsigned bytecodeIndex);
+        void map(unsigned bytecodeIndex, unsigned virtualRegisterIndex, RegisterID tag, RegisterID payload);
+        void unmap(RegisterID);
+        void unmap();
+        bool isMapped(unsigned virtualRegisterIndex);
+        bool getMappedPayload(unsigned virtualRegisterIndex, RegisterID& payload);
+        bool getMappedTag(unsigned virtualRegisterIndex, RegisterID& tag);
+
+        void emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex);
+        void emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex, RegisterID tag);
+        void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, unsigned virtualRegisterIndex);
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+        void compileGetByIdHotPath();
+        void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
+#endif
+        void compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset);
+        void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset);
+        void compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset);
 
-        void emitPutJITStubArg(RegisterID src, unsigned argumentNumber);
-        void emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch);
-        void emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber);
-        void emitPutJITStubArgConstant(void* value, unsigned argumentNumber);
-        void emitGetJITStubArg(unsigned argumentNumber, RegisterID dst);
+        // Arithmetic opcode helpers
+        void emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType);
+        void emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType);
+        void emitBinaryDoubleOp(OpcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters = true, bool op2IsInRegisters = true);
 
-        void emitInitRegister(unsigned dst);
+#if PLATFORM(X86)
+        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
+        static const int patchOffsetPutByIdStructure = 7;
+        static const int patchOffsetPutByIdExternalLoad = 13;
+        static const int patchLengthPutByIdExternalLoad = 3;
+        static const int patchOffsetPutByIdPropertyMapOffset1 = 22;
+        static const int patchOffsetPutByIdPropertyMapOffset2 = 28;
+        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
+        static const int patchOffsetGetByIdStructure = 7;
+        static const int patchOffsetGetByIdBranchToSlowCase = 13;
+        static const int patchOffsetGetByIdExternalLoad = 13;
+        static const int patchLengthGetByIdExternalLoad = 3;
+        static const int patchOffsetGetByIdPropertyMapOffset1 = 22;
+        static const int patchOffsetGetByIdPropertyMapOffset2 = 28;
+        static const int patchOffsetGetByIdPutResult = 28;
+#if ENABLE(OPCODE_SAMPLING) && USE(JIT_STUB_ARGUMENT_VA_LIST)
+        static const int patchOffsetGetByIdSlowCaseCall = 35;
+#elif ENABLE(OPCODE_SAMPLING)
+        static const int patchOffsetGetByIdSlowCaseCall = 37;
+#elif USE(JIT_STUB_ARGUMENT_VA_LIST)
+        static const int patchOffsetGetByIdSlowCaseCall = 25;
+#else
+        static const int patchOffsetGetByIdSlowCaseCall = 27;
+#endif
+        static const int patchOffsetOpCallCompareToJump = 6;
 
-        void emitPutCTIParam(void* value, unsigned name);
-        void emitPutCTIParam(RegisterID from, unsigned name);
-        void emitGetCTIParam(unsigned name, RegisterID to);
+        static const int patchOffsetMethodCheckProtoObj = 11;
+        static const int patchOffsetMethodCheckProtoStruct = 18;
+        static const int patchOffsetMethodCheckPutFunction = 29;
+#else
+#error "JSVALUE32_64 not supported on this platform."
+#endif
 
-        void emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry);
-        void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry);
-        void emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, RegisterID to);
+#else // USE(JSVALUE32_64)
+        void emitGetVirtualRegister(int src, RegisterID dst);
+        void emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2);
+        void emitPutVirtualRegister(unsigned dst, RegisterID from = regT0);
 
-        JSValuePtr getConstantOperand(unsigned src);
         int32_t getConstantOperandImmediateInt(unsigned src);
-        bool isOperandConstantImmediateInt(unsigned src);
+
+        void emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst);
+        void emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index);
+        
+        void killLastResultRegister();
 
         Jump emitJumpIfJSCell(RegisterID);
         Jump emitJumpIfBothJSCells(RegisterID, RegisterID, RegisterID);
@@ -455,31 +457,27 @@ namespace JSC {
         Jump emitJumpIfNotJSCell(RegisterID);
         void emitJumpSlowCaseIfNotJSCell(RegisterID);
         void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg);
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
         JIT::Jump emitJumpIfImmediateNumber(RegisterID);
         JIT::Jump emitJumpIfNotImmediateNumber(RegisterID);
-#endif
-
-        Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter)
+#else
+        JIT::Jump emitJumpIfImmediateNumber(RegisterID reg)
         {
-            return iter++->from;
+            return emitJumpIfImmediateInteger(reg);
         }
-        void linkSlowCase(Vector<SlowCaseEntry>::iterator& iter)
+        
+        JIT::Jump emitJumpIfNotImmediateNumber(RegisterID reg)
         {
-            iter->from.link(this);
-            ++iter;
+            return emitJumpIfNotImmediateInteger(reg);
         }
-        void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, int vReg);
-
+#endif
         JIT::Jump emitJumpIfImmediateInteger(RegisterID);
         JIT::Jump emitJumpIfNotImmediateInteger(RegisterID);
         JIT::Jump emitJumpIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
         void emitJumpSlowCaseIfNotImmediateInteger(RegisterID);
         void emitJumpSlowCaseIfNotImmediateIntegers(RegisterID, RegisterID, RegisterID);
 
-        Jump checkStructure(RegisterID reg, Structure* structure);
-
-#if !USE(ALTERNATE_JSIMMEDIATE)
+#if !USE(JSVALUE64)
         void emitFastArithDeTagImmediate(RegisterID);
         Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID);
 #endif
@@ -488,57 +486,298 @@ namespace JSC {
         void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest);
 
         void emitTagAsBoolImmediate(RegisterID reg);
+        void compileBinaryArithOp(OpcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);
+        void compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned dst, unsigned src1, unsigned src2, OperandTypes opi);
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+        void compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned propertyAccessInstructionIndex);
+        void compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck = false);
+#endif
+        void compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset);
+        void compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset);
+        void compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset);
+
+#if PLATFORM(X86_64)
+        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
+        static const int patchOffsetPutByIdStructure = 10;
+        static const int patchOffsetPutByIdExternalLoad = 20;
+        static const int patchLengthPutByIdExternalLoad = 4;
+        static const int patchOffsetPutByIdPropertyMapOffset = 31;
+        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
+        static const int patchOffsetGetByIdStructure = 10;
+        static const int patchOffsetGetByIdBranchToSlowCase = 20;
+        static const int patchOffsetGetByIdExternalLoad = 20;
+        static const int patchLengthGetByIdExternalLoad = 4;
+        static const int patchOffsetGetByIdPropertyMapOffset = 31;
+        static const int patchOffsetGetByIdPutResult = 31;
+#if ENABLE(OPCODE_SAMPLING)
+        static const int patchOffsetGetByIdSlowCaseCall = 66;
+#else
+        static const int patchOffsetGetByIdSlowCaseCall = 44;
+#endif
+        static const int patchOffsetOpCallCompareToJump = 9;
+
+        static const int patchOffsetMethodCheckProtoObj = 20;
+        static const int patchOffsetMethodCheckProtoStruct = 30;
+        static const int patchOffsetMethodCheckPutFunction = 50;
+#elif PLATFORM(X86)
+        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
+        static const int patchOffsetPutByIdStructure = 7;
+        static const int patchOffsetPutByIdExternalLoad = 13;
+        static const int patchLengthPutByIdExternalLoad = 3;
+        static const int patchOffsetPutByIdPropertyMapOffset = 22;
+        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
+        static const int patchOffsetGetByIdStructure = 7;
+        static const int patchOffsetGetByIdBranchToSlowCase = 13;
+        static const int patchOffsetGetByIdExternalLoad = 13;
+        static const int patchLengthGetByIdExternalLoad = 3;
+        static const int patchOffsetGetByIdPropertyMapOffset = 22;
+        static const int patchOffsetGetByIdPutResult = 22;
+#if ENABLE(OPCODE_SAMPLING) && USE(JIT_STUB_ARGUMENT_VA_LIST)
+        static const int patchOffsetGetByIdSlowCaseCall = 31;
+#elif ENABLE(OPCODE_SAMPLING)
+        static const int patchOffsetGetByIdSlowCaseCall = 33;
+#elif USE(JIT_STUB_ARGUMENT_VA_LIST)
+        static const int patchOffsetGetByIdSlowCaseCall = 21;
+#else
+        static const int patchOffsetGetByIdSlowCaseCall = 23;
+#endif
+        static const int patchOffsetOpCallCompareToJump = 6;
+
+        static const int patchOffsetMethodCheckProtoObj = 11;
+        static const int patchOffsetMethodCheckProtoStruct = 18;
+        static const int patchOffsetMethodCheckPutFunction = 29;
+#elif PLATFORM_ARM_ARCH(7)
+        // These architecture specific value are used to enable patching - see comment on op_put_by_id.
+        static const int patchOffsetPutByIdStructure = 10;
+        static const int patchOffsetPutByIdExternalLoad = 20;
+        static const int patchLengthPutByIdExternalLoad = 12;
+        static const int patchOffsetPutByIdPropertyMapOffset = 40;
+        // These architecture specific value are used to enable patching - see comment on op_get_by_id.
+        static const int patchOffsetGetByIdStructure = 10;
+        static const int patchOffsetGetByIdBranchToSlowCase = 20;
+        static const int patchOffsetGetByIdExternalLoad = 20;
+        static const int patchLengthGetByIdExternalLoad = 12;
+        static const int patchOffsetGetByIdPropertyMapOffset = 40;
+        static const int patchOffsetGetByIdPutResult = 44;
+#if ENABLE(OPCODE_SAMPLING)
+        static const int patchOffsetGetByIdSlowCaseCall = 0; // FIMXE
+#else
+        static const int patchOffsetGetByIdSlowCaseCall = 28;
+#endif
+        static const int patchOffsetOpCallCompareToJump = 10;
+
+        static const int patchOffsetMethodCheckProtoObj = 18;
+        static const int patchOffsetMethodCheckProtoStruct = 28;
+        static const int patchOffsetMethodCheckPutFunction = 46;
+#endif
+#endif // USE(JSVALUE32_64)
+
+        void emit_op_add(Instruction*);
+        void emit_op_bitand(Instruction*);
+        void emit_op_bitnot(Instruction*);
+        void emit_op_bitor(Instruction*);
+        void emit_op_bitxor(Instruction*);
+        void emit_op_call(Instruction*);
+        void emit_op_call_eval(Instruction*);
+        void emit_op_call_varargs(Instruction*);
+        void emit_op_catch(Instruction*);
+        void emit_op_construct(Instruction*);
+        void emit_op_construct_verify(Instruction*);
+        void emit_op_convert_this(Instruction*);
+        void emit_op_create_arguments(Instruction*);
+        void emit_op_debug(Instruction*);
+        void emit_op_del_by_id(Instruction*);
+        void emit_op_div(Instruction*);
+        void emit_op_end(Instruction*);
+        void emit_op_enter(Instruction*);
+        void emit_op_enter_with_activation(Instruction*);
+        void emit_op_eq(Instruction*);
+        void emit_op_eq_null(Instruction*);
+        void emit_op_get_by_id(Instruction*);
+        void emit_op_get_by_val(Instruction*);
+        void emit_op_get_global_var(Instruction*);
+        void emit_op_get_scoped_var(Instruction*);
+        void emit_op_init_arguments(Instruction*);
+        void emit_op_instanceof(Instruction*);
+        void emit_op_jeq_null(Instruction*);
+        void emit_op_jfalse(Instruction*);
+        void emit_op_jmp(Instruction*);
+        void emit_op_jmp_scopes(Instruction*);
+        void emit_op_jneq_null(Instruction*);
+        void emit_op_jneq_ptr(Instruction*);
+        void emit_op_jnless(Instruction*);
+        void emit_op_jnlesseq(Instruction*);
+        void emit_op_jsr(Instruction*);
+        void emit_op_jtrue(Instruction*);
+        void emit_op_load_varargs(Instruction*);
+        void emit_op_loop(Instruction*);
+        void emit_op_loop_if_less(Instruction*);
+        void emit_op_loop_if_lesseq(Instruction*);
+        void emit_op_loop_if_true(Instruction*);
+        void emit_op_lshift(Instruction*);
+        void emit_op_method_check(Instruction*);
+        void emit_op_mod(Instruction*);
+        void emit_op_mov(Instruction*);
+        void emit_op_mul(Instruction*);
+        void emit_op_negate(Instruction*);
+        void emit_op_neq(Instruction*);
+        void emit_op_neq_null(Instruction*);
+        void emit_op_new_array(Instruction*);
+        void emit_op_new_error(Instruction*);
+        void emit_op_new_func(Instruction*);
+        void emit_op_new_func_exp(Instruction*);
+        void emit_op_new_object(Instruction*);
+        void emit_op_new_regexp(Instruction*);
+        void emit_op_next_pname(Instruction*);
+        void emit_op_not(Instruction*);
+        void emit_op_nstricteq(Instruction*);
+        void emit_op_pop_scope(Instruction*);
+        void emit_op_post_dec(Instruction*);
+        void emit_op_post_inc(Instruction*);
+        void emit_op_pre_dec(Instruction*);
+        void emit_op_pre_inc(Instruction*);
+        void emit_op_profile_did_call(Instruction*);
+        void emit_op_profile_will_call(Instruction*);
+        void emit_op_push_new_scope(Instruction*);
+        void emit_op_push_scope(Instruction*);
+        void emit_op_put_by_id(Instruction*);
+        void emit_op_put_by_index(Instruction*);
+        void emit_op_put_by_val(Instruction*);
+        void emit_op_put_getter(Instruction*);
+        void emit_op_put_global_var(Instruction*);
+        void emit_op_put_scoped_var(Instruction*);
+        void emit_op_put_setter(Instruction*);
+        void emit_op_resolve(Instruction*);
+        void emit_op_resolve_base(Instruction*);
+        void emit_op_resolve_global(Instruction*);
+        void emit_op_resolve_skip(Instruction*);
+        void emit_op_resolve_with_base(Instruction*);
+        void emit_op_ret(Instruction*);
+        void emit_op_rshift(Instruction*);
+        void emit_op_sret(Instruction*);
+        void emit_op_strcat(Instruction*);
+        void emit_op_stricteq(Instruction*);
+        void emit_op_sub(Instruction*);
+        void emit_op_switch_char(Instruction*);
+        void emit_op_switch_imm(Instruction*);
+        void emit_op_switch_string(Instruction*);
+        void emit_op_tear_off_activation(Instruction*);
+        void emit_op_tear_off_arguments(Instruction*);
+        void emit_op_throw(Instruction*);
+        void emit_op_to_jsnumber(Instruction*);
+        void emit_op_to_primitive(Instruction*);
+        void emit_op_unexpected_load(Instruction*);
+
+        void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_bitnot(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_bitor(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_bitxor(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_call(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_call_eval(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_call_varargs(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_construct(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_construct_verify(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_convert_this(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_div(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_eq(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_instanceof(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_loop_if_lesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_loop_if_true(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_lshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_negate(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_neq(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_not(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_nstricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_post_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_post_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_pre_dec(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_pre_inc(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_resolve_global(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_rshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_stricteq(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_to_jsnumber(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_to_primitive(Instruction*, Vector<SlowCaseEntry>::iterator&);
+
+        /* These functions are deprecated: Please use JITStubCall instead. */
+        void emitPutJITStubArg(RegisterID src, unsigned argumentNumber);
+#if USE(JSVALUE32_64)
+        void emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch1, RegisterID scratch2);
+#else
+        void emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch);
+#endif
+        void emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber);
+        void emitPutJITStubArgConstant(void* value, unsigned argumentNumber);
+        void emitGetJITStubArg(unsigned argumentNumber, RegisterID dst);
+
+        void emitInitRegister(unsigned dst);
+
+        void emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry);
+        void emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry);
+        void emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister);
+        void emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from = callFrameRegister);
+
+        JSValue getConstantOperand(unsigned src);
+        bool isOperandConstantImmediateInt(unsigned src);
+
+        Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter)
+        {
+            return iter++->from;
+        }
+        void linkSlowCase(Vector<SlowCaseEntry>::iterator& iter)
+        {
+            iter->from.link(this);
+            ++iter;
+        }
+        void linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator&, int vReg);
+
+        Jump checkStructure(RegisterID reg, Structure* structure);
 
         void restoreArgumentReference();
         void restoreArgumentReferenceForTrampoline();
 
-        Jump emitNakedCall(RegisterID);
-        Jump emitNakedCall(void* function);
-        Jump emitCTICall_internal(void*);
-        Jump emitCTICall(CTIHelper_j helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
-        Jump emitCTICall(CTIHelper_o helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
-        Jump emitCTICall(CTIHelper_p helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
-        Jump emitCTICall(CTIHelper_v helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
-        Jump emitCTICall(CTIHelper_s helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
-        Jump emitCTICall(CTIHelper_b helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
-        Jump emitCTICall(CTIHelper_2 helper) { return emitCTICall_internal(reinterpret_cast<void*>(helper)); }
+        Call emitNakedCall(CodePtr function = CodePtr());
 
-        void emitGetVariableObjectRegister(RegisterID variableObject, int index, RegisterID dst);
-        void emitPutVariableObjectRegister(RegisterID src, RegisterID variableObject, int index);
-        
-        void emitSlowScriptCheck();
+        void preserveReturnAddressAfterCall(RegisterID);
+        void restoreReturnAddressBeforeReturn(RegisterID);
+        void restoreReturnAddressBeforeReturn(Address);
+
+        void emitTimeoutCheck();
 #ifndef NDEBUG
         void printBytecodeOperandTypes(unsigned src1, unsigned src2);
 #endif
 
-        void killLastResultRegister();
-
-#if ENABLE(CODEBLOCK_SAMPLING)
-        void sampleCodeBlock(CodeBlock* codeBlock)
-        {
-#if PLATFORM(X86_64)
-            move(ImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86::ecx);
-            storePtr(ImmPtr(codeBlock), X86::ecx);
-#else
-            storePtr(ImmPtr(codeBlock), m_interpreter->sampler()->codeBlockSlot());
+#if ENABLE(SAMPLING_FLAGS)
+        void setSamplingFlag(int32_t);
+        void clearSamplingFlag(int32_t);
 #endif
-        }
-#else
-        void sampleCodeBlock(CodeBlock*) {}
+
+#if ENABLE(SAMPLING_COUNTERS)
+        void emitCount(AbstractSamplingCounter&, uint32_t = 1);
 #endif
 
 #if ENABLE(OPCODE_SAMPLING)
-        void sampleInstruction(Instruction* instruction, bool inHostFunction=false)
-        {
-#if PLATFORM(X86_64)
-            move(ImmPtr(m_interpreter->sampler()->sampleSlot()), X86::ecx);
-            storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), X86::ecx);
-#else
-            storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), m_interpreter->sampler()->sampleSlot());
+        void sampleInstruction(Instruction*, bool = false);
 #endif
-        }
+
+#if ENABLE(CODEBLOCK_SAMPLING)
+        void sampleCodeBlock(CodeBlock*);
 #else
-        void sampleInstruction(Instruction*, bool) {}
+        void sampleCodeBlock(CodeBlock*) {}
 #endif
 
         Interpreter* m_interpreter;
@@ -549,28 +788,30 @@ namespace JSC {
         Vector<Label> m_labels;
         Vector<PropertyStubCompilationInfo> m_propertyAccessCompilationInfo;
         Vector<StructureStubCompilationInfo> m_callStructureStubCompilationInfo;
+        Vector<MethodCallCompilationInfo> m_methodCallCompilationInfo;
         Vector<JumpTable> m_jmpTable;
 
-        struct JSRInfo {
-            DataLabelPtr storeLocation;
-            Label target;
-
-            JSRInfo(DataLabelPtr storeLocation, Label targetLocation)
-                : storeLocation(storeLocation)
-                , target(targetLocation)
-            {
-            }
-        };
-
         unsigned m_bytecodeIndex;
         Vector<JSRInfo> m_jsrSites;
         Vector<SlowCaseEntry> m_slowCases;
         Vector<SwitchRecord> m_switches;
 
+        unsigned m_propertyAccessInstructionIndex;
+        unsigned m_globalResolveInfoIndex;
+        unsigned m_callLinkInfoIndex;
+
+#if USE(JSVALUE32_64)
+        unsigned m_jumpTargetIndex;
+        unsigned m_mappedBytecodeIndex;
+        unsigned m_mappedVirtualRegisterIndex;
+        RegisterID m_mappedTag;
+        RegisterID m_mappedPayload;
+#else
         int m_lastResultBytecodeRegister;
         unsigned m_jumpTargetsPosition;
-    };
-}
+#endif
+    } JIT_CLASS_ALIGNMENT;
+} // namespace JSC
 
 #endif // ENABLE(JIT)
 
index 0a3e9abd242ed86bc0e9a52eca1abc03fffcd42c..3bd7146109242f59e98f9fca583f52db7117a520 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "CodeBlock.h"
 #include "JITInlineMethods.h"
+#include "JITStubCall.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "Interpreter.h"
 #include <stdio.h>
 #endif
 
-#define __ m_assembler.
+using namespace std;
+
+namespace JSC {
+
+#if USE(JSVALUE32_64)
+
+void JIT::emit_op_negate(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src = currentInstruction[2].u.operand;
+
+    emitLoad(src, regT1, regT0);
+
+    Jump srcNotInt = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+    addSlowCase(branch32(Equal, regT0, Imm32(0)));
+
+    neg32(regT0);
+    emitStoreInt32(dst, regT0, (dst == src));
+
+    Jump end = jump();
+
+    srcNotInt.link(this);
+    addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+
+    xor32(Imm32(1 << 31), regT1);
+    store32(regT1, tagFor(dst));
+    if (dst != src)
+        store32(regT0, payloadFor(dst));
+
+    end.link(this);
+}
+
+void JIT::emitSlow_op_negate(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+
+    linkSlowCase(iter); // 0 check
+    linkSlowCase(iter); // double check
+
+    JITStubCall stubCall(this, cti_op_negate);
+    stubCall.addArgument(regT1, regT0);
+    stubCall.call(dst);
+}
+
+void JIT::emit_op_jnless(Instruction* currentInstruction)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    JumpList notInt32Op1;
+    JumpList notInt32Op2;
+
+    // Int32 less.
+    if (isOperandConstantImmediateInt(op1)) {
+        emitLoad(op2, regT3, regT2);
+        notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target + 3);
+    } else if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3);
+    } else {
+        emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+        notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(GreaterThanOrEqual, regT0, regT2), target + 3);
+    }
+
+    if (!supportsFloatingPoint()) {
+        addSlowCase(notInt32Op1);
+        addSlowCase(notInt32Op2);
+        return;
+    }
+    Jump end = jump();
+
+    // Double less.
+    emitBinaryDoubleOp(op_jnless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
+    end.link(this);
+}
+
+void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    if (!supportsFloatingPoint()) {
+        if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+            linkSlowCase(iter); // int32 check
+        linkSlowCase(iter); // int32 check
+    } else {
+        if (!isOperandConstantImmediateInt(op1)) {
+            linkSlowCase(iter); // double check
+            linkSlowCase(iter); // int32 check
+        }
+        if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2))
+            linkSlowCase(iter); // double check
+    }
+
+    JITStubCall stubCall(this, cti_op_jless);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+}
+
+void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    JumpList notInt32Op1;
+    JumpList notInt32Op2;
+
+    // Int32 less.
+    if (isOperandConstantImmediateInt(op1)) {
+        emitLoad(op2, regT3, regT2);
+        notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(LessThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target + 3);
+    } else if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3);
+    } else {
+        emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+        notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(GreaterThan, regT0, regT2), target + 3);
+    }
+
+    if (!supportsFloatingPoint()) {
+        addSlowCase(notInt32Op1);
+        addSlowCase(notInt32Op2);
+        return;
+    }
+    Jump end = jump();
+
+    // Double less.
+    emitBinaryDoubleOp(op_jnlesseq, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
+    end.link(this);
+}
+
+void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    if (!supportsFloatingPoint()) {
+        if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+            linkSlowCase(iter); // int32 check
+        linkSlowCase(iter); // int32 check
+    } else {
+        if (!isOperandConstantImmediateInt(op1)) {
+            linkSlowCase(iter); // double check
+            linkSlowCase(iter); // int32 check
+        }
+        if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2))
+            linkSlowCase(iter); // double check
+    }
+
+    JITStubCall stubCall(this, cti_op_jlesseq);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+}
+
+// LeftShift (<<)
+
+void JIT::emit_op_lshift(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        lshift32(Imm32(getConstantOperand(op2).asInt32()), regT0);
+        emitStoreInt32(dst, regT0, dst == op1);
+        return;
+    }
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    if (!isOperandConstantImmediateInt(op1))
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    lshift32(regT2, regT0);
+    emitStoreInt32(dst, regT0, dst == op1 || dst == op2);
+}
+
+void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+        linkSlowCase(iter); // int32 check
+    linkSlowCase(iter); // int32 check
+
+    JITStubCall stubCall(this, cti_op_lshift);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+// RightShift (>>)
+
+void JIT::emit_op_rshift(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        rshift32(Imm32(getConstantOperand(op2).asInt32()), regT0);
+        emitStoreInt32(dst, regT0, dst == op1);
+        return;
+    }
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    if (!isOperandConstantImmediateInt(op1))
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    rshift32(regT2, regT0);
+    emitStoreInt32(dst, regT0, dst == op1 || dst == op2);
+}
+
+void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+        linkSlowCase(iter); // int32 check
+    linkSlowCase(iter); // int32 check
+
+    JITStubCall stubCall(this, cti_op_rshift);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+// BitAnd (&)
+
+void JIT::emit_op_bitand(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    unsigned op;
+    int32_t constant;
+    if (getOperandConstantImmediateInt(op1, op2, op, constant)) {
+        emitLoad(op, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        and32(Imm32(constant), regT0);
+        emitStoreInt32(dst, regT0, (op == dst));
+        return;
+    }
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    and32(regT2, regT0);
+    emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+}
+
+void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+        linkSlowCase(iter); // int32 check
+    linkSlowCase(iter); // int32 check
+
+    JITStubCall stubCall(this, cti_op_bitand);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+// BitOr (|)
+
+void JIT::emit_op_bitor(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    unsigned op;
+    int32_t constant;
+    if (getOperandConstantImmediateInt(op1, op2, op, constant)) {
+        emitLoad(op, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        or32(Imm32(constant), regT0);
+        emitStoreInt32(dst, regT0, (op == dst));
+        return;
+    }
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    or32(regT2, regT0);
+    emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+}
+
+void JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+        linkSlowCase(iter); // int32 check
+    linkSlowCase(iter); // int32 check
+
+    JITStubCall stubCall(this, cti_op_bitor);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+// BitXor (^)
+
+void JIT::emit_op_bitxor(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    unsigned op;
+    int32_t constant;
+    if (getOperandConstantImmediateInt(op1, op2, op, constant)) {
+        emitLoad(op, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        xor32(Imm32(constant), regT0);
+        emitStoreInt32(dst, regT0, (op == dst));
+        return;
+    }
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    xor32(regT2, regT0);
+    emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+}
+
+void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+        linkSlowCase(iter); // int32 check
+    linkSlowCase(iter); // int32 check
+
+    JITStubCall stubCall(this, cti_op_bitxor);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+// BitNot (~)
+
+void JIT::emit_op_bitnot(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src = currentInstruction[2].u.operand;
+
+    emitLoad(src, regT1, regT0);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+
+    not32(regT0);
+    emitStoreInt32(dst, regT0, (dst == src));
+}
+
+void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+
+    linkSlowCase(iter); // int32 check
+
+    JITStubCall stubCall(this, cti_op_bitnot);
+    stubCall.addArgument(regT1, regT0);
+    stubCall.call(dst);
+}
+
+// PostInc (i++)
+
+void JIT::emit_op_post_inc(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned srcDst = currentInstruction[2].u.operand;
+    
+    emitLoad(srcDst, regT1, regT0);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+
+    if (dst == srcDst) // x = x++ is a noop for ints.
+        return;
+
+    emitStoreInt32(dst, regT0);
+
+    addSlowCase(branchAdd32(Overflow, Imm32(1), regT0));
+    emitStoreInt32(srcDst, regT0, true);
+}
+
+void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned srcDst = currentInstruction[2].u.operand;
+
+    linkSlowCase(iter); // int32 check
+    if (dst != srcDst)
+        linkSlowCase(iter); // overflow check
+
+    JITStubCall stubCall(this, cti_op_post_inc);
+    stubCall.addArgument(srcDst);
+    stubCall.addArgument(Imm32(srcDst));
+    stubCall.call(dst);
+}
+
+// PostDec (i--)
+
+void JIT::emit_op_post_dec(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned srcDst = currentInstruction[2].u.operand;
+
+    emitLoad(srcDst, regT1, regT0);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+
+    if (dst == srcDst) // x = x-- is a noop for ints.
+        return;
+
+    emitStoreInt32(dst, regT0);
+
+    addSlowCase(branchSub32(Overflow, Imm32(1), regT0));
+    emitStoreInt32(srcDst, regT0, true);
+}
+
+void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned srcDst = currentInstruction[2].u.operand;
+
+    linkSlowCase(iter); // int32 check
+    if (dst != srcDst)
+        linkSlowCase(iter); // overflow check
+
+    JITStubCall stubCall(this, cti_op_post_dec);
+    stubCall.addArgument(srcDst);
+    stubCall.addArgument(Imm32(srcDst));
+    stubCall.call(dst);
+}
+
+// PreInc (++i)
+
+void JIT::emit_op_pre_inc(Instruction* currentInstruction)
+{
+    unsigned srcDst = currentInstruction[1].u.operand;
+
+    emitLoad(srcDst, regT1, regT0);
+
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branchAdd32(Overflow, Imm32(1), regT0));
+    emitStoreInt32(srcDst, regT0, true);
+}
+
+void JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned srcDst = currentInstruction[1].u.operand;
+
+    linkSlowCase(iter); // int32 check
+    linkSlowCase(iter); // overflow check
+
+    JITStubCall stubCall(this, cti_op_pre_inc);
+    stubCall.addArgument(srcDst);
+    stubCall.call(srcDst);
+}
+
+// PreDec (--i)
+
+void JIT::emit_op_pre_dec(Instruction* currentInstruction)
+{
+    unsigned srcDst = currentInstruction[1].u.operand;
+
+    emitLoad(srcDst, regT1, regT0);
+
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branchSub32(Overflow, Imm32(1), regT0));
+    emitStoreInt32(srcDst, regT0, true);
+}
+
+void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned srcDst = currentInstruction[1].u.operand;
+
+    linkSlowCase(iter); // int32 check
+    linkSlowCase(iter); // overflow check
+
+    JITStubCall stubCall(this, cti_op_pre_dec);
+    stubCall.addArgument(srcDst);
+    stubCall.call(srcDst);
+}
+
+// Addition (+)
+
+void JIT::emit_op_add(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+    JumpList notInt32Op1;
+    JumpList notInt32Op2;
+
+    unsigned op;
+    int32_t constant;
+    if (getOperandConstantImmediateInt(op1, op2, op, constant)) {
+        emitAdd32Constant(dst, op, constant, op == op1 ? types.first() : types.second());
+        return;
+    }
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+
+    // Int32 case.
+    addSlowCase(branchAdd32(Overflow, regT2, regT0));
+    emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+
+    if (!supportsFloatingPoint()) {
+        addSlowCase(notInt32Op1);
+        addSlowCase(notInt32Op2);
+        return;
+    }
+    Jump end = jump();
+
+    // Double case.
+    emitBinaryDoubleOp(op_add, dst, op1, op2, types, notInt32Op1, notInt32Op2);
+    end.link(this);
+}
+
+void JIT::emitAdd32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType)
+{
+    // Int32 case.
+    emitLoad(op, regT1, regT0);
+    Jump notInt32 = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+    addSlowCase(branchAdd32(Overflow, Imm32(constant), regT0));
+    emitStoreInt32(dst, regT0, (op == dst));
+
+    // Double case.
+    if (!supportsFloatingPoint()) {
+        addSlowCase(notInt32);
+        return;
+    }
+    Jump end = jump();
+
+    notInt32.link(this);
+    if (!opType.definitelyIsNumber())
+        addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+    move(Imm32(constant), regT2);
+    convertInt32ToDouble(regT2, fpRegT0);
+    emitLoadDouble(op, fpRegT1);
+    addDouble(fpRegT1, fpRegT0);
+    emitStoreDouble(dst, fpRegT0);
+
+    end.link(this);
+}
+
+void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+    unsigned op;
+    int32_t constant;
+    if (getOperandConstantImmediateInt(op1, op2, op, constant)) {
+        linkSlowCase(iter); // overflow check
+
+        if (!supportsFloatingPoint())
+            linkSlowCase(iter); // non-sse case
+        else {
+            ResultType opType = op == op1 ? types.first() : types.second();
+            if (!opType.definitelyIsNumber())
+                linkSlowCase(iter); // double check
+        }
+    } else {
+        linkSlowCase(iter); // overflow check
+
+        if (!supportsFloatingPoint()) {
+            linkSlowCase(iter); // int32 check
+            linkSlowCase(iter); // int32 check
+        } else {
+            if (!types.first().definitelyIsNumber())
+                linkSlowCase(iter); // double check
+
+            if (!types.second().definitelyIsNumber()) {
+                linkSlowCase(iter); // int32 check
+                linkSlowCase(iter); // double check
+            }
+        }
+    }
+
+    JITStubCall stubCall(this, cti_op_add);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+// Subtraction (-)
+
+void JIT::emit_op_sub(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+    JumpList notInt32Op1;
+    JumpList notInt32Op2;
+
+    if (isOperandConstantImmediateInt(op2)) {
+        emitSub32Constant(dst, op1, getConstantOperand(op2).asInt32(), types.first());
+        return;
+    }
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+
+    // Int32 case.
+    addSlowCase(branchSub32(Overflow, regT2, regT0));
+    emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+
+    if (!supportsFloatingPoint()) {
+        addSlowCase(notInt32Op1);
+        addSlowCase(notInt32Op2);
+        return;
+    }
+    Jump end = jump();
+
+    // Double case.
+    emitBinaryDoubleOp(op_sub, dst, op1, op2, types, notInt32Op1, notInt32Op2);
+    end.link(this);
+}
+
+void JIT::emitSub32Constant(unsigned dst, unsigned op, int32_t constant, ResultType opType)
+{
+    // Int32 case.
+    emitLoad(op, regT1, regT0);
+    Jump notInt32 = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+    addSlowCase(branchSub32(Overflow, Imm32(constant), regT0));
+    emitStoreInt32(dst, regT0, (op == dst));
+
+    // Double case.
+    if (!supportsFloatingPoint()) {
+        addSlowCase(notInt32);
+        return;
+    }
+    Jump end = jump();
+
+    notInt32.link(this);
+    if (!opType.definitelyIsNumber())
+        addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+    move(Imm32(constant), regT2);
+    convertInt32ToDouble(regT2, fpRegT0);
+    emitLoadDouble(op, fpRegT1);
+    subDouble(fpRegT0, fpRegT1);
+    emitStoreDouble(dst, fpRegT1);
+
+    end.link(this);
+}
+
+void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+    if (isOperandConstantImmediateInt(op2)) {
+        linkSlowCase(iter); // overflow check
+
+        if (!supportsFloatingPoint() || !types.first().definitelyIsNumber())
+            linkSlowCase(iter); // int32 or double check
+    } else {
+        linkSlowCase(iter); // overflow check
+
+        if (!supportsFloatingPoint()) {
+            linkSlowCase(iter); // int32 check
+            linkSlowCase(iter); // int32 check
+        } else {
+            if (!types.first().definitelyIsNumber())
+                linkSlowCase(iter); // double check
+
+            if (!types.second().definitelyIsNumber()) {
+                linkSlowCase(iter); // int32 check
+                linkSlowCase(iter); // double check
+            }
+        }
+    }
+
+    JITStubCall stubCall(this, cti_op_sub);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, unsigned dst, unsigned op1, unsigned op2, OperandTypes types, JumpList& notInt32Op1, JumpList& notInt32Op2, bool op1IsInRegisters, bool op2IsInRegisters)
+{
+    JumpList end;
+    
+    if (!notInt32Op1.empty()) {
+        // Double case 1: Op1 is not int32; Op2 is unknown.
+        notInt32Op1.link(this);
+
+        ASSERT(op1IsInRegisters);
+
+        // Verify Op1 is double.
+        if (!types.first().definitelyIsNumber())
+            addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+
+        if (!op2IsInRegisters)
+            emitLoad(op2, regT3, regT2);
+
+        Jump doubleOp2 = branch32(Below, regT3, Imm32(JSValue::LowestTag));
+
+        if (!types.second().definitelyIsNumber())
+            addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+
+        convertInt32ToDouble(regT2, fpRegT0);
+        Jump doTheMath = jump();
+
+        // Load Op2 as double into double register.
+        doubleOp2.link(this);
+        emitLoadDouble(op2, fpRegT0);
+
+        // Do the math.
+        doTheMath.link(this);
+        switch (opcodeID) {
+            case op_mul:
+                emitLoadDouble(op1, fpRegT2);
+                mulDouble(fpRegT2, fpRegT0);
+                emitStoreDouble(dst, fpRegT0);
+                break;
+            case op_add:
+                emitLoadDouble(op1, fpRegT2);
+                addDouble(fpRegT2, fpRegT0);
+                emitStoreDouble(dst, fpRegT0);
+                break;
+            case op_sub:
+                emitLoadDouble(op1, fpRegT1);
+                subDouble(fpRegT0, fpRegT1);
+                emitStoreDouble(dst, fpRegT1);
+                break;
+            case op_div:
+                emitLoadDouble(op1, fpRegT1);
+                divDouble(fpRegT0, fpRegT1);
+                emitStoreDouble(dst, fpRegT1);
+                break;
+            case op_jnless:
+                emitLoadDouble(op1, fpRegT2);
+                addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT2), dst + 3);
+                break;
+            case op_jnlesseq:
+                emitLoadDouble(op1, fpRegT2);
+                addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT2), dst + 3);
+                break;
+            default:
+                ASSERT_NOT_REACHED();
+        }
+
+        if (!notInt32Op2.empty())
+            end.append(jump());
+    }
+
+    if (!notInt32Op2.empty()) {
+        // Double case 2: Op1 is int32; Op2 is not int32.
+        notInt32Op2.link(this);
+
+        ASSERT(op2IsInRegisters);
+
+        if (!op1IsInRegisters)
+            emitLoadPayload(op1, regT0);
+
+        convertInt32ToDouble(regT0, fpRegT0);
+
+        // Verify op2 is double.
+        if (!types.second().definitelyIsNumber())
+            addSlowCase(branch32(Above, regT3, Imm32(JSValue::LowestTag)));
+
+        // Do the math.
+        switch (opcodeID) {
+            case op_mul:
+                emitLoadDouble(op2, fpRegT2);
+                mulDouble(fpRegT2, fpRegT0);
+                emitStoreDouble(dst, fpRegT0);
+                break;
+            case op_add:
+                emitLoadDouble(op2, fpRegT2);
+                addDouble(fpRegT2, fpRegT0);
+                emitStoreDouble(dst, fpRegT0);
+                break;
+            case op_sub:
+                emitLoadDouble(op2, fpRegT2);
+                subDouble(fpRegT2, fpRegT0);
+                emitStoreDouble(dst, fpRegT0);
+                break;
+            case op_div:
+                emitLoadDouble(op2, fpRegT2);
+                divDouble(fpRegT2, fpRegT0);
+                emitStoreDouble(dst, fpRegT0);
+                break;
+            case op_jnless:
+                emitLoadDouble(op2, fpRegT1);
+                addJump(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), dst + 3);
+                break;
+            case op_jnlesseq:
+                emitLoadDouble(op2, fpRegT1);
+                addJump(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), dst + 3);
+                break;
+            default:
+                ASSERT_NOT_REACHED();
+        }
+    }
+
+    end.link(this);
+}
+
+// Multiplication (*)
+
+void JIT::emit_op_mul(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+    JumpList notInt32Op1;
+    JumpList notInt32Op2;
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+
+    // Int32 case.
+    move(regT0, regT3);
+    addSlowCase(branchMul32(Overflow, regT2, regT0));
+    addSlowCase(branchTest32(Zero, regT0));
+    emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+
+    if (!supportsFloatingPoint()) {
+        addSlowCase(notInt32Op1);
+        addSlowCase(notInt32Op2);
+        return;
+    }
+    Jump end = jump();
+
+    // Double case.
+    emitBinaryDoubleOp(op_mul, dst, op1, op2, types, notInt32Op1, notInt32Op2);
+    end.link(this);
+}
+
+void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+    Jump overflow = getSlowCase(iter); // overflow check
+    linkSlowCase(iter); // zero result check
+
+    Jump negZero = branchOr32(Signed, regT2, regT3);
+    emitStoreInt32(dst, Imm32(0), (op1 == dst || op2 == dst));
+
+    emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_mul));
+
+    negZero.link(this);
+    overflow.link(this);
+
+    if (!supportsFloatingPoint()) {
+        linkSlowCase(iter); // int32 check
+        linkSlowCase(iter); // int32 check
+    }
+
+    if (supportsFloatingPoint()) {
+        if (!types.first().definitelyIsNumber())
+            linkSlowCase(iter); // double check
+
+        if (!types.second().definitelyIsNumber()) {
+            linkSlowCase(iter); // int32 check
+            linkSlowCase(iter); // double check
+        }
+    }
+
+    Label jitStubCall(this);
+    JITStubCall stubCall(this, cti_op_mul);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+// Division (/)
+
+void JIT::emit_op_div(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+    if (!supportsFloatingPoint()) {
+        addSlowCase(jump());
+        return;
+    }
+
+    // Int32 divide.
+    JumpList notInt32Op1;
+    JumpList notInt32Op2;
+
+    JumpList end;
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+
+    notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+
+    convertInt32ToDouble(regT0, fpRegT0);
+    convertInt32ToDouble(regT2, fpRegT1);
+    divDouble(fpRegT1, fpRegT0);
+
+    JumpList doubleResult;
+    if (!isOperandConstantImmediateInt(op1) || getConstantOperand(op1).asInt32() > 1) {
+        m_assembler.cvttsd2si_rr(fpRegT0, regT0);
+        convertInt32ToDouble(regT0, fpRegT1);
+        m_assembler.ucomisd_rr(fpRegT1, fpRegT0);
+
+        doubleResult.append(m_assembler.jne());
+        doubleResult.append(m_assembler.jp());
+        
+        doubleResult.append(branchTest32(Zero, regT0));
+
+        // Int32 result.
+        emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+        end.append(jump());
+    }
+
+    // Double result.
+    doubleResult.link(this);
+    emitStoreDouble(dst, fpRegT0);
+    end.append(jump());
+
+    // Double divide.
+    emitBinaryDoubleOp(op_div, dst, op1, op2, types, notInt32Op1, notInt32Op2);
+    end.link(this);
+}
+
+void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
+
+    if (!supportsFloatingPoint())
+        linkSlowCase(iter);
+    else {
+        if (!types.first().definitelyIsNumber())
+            linkSlowCase(iter); // double check
+
+        if (!types.second().definitelyIsNumber()) {
+            linkSlowCase(iter); // int32 check
+            linkSlowCase(iter); // double check
+        }
+    }
+
+    JITStubCall stubCall(this, cti_op_div);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+// Mod (%)
+
+/* ------------------------------ BEGIN: OP_MOD ------------------------------ */
+
+#if PLATFORM(X86) || PLATFORM(X86_64)
+
+void JIT::emit_op_mod(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (isOperandConstantImmediateInt(op2) && getConstantOperand(op2).asInt32() != 0) {
+        emitLoad(op1, X86::edx, X86::eax);
+        move(Imm32(getConstantOperand(op2).asInt32()), X86::ecx);
+        addSlowCase(branch32(NotEqual, X86::edx, Imm32(JSValue::Int32Tag)));
+        if (getConstantOperand(op2).asInt32() == -1)
+            addSlowCase(branch32(Equal, X86::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
+    } else {
+        emitLoad2(op1, X86::edx, X86::eax, op2, X86::ebx, X86::ecx);
+        addSlowCase(branch32(NotEqual, X86::edx, Imm32(JSValue::Int32Tag)));
+        addSlowCase(branch32(NotEqual, X86::ebx, Imm32(JSValue::Int32Tag)));
+
+        addSlowCase(branch32(Equal, X86::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
+        addSlowCase(branch32(Equal, X86::ecx, Imm32(0))); // divide by 0
+    }
+
+    move(X86::eax, X86::ebx); // Save dividend payload, in case of 0.
+    m_assembler.cdq();
+    m_assembler.idivl_r(X86::ecx);
+    
+    // If the remainder is zero and the dividend is negative, the result is -0.
+    Jump storeResult1 = branchTest32(NonZero, X86::edx);
+    Jump storeResult2 = branchTest32(Zero, X86::ebx, Imm32(0x80000000)); // not negative
+    emitStore(dst, jsNumber(m_globalData, -0.0));
+    Jump end = jump();
+
+    storeResult1.link(this);
+    storeResult2.link(this);
+    emitStoreInt32(dst, X86::edx, (op1 == dst || op2 == dst));
+    end.link(this);
+}
+
+void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (isOperandConstantImmediateInt(op2) && getConstantOperand(op2).asInt32() != 0) {
+        linkSlowCase(iter); // int32 check
+        if (getConstantOperand(op2).asInt32() == -1)
+            linkSlowCase(iter); // 0x80000000 check
+    } else {
+        linkSlowCase(iter); // int32 check
+        linkSlowCase(iter); // int32 check
+        linkSlowCase(iter); // 0 check
+        linkSlowCase(iter); // 0x80000000 check
+    }
+
+    JITStubCall stubCall(this, cti_op_mod);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+#else // PLATFORM(X86) || PLATFORM(X86_64)
+
+void JIT::emit_op_mod(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_mod);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
+{
+}
+
+#endif // PLATFORM(X86) || PLATFORM(X86_64)
+
+/* ------------------------------ END: OP_MOD ------------------------------ */
+
+#else // USE(JSVALUE32_64)
+
+void JIT::emit_op_lshift(Instruction* currentInstruction)
+{
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    emitGetVirtualRegisters(op1, regT0, op2, regT2);
+    // FIXME: would we be better using 'emitJumpSlowCaseIfNotImmediateIntegers'? - we *probably* ought to be consistent.
+    emitJumpSlowCaseIfNotImmediateInteger(regT0);
+    emitJumpSlowCaseIfNotImmediateInteger(regT2);
+    emitFastArithImmToInt(regT0);
+    emitFastArithImmToInt(regT2);
+#if !PLATFORM(X86)
+    // Mask with 0x1f as per ecma-262 11.7.2 step 7.
+    // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
+    and32(Imm32(0x1f), regT2);
+#endif
+    lshift32(regT2, regT0);
+#if !USE(JSVALUE64)
+    addSlowCase(branchAdd32(Overflow, regT0, regT0));
+    signExtend32ToPtr(regT0, regT0);
+#endif
+    emitFastArithReTagImmediate(regT0, regT0);
+    emitPutVirtualRegister(result);
+}
+
+void JIT::emitSlow_op_lshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+#if USE(JSVALUE64)
+    UNUSED_PARAM(op1);
+    UNUSED_PARAM(op2);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+#else
+    // If we are limited to 32-bit immediates there is a third slow case, which required the operands to have been reloaded.
+    Jump notImm1 = getSlowCase(iter);
+    Jump notImm2 = getSlowCase(iter);
+    linkSlowCase(iter);
+    emitGetVirtualRegisters(op1, regT0, op2, regT2);
+    notImm1.link(this);
+    notImm2.link(this);
+#endif
+    JITStubCall stubCall(this, cti_op_lshift);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT2);
+    stubCall.call(result);
+}
+
+void JIT::emit_op_rshift(Instruction* currentInstruction)
+{
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    if (isOperandConstantImmediateInt(op2)) {
+        // isOperandConstantImmediateInt(op2) => 1 SlowCase
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        // Mask with 0x1f as per ecma-262 11.7.2 step 7.
+#if USE(JSVALUE64)
+        rshift32(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), regT0);
+#else
+        rshiftPtr(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), regT0);
+#endif
+    } else {
+        emitGetVirtualRegisters(op1, regT0, op2, regT2);
+        if (supportsFloatingPointTruncate()) {
+            Jump lhsIsInt = emitJumpIfImmediateInteger(regT0);
+#if USE(JSVALUE64)
+            // supportsFloatingPoint() && USE(JSVALUE64) => 3 SlowCases
+            addSlowCase(emitJumpIfNotImmediateNumber(regT0));
+            addPtr(tagTypeNumberRegister, regT0);
+            movePtrToDouble(regT0, fpRegT0);
+            addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
+#else
+            // supportsFloatingPoint() && !USE(JSVALUE64) => 5 SlowCases (of which 1 IfNotJSCell)
+            emitJumpSlowCaseIfNotJSCell(regT0, op1);
+            addSlowCase(checkStructure(regT0, m_globalData->numberStructure.get()));
+            loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
+            addSlowCase(branchTruncateDoubleToInt32(fpRegT0, regT0));
+            addSlowCase(branchAdd32(Overflow, regT0, regT0));
+#endif
+            lhsIsInt.link(this);
+            emitJumpSlowCaseIfNotImmediateInteger(regT2);
+        } else {
+            // !supportsFloatingPoint() => 2 SlowCases
+            emitJumpSlowCaseIfNotImmediateInteger(regT0);
+            emitJumpSlowCaseIfNotImmediateInteger(regT2);
+        }
+        emitFastArithImmToInt(regT2);
+#if !PLATFORM(X86)
+        // Mask with 0x1f as per ecma-262 11.7.2 step 7.
+        // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
+        and32(Imm32(0x1f), regT2);
+#endif
+#if USE(JSVALUE64)
+        rshift32(regT2, regT0);
+#else
+        rshiftPtr(regT2, regT0);
+#endif
+    }
+#if USE(JSVALUE64)
+    emitFastArithIntToImmNoCheck(regT0, regT0);
+#else
+    orPtr(Imm32(JSImmediate::TagTypeNumber), regT0);
+#endif
+    emitPutVirtualRegister(result);
+}
+
+void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_rshift);
+
+    if (isOperandConstantImmediateInt(op2)) {
+        linkSlowCase(iter);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(op2, regT2);
+    } else {
+        if (supportsFloatingPointTruncate()) {
+#if USE(JSVALUE64)
+            linkSlowCase(iter);
+            linkSlowCase(iter);
+            linkSlowCase(iter);
+#else
+            linkSlowCaseIfNotJSCell(iter, op1);
+            linkSlowCase(iter);
+            linkSlowCase(iter);
+            linkSlowCase(iter);
+            linkSlowCase(iter);
+#endif
+            // We're reloading op1 to regT0 as we can no longer guarantee that
+            // we have not munged the operand.  It may have already been shifted
+            // correctly, but it still will not have been tagged.
+            stubCall.addArgument(op1, regT0);
+            stubCall.addArgument(regT2);
+        } else {
+            linkSlowCase(iter);
+            linkSlowCase(iter);
+            stubCall.addArgument(regT0);
+            stubCall.addArgument(regT2);
+        }
+    }
+
+    stubCall.call(result);
+}
+
+void JIT::emit_op_jnless(Instruction* currentInstruction)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    // We generate inline code for the following cases in the fast path:
+    // - int immediate to constant int immediate
+    // - constant int immediate to int immediate
+    // - int immediate to int immediate
+
+    if (isOperandConstantImmediateInt(op2)) {
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+        int32_t op2imm = getConstantOperandImmediateInt(op2);
+#else
+        int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
+#endif
+        addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3);
+    } else if (isOperandConstantImmediateInt(op1)) {
+        emitGetVirtualRegister(op2, regT1);
+        emitJumpSlowCaseIfNotImmediateInteger(regT1);
+#if USE(JSVALUE64)
+        int32_t op1imm = getConstantOperandImmediateInt(op1);
+#else
+        int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
+#endif
+        addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target + 3);
+    } else {
+        emitGetVirtualRegisters(op1, regT0, op2, regT1);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT1);
+
+        addJump(branch32(GreaterThanOrEqual, regT0, regT1), target + 3);
+    }
+}
+
+void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    // We generate inline code for the following cases in the slow path:
+    // - floating-point number to constant int immediate
+    // - constant int immediate to floating-point number
+    // - floating-point number to floating-point number.
+
+    if (isOperandConstantImmediateInt(op2)) {
+        linkSlowCase(iter);
+
+        if (supportsFloatingPoint()) {
+#if USE(JSVALUE64)
+            Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
+            addPtr(tagTypeNumberRegister, regT0);
+            movePtrToDouble(regT0, fpRegT0);
+#else
+            Jump fail1;
+            if (!m_codeBlock->isKnownNotImmediate(op1))
+                fail1 = emitJumpIfNotJSCell(regT0);
+
+            Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
+            loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
+#endif
+            
+            int32_t op2imm = getConstantOperand(op2).asInt32();;
+                    
+            move(Imm32(op2imm), regT1);
+            convertInt32ToDouble(regT1, fpRegT1);
+
+            emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3);
+
+            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
+
+#if USE(JSVALUE64)
+            fail1.link(this);
+#else
+            if (!m_codeBlock->isKnownNotImmediate(op1))
+                fail1.link(this);
+            fail2.link(this);
+#endif
+        }
+
+        JITStubCall stubCall(this, cti_op_jless);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(op2, regT2);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+
+    } else if (isOperandConstantImmediateInt(op1)) {
+        linkSlowCase(iter);
 
-using namespace std;
+        if (supportsFloatingPoint()) {
+#if USE(JSVALUE64)
+            Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
+            addPtr(tagTypeNumberRegister, regT1);
+            movePtrToDouble(regT1, fpRegT1);
+#else
+            Jump fail1;
+            if (!m_codeBlock->isKnownNotImmediate(op2))
+                fail1 = emitJumpIfNotJSCell(regT1);
+            
+            Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
+            loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
+#endif
+            
+            int32_t op1imm = getConstantOperand(op1).asInt32();;
+                    
+            move(Imm32(op1imm), regT0);
+            convertInt32ToDouble(regT0, fpRegT0);
 
-namespace JSC {
+            emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3);
 
-void JIT::compileFastArith_op_lshift(unsigned result, unsigned op1, unsigned op2)
-{
-    emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
-    // FIXME: would we be better using 'emitJumpSlowCaseIfNotImmediateIntegers'? - we *probably* ought to be consistent.
-    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-    emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
-    emitFastArithImmToInt(X86::eax);
-    emitFastArithImmToInt(X86::ecx);
-#if !PLATFORM(X86)
-    // Mask with 0x1f as per ecma-262 11.7.2 step 7.
-    // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
-    and32(Imm32(0x1f), X86::ecx);
+            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
+
+#if USE(JSVALUE64)
+            fail1.link(this);
+#else
+            if (!m_codeBlock->isKnownNotImmediate(op2))
+                fail1.link(this);
+            fail2.link(this);
+#endif
+        }
+
+        JITStubCall stubCall(this, cti_op_jless);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(regT1);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+
+    } else {
+        linkSlowCase(iter);
+
+        if (supportsFloatingPoint()) {
+#if USE(JSVALUE64)
+            Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
+            Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
+            Jump fail3 = emitJumpIfImmediateInteger(regT1);
+            addPtr(tagTypeNumberRegister, regT0);
+            addPtr(tagTypeNumberRegister, regT1);
+            movePtrToDouble(regT0, fpRegT0);
+            movePtrToDouble(regT1, fpRegT1);
+#else
+            Jump fail1;
+            if (!m_codeBlock->isKnownNotImmediate(op1))
+                fail1 = emitJumpIfNotJSCell(regT0);
+
+            Jump fail2;
+            if (!m_codeBlock->isKnownNotImmediate(op2))
+                fail2 = emitJumpIfNotJSCell(regT1);
+
+            Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
+            Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
+            loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
+            loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
 #endif
-    lshift32(X86::ecx, X86::eax);
-#if !USE(ALTERNATE_JSIMMEDIATE)
-    addSlowCase(joAdd32(X86::eax, X86::eax));
-    signExtend32ToPtr(X86::eax, X86::eax);
+
+            emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqual, fpRegT1, fpRegT0), target + 3);
+
+            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
+
+#if USE(JSVALUE64)
+            fail1.link(this);
+            fail2.link(this);
+            fail3.link(this);
+#else
+            if (!m_codeBlock->isKnownNotImmediate(op1))
+                fail1.link(this);
+            if (!m_codeBlock->isKnownNotImmediate(op2))
+                fail2.link(this);
+            fail3.link(this);
+            fail4.link(this);
 #endif
-    emitFastArithReTagImmediate(X86::eax, X86::eax);
-    emitPutVirtualRegister(result);
+        }
+
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_jless);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(regT1);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+    }
 }
-void JIT::compileFastArithSlow_op_lshift(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
 {
-#if USE(ALTERNATE_JSIMMEDIATE)
-    UNUSED_PARAM(op1);
-    UNUSED_PARAM(op2);
-    linkSlowCase(iter);
-    linkSlowCase(iter);
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    // We generate inline code for the following cases in the fast path:
+    // - int immediate to constant int immediate
+    // - constant int immediate to int immediate
+    // - int immediate to int immediate
+
+    if (isOperandConstantImmediateInt(op2)) {
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+        int32_t op2imm = getConstantOperandImmediateInt(op2);
 #else
-    // If we are limited to 32-bit immediates there is a third slow case, which required the operands to have been reloaded.
-    Jump notImm1 = getSlowCase(iter);
-    Jump notImm2 = getSlowCase(iter);
-    linkSlowCase(iter);
-    emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
-    notImm1.link(this);
-    notImm2.link(this);
+        int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
 #endif
-    emitPutJITStubArg(X86::eax, 1);
-    emitPutJITStubArg(X86::ecx, 2);
-    emitCTICall(Interpreter::cti_op_lshift);
-    emitPutVirtualRegister(result);
+        addJump(branch32(GreaterThan, regT0, Imm32(op2imm)), target + 3);
+    } else if (isOperandConstantImmediateInt(op1)) {
+        emitGetVirtualRegister(op2, regT1);
+        emitJumpSlowCaseIfNotImmediateInteger(regT1);
+#if USE(JSVALUE64)
+        int32_t op1imm = getConstantOperandImmediateInt(op1);
+#else
+        int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
+#endif
+        addJump(branch32(LessThan, regT1, Imm32(op1imm)), target + 3);
+    } else {
+        emitGetVirtualRegisters(op1, regT0, op2, regT1);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT1);
+
+        addJump(branch32(GreaterThan, regT0, regT1), target + 3);
+    }
 }
 
-void JIT::compileFastArith_op_rshift(unsigned result, unsigned op1, unsigned op2)
+void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    // We generate inline code for the following cases in the slow path:
+    // - floating-point number to constant int immediate
+    // - constant int immediate to floating-point number
+    // - floating-point number to floating-point number.
+
     if (isOperandConstantImmediateInt(op2)) {
-        emitGetVirtualRegister(op1, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        // Mask with 0x1f as per ecma-262 11.7.2 step 7.
-#if USE(ALTERNATE_JSIMMEDIATE)
-        rshift32(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), X86::eax);
+        linkSlowCase(iter);
+
+        if (supportsFloatingPoint()) {
+#if USE(JSVALUE64)
+            Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
+            addPtr(tagTypeNumberRegister, regT0);
+            movePtrToDouble(regT0, fpRegT0);
 #else
-        rshiftPtr(Imm32(getConstantOperandImmediateInt(op2) & 0x1f), X86::eax);
+            Jump fail1;
+            if (!m_codeBlock->isKnownNotImmediate(op1))
+                fail1 = emitJumpIfNotJSCell(regT0);
+
+            Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
+            loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
 #endif
-    } else {
-        emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
-        emitFastArithImmToInt(X86::ecx);
-#if !PLATFORM(X86)
-        // Mask with 0x1f as per ecma-262 11.7.2 step 7.
-        // On 32-bit x86 this is not necessary, since the shift anount is implicitly masked in the instruction.
-        and32(Imm32(0x1f), X86::ecx);
+            
+            int32_t op2imm = getConstantOperand(op2).asInt32();;
+                    
+            move(Imm32(op2imm), regT1);
+            convertInt32ToDouble(regT1, fpRegT1);
+
+            emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3);
+
+            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
+
+#if USE(JSVALUE64)
+            fail1.link(this);
+#else
+            if (!m_codeBlock->isKnownNotImmediate(op1))
+                fail1.link(this);
+            fail2.link(this);
 #endif
-#if USE(ALTERNATE_JSIMMEDIATE)
-        rshift32(X86::ecx, X86::eax);
+        }
+
+        JITStubCall stubCall(this, cti_op_jlesseq);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(op2, regT2);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+
+    } else if (isOperandConstantImmediateInt(op1)) {
+        linkSlowCase(iter);
+
+        if (supportsFloatingPoint()) {
+#if USE(JSVALUE64)
+            Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
+            addPtr(tagTypeNumberRegister, regT1);
+            movePtrToDouble(regT1, fpRegT1);
 #else
-        rshiftPtr(X86::ecx, X86::eax);
+            Jump fail1;
+            if (!m_codeBlock->isKnownNotImmediate(op2))
+                fail1 = emitJumpIfNotJSCell(regT1);
+            
+            Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
+            loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
 #endif
-    }
-#if USE(ALTERNATE_JSIMMEDIATE)
-    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+            
+            int32_t op1imm = getConstantOperand(op1).asInt32();;
+                    
+            move(Imm32(op1imm), regT0);
+            convertInt32ToDouble(regT0, fpRegT0);
+
+            emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3);
+
+            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
+
+#if USE(JSVALUE64)
+            fail1.link(this);
 #else
-    orPtr(Imm32(JSImmediate::TagTypeNumber), X86::eax);
+            if (!m_codeBlock->isKnownNotImmediate(op2))
+                fail1.link(this);
+            fail2.link(this);
 #endif
-    emitPutVirtualRegister(result);
-}
-void JIT::compileFastArithSlow_op_rshift(unsigned result, unsigned, unsigned op2, Vector<SlowCaseEntry>::iterator& iter)
-{
-    linkSlowCase(iter);
-    if (isOperandConstantImmediateInt(op2))
-        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-    else {
+        }
+
+        JITStubCall stubCall(this, cti_op_jlesseq);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(regT1);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+
+    } else {
         linkSlowCase(iter);
-        emitPutJITStubArg(X86::ecx, 2);
-    }
 
-    emitPutJITStubArg(X86::eax, 1);
-    emitCTICall(Interpreter::cti_op_rshift);
-    emitPutVirtualRegister(result);
+        if (supportsFloatingPoint()) {
+#if USE(JSVALUE64)
+            Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
+            Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
+            Jump fail3 = emitJumpIfImmediateInteger(regT1);
+            addPtr(tagTypeNumberRegister, regT0);
+            addPtr(tagTypeNumberRegister, regT1);
+            movePtrToDouble(regT0, fpRegT0);
+            movePtrToDouble(regT1, fpRegT1);
+#else
+            Jump fail1;
+            if (!m_codeBlock->isKnownNotImmediate(op1))
+                fail1 = emitJumpIfNotJSCell(regT0);
+
+            Jump fail2;
+            if (!m_codeBlock->isKnownNotImmediate(op2))
+                fail2 = emitJumpIfNotJSCell(regT1);
+
+            Jump fail3 = checkStructure(regT0, m_globalData->numberStructure.get());
+            Jump fail4 = checkStructure(regT1, m_globalData->numberStructure.get());
+            loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
+            loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
+#endif
+
+            emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT1, fpRegT0), target + 3);
+
+            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
+
+#if USE(JSVALUE64)
+            fail1.link(this);
+            fail2.link(this);
+            fail3.link(this);
+#else
+            if (!m_codeBlock->isKnownNotImmediate(op1))
+                fail1.link(this);
+            if (!m_codeBlock->isKnownNotImmediate(op2))
+                fail2.link(this);
+            fail3.link(this);
+            fail4.link(this);
+#endif
+        }
+
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_jlesseq);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(regT1);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
+    }
 }
 
-void JIT::compileFastArith_op_bitand(unsigned result, unsigned op1, unsigned op2)
+void JIT::emit_op_bitand(Instruction* currentInstruction)
 {
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
     if (isOperandConstantImmediateInt(op1)) {
-        emitGetVirtualRegister(op2, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
+        emitGetVirtualRegister(op2, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
         int32_t imm = getConstantOperandImmediateInt(op1);
-        andPtr(Imm32(imm), X86::eax);
+        andPtr(Imm32(imm), regT0);
         if (imm >= 0)
-            emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+            emitFastArithIntToImmNoCheck(regT0, regT0);
 #else
-        andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)))), X86::eax);
+        andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)))), regT0);
 #endif
     } else if (isOperandConstantImmediateInt(op2)) {
-        emitGetVirtualRegister(op1, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
         int32_t imm = getConstantOperandImmediateInt(op2);
-        andPtr(Imm32(imm), X86::eax);
+        andPtr(Imm32(imm), regT0);
         if (imm >= 0)
-            emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+            emitFastArithIntToImmNoCheck(regT0, regT0);
 #else
-        andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)))), X86::eax);
+        andPtr(Imm32(static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)))), regT0);
 #endif
     } else {
-        emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
-        andPtr(X86::edx, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+        emitGetVirtualRegisters(op1, regT0, op2, regT1);
+        andPtr(regT1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
     }
     emitPutVirtualRegister(result);
 }
-void JIT::compileFastArithSlow_op_bitand(unsigned result, unsigned op1, unsigned op2, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_bitand(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
     linkSlowCase(iter);
     if (isOperandConstantImmediateInt(op1)) {
-        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-        emitPutJITStubArg(X86::eax, 2);
+        JITStubCall stubCall(this, cti_op_bitand);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(regT0);
+        stubCall.call(result);
     } else if (isOperandConstantImmediateInt(op2)) {
-        emitPutJITStubArg(X86::eax, 1);
-        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
+        JITStubCall stubCall(this, cti_op_bitand);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(op2, regT2);
+        stubCall.call(result);
     } else {
-        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-        emitPutJITStubArg(X86::edx, 2);
+        JITStubCall stubCall(this, cti_op_bitand);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(regT1);
+        stubCall.call(result);
     }
-    emitCTICall(Interpreter::cti_op_bitand);
-    emitPutVirtualRegister(result);
 }
 
-void JIT::compileFastArith_op_mod(unsigned result, unsigned op1, unsigned op2)
-{
-    emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
-    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-    emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
-#if USE(ALTERNATE_JSIMMEDIATE)
-    addSlowCase(jePtr(X86::ecx, ImmPtr(JSValuePtr::encode(js0()))));
-    mod32(X86::ecx, X86::eax, X86::edx);
-#else
-    emitFastArithDeTagImmediate(X86::eax);
-    addSlowCase(emitFastArithDeTagImmediateJumpIfZero(X86::ecx));
-    mod32(X86::ecx, X86::eax, X86::edx);
-    signExtend32ToPtr(X86::edx, X86::edx);
-#endif
-    emitFastArithReTagImmediate(X86::edx, X86::eax);
-    emitPutVirtualRegister(result);
-}
-void JIT::compileFastArithSlow_op_mod(unsigned result, unsigned, unsigned, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emit_op_post_inc(Instruction* currentInstruction)
 {
-#if USE(ALTERNATE_JSIMMEDIATE)
-    linkSlowCase(iter);
-    linkSlowCase(iter);
-    linkSlowCase(iter);
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned srcDst = currentInstruction[2].u.operand;
+
+    emitGetVirtualRegister(srcDst, regT0);
+    move(regT0, regT1);
+    emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+    addSlowCase(branchAdd32(Overflow, Imm32(1), regT1));
+    emitFastArithIntToImmNoCheck(regT1, regT1);
 #else
-    Jump notImm1 = getSlowCase(iter);
-    Jump notImm2 = getSlowCase(iter);
-    linkSlowCase(iter);
-    emitFastArithReTagImmediate(X86::eax, X86::eax);
-    emitFastArithReTagImmediate(X86::ecx, X86::ecx);
-    notImm1.link(this);
-    notImm2.link(this);
+    addSlowCase(branchAdd32(Overflow, Imm32(1 << JSImmediate::IntegerPayloadShift), regT1));
+    signExtend32ToPtr(regT1, regT1);
 #endif
-    emitPutJITStubArg(X86::eax, 1);
-    emitPutJITStubArg(X86::ecx, 2);
-    emitCTICall(Interpreter::cti_op_mod);
+    emitPutVirtualRegister(srcDst, regT1);
     emitPutVirtualRegister(result);
 }
 
-void JIT::compileFastArith_op_post_inc(unsigned result, unsigned srcDst)
-{
-    emitGetVirtualRegister(srcDst, X86::eax);
-    move(X86::eax, X86::edx);
-    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
-    addSlowCase(joAdd32(Imm32(1), X86::edx));
-    emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
-#else
-    addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx));
-    signExtend32ToPtr(X86::edx, X86::edx);
-#endif
-    emitPutVirtualRegister(srcDst, X86::edx);
-    emitPutVirtualRegister(result);
-}
-void JIT::compileFastArithSlow_op_post_inc(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_post_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned srcDst = currentInstruction[2].u.operand;
+
     linkSlowCase(iter);
     linkSlowCase(iter);
-    emitPutJITStubArg(X86::eax, 1);
-    emitCTICall(Interpreter::cti_op_post_inc);
-    emitPutVirtualRegister(srcDst, X86::edx);
-    emitPutVirtualRegister(result);
+    JITStubCall stubCall(this, cti_op_post_inc);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(Imm32(srcDst));
+    stubCall.call(result);
 }
 
-void JIT::compileFastArith_op_post_dec(unsigned result, unsigned srcDst)
+void JIT::emit_op_post_dec(Instruction* currentInstruction)
 {
-    emitGetVirtualRegister(srcDst, X86::eax);
-    move(X86::eax, X86::edx);
-    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
-    addSlowCase(joSub32(Imm32(1), X86::edx));
-    emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned srcDst = currentInstruction[2].u.operand;
+
+    emitGetVirtualRegister(srcDst, regT0);
+    move(regT0, regT1);
+    emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+    addSlowCase(branchSub32(Zero, Imm32(1), regT1));
+    emitFastArithIntToImmNoCheck(regT1, regT1);
 #else
-    addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::edx));
-    signExtend32ToPtr(X86::edx, X86::edx);
+    addSlowCase(branchSub32(Zero, Imm32(1 << JSImmediate::IntegerPayloadShift), regT1));
+    signExtend32ToPtr(regT1, regT1);
 #endif
-    emitPutVirtualRegister(srcDst, X86::edx);
+    emitPutVirtualRegister(srcDst, regT1);
     emitPutVirtualRegister(result);
 }
-void JIT::compileFastArithSlow_op_post_dec(unsigned result, unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_post_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned srcDst = currentInstruction[2].u.operand;
+
     linkSlowCase(iter);
     linkSlowCase(iter);
-    emitPutJITStubArg(X86::eax, 1);
-    emitCTICall(Interpreter::cti_op_post_dec);
-    emitPutVirtualRegister(srcDst, X86::edx);
-    emitPutVirtualRegister(result);
+    JITStubCall stubCall(this, cti_op_post_dec);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(Imm32(srcDst));
+    stubCall.call(result);
 }
 
-void JIT::compileFastArith_op_pre_inc(unsigned srcDst)
+void JIT::emit_op_pre_inc(Instruction* currentInstruction)
 {
-    emitGetVirtualRegister(srcDst, X86::eax);
-    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
-    addSlowCase(joAdd32(Imm32(1), X86::eax));
-    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+    unsigned srcDst = currentInstruction[1].u.operand;
+
+    emitGetVirtualRegister(srcDst, regT0);
+    emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+    addSlowCase(branchAdd32(Overflow, Imm32(1), regT0));
+    emitFastArithIntToImmNoCheck(regT0, regT0);
 #else
-    addSlowCase(joAdd32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax));
-    signExtend32ToPtr(X86::eax, X86::eax);
+    addSlowCase(branchAdd32(Overflow, Imm32(1 << JSImmediate::IntegerPayloadShift), regT0));
+    signExtend32ToPtr(regT0, regT0);
 #endif
     emitPutVirtualRegister(srcDst);
 }
-void JIT::compileFastArithSlow_op_pre_inc(unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_pre_inc(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+    unsigned srcDst = currentInstruction[1].u.operand;
+
     Jump notImm = getSlowCase(iter);
     linkSlowCase(iter);
-    emitGetVirtualRegister(srcDst, X86::eax);
+    emitGetVirtualRegister(srcDst, regT0);
     notImm.link(this);
-    emitPutJITStubArg(X86::eax, 1);
-    emitCTICall(Interpreter::cti_op_pre_inc);
-    emitPutVirtualRegister(srcDst);
+    JITStubCall stubCall(this, cti_op_pre_inc);
+    stubCall.addArgument(regT0);
+    stubCall.call(srcDst);
 }
 
-void JIT::compileFastArith_op_pre_dec(unsigned srcDst)
+void JIT::emit_op_pre_dec(Instruction* currentInstruction)
 {
-    emitGetVirtualRegister(srcDst, X86::eax);
-    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-#if USE(ALTERNATE_JSIMMEDIATE)
-    addSlowCase(joSub32(Imm32(1), X86::eax));
-    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+    unsigned srcDst = currentInstruction[1].u.operand;
+
+    emitGetVirtualRegister(srcDst, regT0);
+    emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+    addSlowCase(branchSub32(Zero, Imm32(1), regT0));
+    emitFastArithIntToImmNoCheck(regT0, regT0);
 #else
-    addSlowCase(joSub32(Imm32(1 << JSImmediate::IntegerPayloadShift), X86::eax));
-    signExtend32ToPtr(X86::eax, X86::eax);
+    addSlowCase(branchSub32(Zero, Imm32(1 << JSImmediate::IntegerPayloadShift), regT0));
+    signExtend32ToPtr(regT0, regT0);
 #endif
     emitPutVirtualRegister(srcDst);
 }
-void JIT::compileFastArithSlow_op_pre_dec(unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_pre_dec(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+    unsigned srcDst = currentInstruction[1].u.operand;
+
     Jump notImm = getSlowCase(iter);
     linkSlowCase(iter);
-    emitGetVirtualRegister(srcDst, X86::eax);
+    emitGetVirtualRegister(srcDst, regT0);
     notImm.link(this);
-    emitPutJITStubArg(X86::eax, 1);
-    emitCTICall(Interpreter::cti_op_pre_dec);
-    emitPutVirtualRegister(srcDst);
+    JITStubCall stubCall(this, cti_op_pre_dec);
+    stubCall.addArgument(regT0);
+    stubCall.call(srcDst);
 }
 
+/* ------------------------------ BEGIN: OP_MOD ------------------------------ */
 
-#if !ENABLE(JIT_OPTIMIZE_ARITHMETIC)
+#if PLATFORM(X86) || PLATFORM(X86_64)
 
-void JIT::compileFastArith_op_add(Instruction* currentInstruction)
+void JIT::emit_op_mod(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
     unsigned op2 = currentInstruction[3].u.operand;
 
-    emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-    emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-    emitCTICall(Interpreter::cti_op_add);
+    emitGetVirtualRegisters(op1, X86::eax, op2, X86::ecx);
+    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
+    emitJumpSlowCaseIfNotImmediateInteger(X86::ecx);
+#if USE(JSVALUE64)
+    addSlowCase(branchPtr(Equal, X86::ecx, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))));
+    m_assembler.cdq();
+    m_assembler.idivl_r(X86::ecx);
+#else
+    emitFastArithDeTagImmediate(X86::eax);
+    addSlowCase(emitFastArithDeTagImmediateJumpIfZero(X86::ecx));
+    m_assembler.cdq();
+    m_assembler.idivl_r(X86::ecx);
+    signExtend32ToPtr(X86::edx, X86::edx);
+#endif
+    emitFastArithReTagImmediate(X86::edx, X86::eax);
     emitPutVirtualRegister(result);
 }
-void JIT::compileFastArithSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&)
-{
-    ASSERT_NOT_REACHED();
-}
 
-void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
+void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     unsigned result = currentInstruction[1].u.operand;
-    unsigned op1 = currentInstruction[2].u.operand;
-    unsigned op2 = currentInstruction[3].u.operand;
 
-    emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-    emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-    emitCTICall(Interpreter::cti_op_mul);
-    emitPutVirtualRegister(result);
-}
-void JIT::compileFastArithSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&)
-{
-    ASSERT_NOT_REACHED();
+#if USE(JSVALUE64)
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+#else
+    Jump notImm1 = getSlowCase(iter);
+    Jump notImm2 = getSlowCase(iter);
+    linkSlowCase(iter);
+    emitFastArithReTagImmediate(X86::eax, X86::eax);
+    emitFastArithReTagImmediate(X86::ecx, X86::ecx);
+    notImm1.link(this);
+    notImm2.link(this);
+#endif
+    JITStubCall stubCall(this, cti_op_mod);
+    stubCall.addArgument(X86::eax);
+    stubCall.addArgument(X86::ecx);
+    stubCall.call(result);
 }
 
-void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
+#else // PLATFORM(X86) || PLATFORM(X86_64)
+
+void JIT::emit_op_mod(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
     unsigned op2 = currentInstruction[3].u.operand;
 
-    emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-    emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-    emitCTICall(Interpreter::cti_op_sub);
-    emitPutVirtualRegister(result);
+    JITStubCall stubCall(this, cti_op_mod);
+    stubCall.addArgument(op1, regT2);
+    stubCall.addArgument(op2, regT2);
+    stubCall.call(result);
 }
-void JIT::compileFastArithSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&)
+
+void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
 {
     ASSERT_NOT_REACHED();
 }
 
-#elif USE(ALTERNATE_JSIMMEDIATE) // *AND* ENABLE(JIT_OPTIMIZE_ARITHMETIC)
+#endif // PLATFORM(X86) || PLATFORM(X86_64)
+
+/* ------------------------------ END: OP_MOD ------------------------------ */
+
+#if USE(JSVALUE64)
+
+/* ------------------------------ BEGIN: USE(JSVALUE64) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */
 
 void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsigned op2, OperandTypes)
 {
-    emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
-    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-    emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+    emitGetVirtualRegisters(op1, regT0, op2, regT1);
+    emitJumpSlowCaseIfNotImmediateInteger(regT0);
+    emitJumpSlowCaseIfNotImmediateInteger(regT1);
     if (opcodeID == op_add)
-        addSlowCase(joAdd32(X86::edx, X86::eax));
+        addSlowCase(branchAdd32(Overflow, regT1, regT0));
     else if (opcodeID == op_sub)
-        addSlowCase(joSub32(X86::edx, X86::eax));
+        addSlowCase(branchSub32(Overflow, regT1, regT0));
     else {
         ASSERT(opcodeID == op_mul);
-        addSlowCase(joMul32(X86::edx, X86::eax));
-        addSlowCase(jz32(X86::eax));
+        addSlowCase(branchMul32(Overflow, regT1, regT0));
+        addSlowCase(branchTest32(Zero, regT0));
     }
-    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+    emitFastArithIntToImmNoCheck(regT0, regT0);
 }
 
-void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned, unsigned op1, unsigned, OperandTypes types)
+void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned result, unsigned op1, unsigned, OperandTypes types)
 {
     // We assume that subtracting TagTypeNumber is equivalent to adding DoubleEncodeOffset.
     COMPILE_ASSERT(((JSImmediate::TagTypeNumber + JSImmediate::DoubleEncodeOffset) == 0), TagTypeNumber_PLUS_DoubleEncodeOffset_EQUALS_0);
@@ -403,58 +1942,53 @@ void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>:
     linkSlowCase(iter); // Integer overflow case - we could handle this in JIT code, but this is likely rare.
     if (opcodeID == op_mul) // op_mul has an extra slow case to handle 0 * negative number.
         linkSlowCase(iter);
-    emitGetVirtualRegister(op1, X86::eax);
+    emitGetVirtualRegister(op1, regT0);
 
     Label stubFunctionCall(this);
-    emitPutJITStubArg(X86::eax, 1);
-    emitPutJITStubArg(X86::edx, 2);
-    if (opcodeID == op_add)
-        emitCTICall(Interpreter::cti_op_add);
-    else if (opcodeID == op_sub)
-        emitCTICall(Interpreter::cti_op_sub);
-    else {
-        ASSERT(opcodeID == op_mul);
-        emitCTICall(Interpreter::cti_op_mul);
-    }
+    JITStubCall stubCall(this, opcodeID == op_add ? cti_op_add : opcodeID == op_sub ? cti_op_sub : cti_op_mul);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT1);
+    stubCall.call(result);
     Jump end = jump();
 
     // if we get here, eax is not an int32, edx not yet checked.
     notImm1.link(this);
     if (!types.first().definitelyIsNumber())
-        emitJumpIfNotImmediateNumber(X86::eax).linkTo(stubFunctionCall, this);
+        emitJumpIfNotImmediateNumber(regT0).linkTo(stubFunctionCall, this);
     if (!types.second().definitelyIsNumber())
-        emitJumpIfNotImmediateNumber(X86::edx).linkTo(stubFunctionCall, this);
-    addPtr(tagTypeNumberRegister, X86::eax);
-    m_assembler.movq_rr(X86::eax, X86::xmm1);
-    Jump op2isDouble = emitJumpIfNotImmediateInteger(X86::edx);
-    m_assembler.cvtsi2sd_rr(X86::edx, X86::xmm2);
+        emitJumpIfNotImmediateNumber(regT1).linkTo(stubFunctionCall, this);
+    addPtr(tagTypeNumberRegister, regT0);
+    movePtrToDouble(regT0, fpRegT1);
+    Jump op2isDouble = emitJumpIfNotImmediateInteger(regT1);
+    convertInt32ToDouble(regT1, fpRegT2);
     Jump op2wasInteger = jump();
 
     // if we get here, eax IS an int32, edx is not.
     notImm2.link(this);
     if (!types.second().definitelyIsNumber())
-        emitJumpIfNotImmediateNumber(X86::edx).linkTo(stubFunctionCall, this);
-    m_assembler.cvtsi2sd_rr(X86::eax, X86::xmm1);
+        emitJumpIfNotImmediateNumber(regT1).linkTo(stubFunctionCall, this);
+    convertInt32ToDouble(regT0, fpRegT1);
     op2isDouble.link(this);
-    addPtr(tagTypeNumberRegister, X86::edx);
-    m_assembler.movq_rr(X86::edx, X86::xmm2);
+    addPtr(tagTypeNumberRegister, regT1);
+    movePtrToDouble(regT1, fpRegT2);
     op2wasInteger.link(this);
 
     if (opcodeID == op_add)
-        m_assembler.addsd_rr(X86::xmm2, X86::xmm1);
+        addDouble(fpRegT2, fpRegT1);
     else if (opcodeID == op_sub)
-        m_assembler.subsd_rr(X86::xmm2, X86::xmm1);
+        subDouble(fpRegT2, fpRegT1);
     else {
         ASSERT(opcodeID == op_mul);
-        m_assembler.mulsd_rr(X86::xmm2, X86::xmm1);
+        mulDouble(fpRegT2, fpRegT1);
     }
-    m_assembler.movq_rr(X86::xmm1, X86::eax);
-    subPtr(tagTypeNumberRegister, X86::eax);
+    moveDoubleToPtr(fpRegT1, regT0);
+    subPtr(tagTypeNumberRegister, regT0);
+    emitPutVirtualRegister(result, regT0);
 
     end.link(this);
 }
 
-void JIT::compileFastArith_op_add(Instruction* currentInstruction)
+void JIT::emit_op_add(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
@@ -462,54 +1996,47 @@ void JIT::compileFastArith_op_add(Instruction* currentInstruction)
     OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
 
     if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
-        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-        emitCTICall(Interpreter::cti_op_add);
-        emitPutVirtualRegister(result);
+        JITStubCall stubCall(this, cti_op_add);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(op2, regT2);
+        stubCall.call(result);
         return;
     }
 
     if (isOperandConstantImmediateInt(op1)) {
-        emitGetVirtualRegister(op2, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1)), X86::eax));
-        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+        emitGetVirtualRegister(op2, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op1)), regT0));
+        emitFastArithIntToImmNoCheck(regT0, regT0);
     } else if (isOperandConstantImmediateInt(op2)) {
-        emitGetVirtualRegister(op1, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2)), X86::eax));
-        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op2)), regT0));
+        emitFastArithIntToImmNoCheck(regT0, regT0);
     } else
         compileBinaryArithOp(op_add, result, op1, op2, types);
 
     emitPutVirtualRegister(result);
 }
-void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
     unsigned op2 = currentInstruction[3].u.operand;
-    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
 
-    if (isOperandConstantImmediateInt(op1)) {
+    if (isOperandConstantImmediateInt(op1) || isOperandConstantImmediateInt(op2)) {
         linkSlowCase(iter);
         linkSlowCase(iter);
-        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-        emitCTICall(Interpreter::cti_op_add);
-    } else if (isOperandConstantImmediateInt(op2)) {
-        linkSlowCase(iter);
-        linkSlowCase(iter);
-        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-        emitCTICall(Interpreter::cti_op_add);
+        JITStubCall stubCall(this, cti_op_add);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(op2, regT2);
+        stubCall.call(result);
     } else
-        compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types);
-
-    emitPutVirtualRegister(result);
+        compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
 }
 
-void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
+void JIT::emit_op_mul(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
@@ -519,21 +2046,22 @@ void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
     // For now, only plant a fast int case if the constant operand is greater than zero.
     int32_t value;
     if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
-        emitGetVirtualRegister(op2, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
-        emitFastArithReTagImmediate(X86::eax, X86::eax);
+        emitGetVirtualRegister(op2, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
+        emitFastArithReTagImmediate(regT0, regT0);
     } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
-        emitGetVirtualRegister(op1, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
-        emitFastArithReTagImmediate(X86::eax, X86::eax);
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
+        emitFastArithReTagImmediate(regT0, regT0);
     } else
         compileBinaryArithOp(op_mul, result, op1, op2, types);
 
     emitPutVirtualRegister(result);
 }
-void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
@@ -545,16 +2073,15 @@ void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<Sl
         linkSlowCase(iter);
         linkSlowCase(iter);
         // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
-        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-        emitCTICall(Interpreter::cti_op_mul);
+        JITStubCall stubCall(this, cti_op_mul);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(op2, regT2);
+        stubCall.call(result);
     } else
         compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, types);
-
-    emitPutVirtualRegister(result);
 }
 
-void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
+void JIT::emit_op_sub(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
@@ -565,7 +2092,8 @@ void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
 
     emitPutVirtualRegister(result);
 }
-void JIT::compileFastArithSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
@@ -573,247 +2101,153 @@ void JIT::compileFastArithSlow_op_sub(Instruction* currentInstruction, Vector<Sl
     OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
 
     compileBinaryArithOpSlowCase(op_sub, iter, result, op1, op2, types);
-
-    emitPutVirtualRegister(result);
-}
-
-#else
-
-typedef X86Assembler::JmpSrc JmpSrc;
-typedef X86Assembler::JmpDst JmpDst;
-typedef X86Assembler::XMMRegisterID XMMRegisterID;
-
-#if PLATFORM(MAC)
-
-static inline bool isSSE2Present()
-{
-    return true; // All X86 Macs are guaranteed to support at least SSE2
-}
-
-#else
-
-static bool isSSE2Present()
-{
-    static const int SSE2FeatureBit = 1 << 26;
-    struct SSE2Check {
-        SSE2Check()
-        {
-            int flags;
-#if COMPILER(MSVC)
-            _asm {
-                mov eax, 1 // cpuid function 1 gives us the standard feature set
-                cpuid;
-                mov flags, edx;
-            }
-#else
-            flags = 0;
-            // FIXME: Add GCC code to do above asm
-#endif
-            present = (flags & SSE2FeatureBit) != 0;
-        }
-        bool present;
-    };
-    static SSE2Check check;
-    return check.present;
 }
 
-#endif
+#else // USE(JSVALUE64)
 
-/*
-  This is required since number representation is canonical - values representable as a JSImmediate should not be stored in a JSNumberCell.
-  
-  In the common case, the double value from 'xmmSource' is written to the reusable JSNumberCell pointed to by 'jsNumberCell', then 'jsNumberCell'
-  is written to the output SF Register 'dst', and then a jump is planted (stored into *wroteJSNumberCell).
-  
-  However if the value from xmmSource is representable as a JSImmediate, then the JSImmediate value will be written to the output, and flow
-  control will fall through from the code planted.
-*/
-void JIT::putDoubleResultToJSNumberCellOrJSImmediate(X86::XMMRegisterID xmmSource, X86::RegisterID jsNumberCell, unsigned dst, JmpSrc* wroteJSNumberCell,  X86::XMMRegisterID tempXmm, X86::RegisterID tempReg1, X86::RegisterID tempReg2)
-{
-    // convert (double -> JSImmediate -> double), and check if the value is unchanged - in which case the value is representable as a JSImmediate.
-    __ cvttsd2si_rr(xmmSource, tempReg1);
-    __ addl_rr(tempReg1, tempReg1);
-    __ sarl_i8r(1, tempReg1);
-    __ cvtsi2sd_rr(tempReg1, tempXmm);
-    // Compare & branch if immediate. 
-    __ ucomisd_rr(tempXmm, xmmSource);
-    JmpSrc resultIsImm = __ je();
-    JmpDst resultLookedLikeImmButActuallyIsnt = __ label();
-    
-    // Store the result to the JSNumberCell and jump.
-    __ movsd_rm(xmmSource, FIELD_OFFSET(JSNumberCell, m_value), jsNumberCell);
-    if (jsNumberCell != X86::eax)
-        __ movl_rr(jsNumberCell, X86::eax);
-    emitPutVirtualRegister(dst);
-    *wroteJSNumberCell = __ jmp();
-
-    __ link(resultIsImm, __ label());
-    // value == (double)(JSImmediate)value... or at least, it looks that way...
-    // ucomi will report that (0 == -0), and will report true if either input in NaN (result is unordered).
-    __ link(__ jp(), resultLookedLikeImmButActuallyIsnt); // Actually was a NaN
-    __ pextrw_irr(3, xmmSource, tempReg2);
-    __ cmpl_ir(0x8000, tempReg2);
-    __ link(__ je(), resultLookedLikeImmButActuallyIsnt); // Actually was -0
-    // Yes it really really really is representable as a JSImmediate.
-    emitFastArithIntToImmNoCheck(tempReg1, X86::eax);
-    emitPutVirtualRegister(dst);
-}
+/* ------------------------------ BEGIN: !USE(JSVALUE64) (OP_ADD, OP_SUB, OP_MUL) ------------------------------ */
 
 void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes types)
 {
     Structure* numberStructure = m_globalData->numberStructure.get();
-    JmpSrc wasJSNumberCell1;
-    JmpSrc wasJSNumberCell1b;
-    JmpSrc wasJSNumberCell2;
-    JmpSrc wasJSNumberCell2b;
+    Jump wasJSNumberCell1;
+    Jump wasJSNumberCell2;
 
-    emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx);
+    emitGetVirtualRegisters(src1, regT0, src2, regT1);
 
-    if (types.second().isReusable() && isSSE2Present()) {
+    if (types.second().isReusable() && supportsFloatingPoint()) {
         ASSERT(types.second().mightBeNumber());
 
         // Check op2 is a number
-        __ testl_i32r(JSImmediate::TagTypeNumber, X86::edx);
-        JmpSrc op2imm = __ jne();
+        Jump op2imm = emitJumpIfImmediateInteger(regT1);
         if (!types.second().definitelyIsNumber()) {
-            emitJumpSlowCaseIfNotJSCell(X86::edx, src2);
-            __ cmpl_im(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::edx);
-            addSlowCase(__ jne());
+            emitJumpSlowCaseIfNotJSCell(regT1, src2);
+            addSlowCase(checkStructure(regT1, numberStructure));
         }
 
         // (1) In this case src2 is a reusable number cell.
         //     Slow case if src1 is not a number type.
-        __ testl_i32r(JSImmediate::TagTypeNumber, X86::eax);
-        JmpSrc op1imm = __ jne();
+        Jump op1imm = emitJumpIfImmediateInteger(regT0);
         if (!types.first().definitelyIsNumber()) {
-            emitJumpSlowCaseIfNotJSCell(X86::eax, src1);
-            __ cmpl_im(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::eax);
-            addSlowCase(__ jne());
+            emitJumpSlowCaseIfNotJSCell(regT0, src1);
+            addSlowCase(checkStructure(regT0, numberStructure));
         }
 
         // (1a) if we get here, src1 is also a number cell
-        __ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
-        JmpSrc loadedDouble = __ jmp();
+        loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
+        Jump loadedDouble = jump();
         // (1b) if we get here, src1 is an immediate
-        __ link(op1imm, __ label());
-        emitFastArithImmToInt(X86::eax);
-        __ cvtsi2sd_rr(X86::eax, X86::xmm0);
+        op1imm.link(this);
+        emitFastArithImmToInt(regT0);
+        convertInt32ToDouble(regT0, fpRegT0);
         // (1c) 
-        __ link(loadedDouble, __ label());
+        loadedDouble.link(this);
         if (opcodeID == op_add)
-            __ addsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
+            addDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
         else if (opcodeID == op_sub)
-            __ subsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
+            subDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
         else {
             ASSERT(opcodeID == op_mul);
-            __ mulsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm0);
+            mulDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
         }
 
-        putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::edx, dst, &wasJSNumberCell2, X86::xmm1, X86::ecx, X86::eax);
-        wasJSNumberCell2b = __ jmp();
+        // Store the result to the JSNumberCell and jump.
+        storeDouble(fpRegT0, Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)));
+        move(regT1, regT0);
+        emitPutVirtualRegister(dst);
+        wasJSNumberCell2 = jump();
 
         // (2) This handles cases where src2 is an immediate number.
         //     Two slow cases - either src1 isn't an immediate, or the subtract overflows.
-        __ link(op2imm, __ label());
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-    } else if (types.first().isReusable() && isSSE2Present()) {
+        op2imm.link(this);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+    } else if (types.first().isReusable() && supportsFloatingPoint()) {
         ASSERT(types.first().mightBeNumber());
 
         // Check op1 is a number
-        __ testl_i32r(JSImmediate::TagTypeNumber, X86::eax);
-        JmpSrc op1imm = __ jne();
+        Jump op1imm = emitJumpIfImmediateInteger(regT0);
         if (!types.first().definitelyIsNumber()) {
-            emitJumpSlowCaseIfNotJSCell(X86::eax, src1);
-            __ cmpl_im(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::eax);
-            addSlowCase(__ jne());
+            emitJumpSlowCaseIfNotJSCell(regT0, src1);
+            addSlowCase(checkStructure(regT0, numberStructure));
         }
 
         // (1) In this case src1 is a reusable number cell.
         //     Slow case if src2 is not a number type.
-        __ testl_i32r(JSImmediate::TagTypeNumber, X86::edx);
-        JmpSrc op2imm = __ jne();
+        Jump op2imm = emitJumpIfImmediateInteger(regT1);
         if (!types.second().definitelyIsNumber()) {
-            emitJumpSlowCaseIfNotJSCell(X86::edx, src2);
-            __ cmpl_im(reinterpret_cast<unsigned>(numberStructure), FIELD_OFFSET(JSCell, m_structure), X86::edx);
-            addSlowCase(__ jne());
+            emitJumpSlowCaseIfNotJSCell(regT1, src2);
+            addSlowCase(checkStructure(regT1, numberStructure));
         }
 
         // (1a) if we get here, src2 is also a number cell
-        __ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::edx, X86::xmm1);
-        JmpSrc loadedDouble = __ jmp();
+        loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
+        Jump loadedDouble = jump();
         // (1b) if we get here, src2 is an immediate
-        __ link(op2imm, __ label());
-        emitFastArithImmToInt(X86::edx);
-        __ cvtsi2sd_rr(X86::edx, X86::xmm1);
+        op2imm.link(this);
+        emitFastArithImmToInt(regT1);
+        convertInt32ToDouble(regT1, fpRegT1);
         // (1c) 
-        __ link(loadedDouble, __ label());
-        __ movsd_mr(FIELD_OFFSET(JSNumberCell, m_value), X86::eax, X86::xmm0);
+        loadedDouble.link(this);
+        loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
         if (opcodeID == op_add)
-            __ addsd_rr(X86::xmm1, X86::xmm0);
+            addDouble(fpRegT1, fpRegT0);
         else if (opcodeID == op_sub)
-            __ subsd_rr(X86::xmm1, X86::xmm0);
+            subDouble(fpRegT1, fpRegT0);
         else {
             ASSERT(opcodeID == op_mul);
-            __ mulsd_rr(X86::xmm1, X86::xmm0);
+            mulDouble(fpRegT1, fpRegT0);
         }
-        __ movsd_rm(X86::xmm0, FIELD_OFFSET(JSNumberCell, m_value), X86::eax);
+        storeDouble(fpRegT0, Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)));
         emitPutVirtualRegister(dst);
 
-        putDoubleResultToJSNumberCellOrJSImmediate(X86::xmm0, X86::eax, dst, &wasJSNumberCell1, X86::xmm1, X86::ecx, X86::edx);
-        wasJSNumberCell1b = __ jmp();
+        // Store the result to the JSNumberCell and jump.
+        storeDouble(fpRegT0, Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)));
+        emitPutVirtualRegister(dst);
+        wasJSNumberCell1 = jump();
 
         // (2) This handles cases where src1 is an immediate number.
         //     Two slow cases - either src2 isn't an immediate, or the subtract overflows.
-        __ link(op1imm, __ label());
-        emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
+        op1imm.link(this);
+        emitJumpSlowCaseIfNotImmediateInteger(regT1);
     } else
-        emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
+        emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
 
     if (opcodeID == op_add) {
-        emitFastArithDeTagImmediate(X86::eax);
-        __ addl_rr(X86::edx, X86::eax);
-        addSlowCase(__ jo());
+        emitFastArithDeTagImmediate(regT0);
+        addSlowCase(branchAdd32(Overflow, regT1, regT0));
     } else  if (opcodeID == op_sub) {
-        __ subl_rr(X86::edx, X86::eax);
-        addSlowCase(__ jo());
-        signExtend32ToPtr(X86::eax, X86::eax);
-        emitFastArithReTagImmediate(X86::eax, X86::eax);
+        addSlowCase(branchSub32(Overflow, regT1, regT0));
+        signExtend32ToPtr(regT0, regT0);
+        emitFastArithReTagImmediate(regT0, regT0);
     } else {
         ASSERT(opcodeID == op_mul);
         // convert eax & edx from JSImmediates to ints, and check if either are zero
-        emitFastArithImmToInt(X86::edx);
-        JmpSrc op1Zero = emitFastArithDeTagImmediateJumpIfZero(X86::eax);
-        __ testl_rr(X86::edx, X86::edx);
-        JmpSrc op2NonZero = __ jne();
-        __ link(op1Zero, __ label());
+        emitFastArithImmToInt(regT1);
+        Jump op1Zero = emitFastArithDeTagImmediateJumpIfZero(regT0);
+        Jump op2NonZero = branchTest32(NonZero, regT1);
+        op1Zero.link(this);
         // if either input is zero, add the two together, and check if the result is < 0.
         // If it is, we have a problem (N < 0), (N * 0) == -0, not representatble as a JSImmediate. 
-        __ movl_rr(X86::eax, X86::ecx);
-        __ addl_rr(X86::edx, X86::ecx);
-        addSlowCase(__ js());
+        move(regT0, regT2);
+        addSlowCase(branchAdd32(Signed, regT1, regT2));
         // Skip the above check if neither input is zero
-        __ link(op2NonZero, __ label());
-        __ imull_rr(X86::edx, X86::eax);
-        addSlowCase(__ jo());
-        signExtend32ToPtr(X86::eax, X86::eax);
-        emitFastArithReTagImmediate(X86::eax, X86::eax);
+        op2NonZero.link(this);
+        addSlowCase(branchMul32(Overflow, regT1, regT0));
+        signExtend32ToPtr(regT0, regT0);
+        emitFastArithReTagImmediate(regT0, regT0);
     }
     emitPutVirtualRegister(dst);
 
-    if (types.second().isReusable() && isSSE2Present()) {
-        __ link(wasJSNumberCell2, __ label());
-        __ link(wasJSNumberCell2b, __ label());
-    }
-    else if (types.first().isReusable() && isSSE2Present()) {
-        __ link(wasJSNumberCell1, __ label());
-        __ link(wasJSNumberCell1b, __ label());
-    }
+    if (types.second().isReusable() && supportsFloatingPoint())
+        wasJSNumberCell2.link(this);
+    else if (types.first().isReusable() && supportsFloatingPoint())
+        wasJSNumberCell1.link(this);
 }
 
 void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned dst, unsigned src1, unsigned src2, OperandTypes types)
 {
     linkSlowCase(iter);
-    if (types.second().isReusable() && isSSE2Present()) {
+    if (types.second().isReusable() && supportsFloatingPoint()) {
         if (!types.first().definitelyIsNumber()) {
             linkSlowCaseIfNotJSCell(iter, src1);
             linkSlowCase(iter);
@@ -822,7 +2256,7 @@ void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>:
             linkSlowCaseIfNotJSCell(iter, src2);
             linkSlowCase(iter);
         }
-    } else if (types.first().isReusable() && isSSE2Present()) {
+    } else if (types.first().isReusable() && supportsFloatingPoint()) {
         if (!types.first().definitelyIsNumber()) {
             linkSlowCaseIfNotJSCell(iter, src1);
             linkSlowCase(iter);
@@ -838,50 +2272,44 @@ void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>:
     if (opcodeID == op_mul)
         linkSlowCase(iter);
 
-    emitPutJITStubArgFromVirtualRegister(src1, 1, X86::ecx);
-    emitPutJITStubArgFromVirtualRegister(src2, 2, X86::ecx);
-    if (opcodeID == op_add)
-        emitCTICall(Interpreter::cti_op_add);
-    else if (opcodeID == op_sub)
-        emitCTICall(Interpreter::cti_op_sub);
-    else {
-        ASSERT(opcodeID == op_mul);
-        emitCTICall(Interpreter::cti_op_mul);
-    }
-    emitPutVirtualRegister(dst);
+    JITStubCall stubCall(this, opcodeID == op_add ? cti_op_add : opcodeID == op_sub ? cti_op_sub : cti_op_mul);
+    stubCall.addArgument(src1, regT2);
+    stubCall.addArgument(src2, regT2);
+    stubCall.call(dst);
 }
 
-void JIT::compileFastArith_op_add(Instruction* currentInstruction)
+void JIT::emit_op_add(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
     unsigned op2 = currentInstruction[3].u.operand;
 
     if (isOperandConstantImmediateInt(op1)) {
-        emitGetVirtualRegister(op2, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax));
-        signExtend32ToPtr(X86::eax, X86::eax);
+        emitGetVirtualRegister(op2, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), regT0));
+        signExtend32ToPtr(regT0, regT0);
         emitPutVirtualRegister(result);
     } else if (isOperandConstantImmediateInt(op2)) {
-        emitGetVirtualRegister(op1, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax));
-        signExtend32ToPtr(X86::eax, X86::eax);
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), regT0));
+        signExtend32ToPtr(regT0, regT0);
         emitPutVirtualRegister(result);
     } else {
         OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
         if (types.first().mightBeNumber() && types.second().mightBeNumber())
             compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
         else {
-            emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-            emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-            emitCTICall(Interpreter::cti_op_add);
-            emitPutVirtualRegister(result);
+            JITStubCall stubCall(this, cti_op_add);
+            stubCall.addArgument(op1, regT2);
+            stubCall.addArgument(op2, regT2);
+            stubCall.call(result);
         }
     }
 }
-void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
@@ -890,21 +2318,21 @@ void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<Sl
     if (isOperandConstantImmediateInt(op1)) {
         Jump notImm = getSlowCase(iter);
         linkSlowCase(iter);
-        sub32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax);
+        sub32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), regT0);
         notImm.link(this);
-        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-        emitPutJITStubArg(X86::eax, 2);
-        emitCTICall(Interpreter::cti_op_add);
-        emitPutVirtualRegister(result);
+        JITStubCall stubCall(this, cti_op_add);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(regT0);
+        stubCall.call(result);
     } else if (isOperandConstantImmediateInt(op2)) {
         Jump notImm = getSlowCase(iter);
         linkSlowCase(iter);
-        sub32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax);
+        sub32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), regT0);
         notImm.link(this);
-        emitPutJITStubArg(X86::eax, 1);
-        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-        emitCTICall(Interpreter::cti_op_add);
-        emitPutVirtualRegister(result);
+        JITStubCall stubCall(this, cti_op_add);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(op2, regT2);
+        stubCall.call(result);
     } else {
         OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
         ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber());
@@ -912,7 +2340,7 @@ void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<Sl
     }
 }
 
-void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
+void JIT::emit_op_mul(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
@@ -921,25 +2349,26 @@ void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
     // For now, only plant a fast int case if the constant operand is greater than zero.
     int32_t value;
     if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
-        emitGetVirtualRegister(op2, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        emitFastArithDeTagImmediate(X86::eax);
-        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
-        signExtend32ToPtr(X86::eax, X86::eax);
-        emitFastArithReTagImmediate(X86::eax, X86::eax);
+        emitGetVirtualRegister(op2, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        emitFastArithDeTagImmediate(regT0);
+        addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
+        signExtend32ToPtr(regT0, regT0);
+        emitFastArithReTagImmediate(regT0, regT0);
         emitPutVirtualRegister(result);
     } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
-        emitGetVirtualRegister(op1, X86::eax);
-        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
-        emitFastArithDeTagImmediate(X86::eax);
-        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
-        signExtend32ToPtr(X86::eax, X86::eax);
-        emitFastArithReTagImmediate(X86::eax, X86::eax);
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        emitFastArithDeTagImmediate(regT0);
+        addSlowCase(branchMul32(Overflow, Imm32(value), regT0, regT0));
+        signExtend32ToPtr(regT0, regT0);
+        emitFastArithReTagImmediate(regT0, regT0);
         emitPutVirtualRegister(result);
     } else
         compileBinaryArithOp(op_mul, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
 }
-void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     unsigned result = currentInstruction[1].u.operand;
     unsigned op1 = currentInstruction[2].u.operand;
@@ -950,24 +2379,29 @@ void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<Sl
         linkSlowCase(iter);
         linkSlowCase(iter);
         // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
-        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
-        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
-        emitCTICall(Interpreter::cti_op_mul);
-        emitPutVirtualRegister(result);
+        JITStubCall stubCall(this, cti_op_mul);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(op2, regT2);
+        stubCall.call(result);
     } else
         compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
 }
 
-void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
+void JIT::emit_op_sub(Instruction* currentInstruction)
 {
     compileBinaryArithOp(op_sub, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
 }
-void JIT::compileFastArithSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+
+void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     compileBinaryArithOpSlowCase(op_sub, iter, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
 }
 
-#endif
+#endif // USE(JSVALUE64)
+
+/* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */
+
+#endif // USE(JSVALUE32_64)
 
 } // namespace JSC
 
index af267123698ba4c7ea4088aa4e7c441f66ff2bf5..fb1f2e1e34f13a16d29719b3acd8a2439715614c 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "CodeBlock.h"
 #include "JITInlineMethods.h"
+#include "JITStubCall.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "Interpreter.h"
@@ -44,40 +45,405 @@ using namespace std;
 
 namespace JSC {
 
-void JIT::unlinkCall(CallLinkInfo* callLinkInfo)
+#if USE(JSVALUE32_64)
+
+void JIT::compileOpCallInitializeCallFrame()
+{
+    // regT0 holds callee, regT1 holds argCount
+    store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // scopeChain
+
+    emitStore(static_cast<unsigned>(RegisterFile::OptionalCalleeArguments), JSValue());
+    storePtr(regT0, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register)))); // callee
+    storePtr(regT1, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register)))); // scopeChain
+}
+
+void JIT::compileOpCallSetupArgs(Instruction* instruction)
+{
+    int argCount = instruction[3].u.operand;
+    int registerOffset = instruction[4].u.operand;
+
+    emitPutJITStubArg(regT0, 1);
+    emitPutJITStubArg(regT1, 2);
+    emitPutJITStubArgConstant(registerOffset, 3);
+    emitPutJITStubArgConstant(argCount, 5);
+}
+          
+void JIT::compileOpConstructSetupArgs(Instruction* instruction)
+{
+    int argCount = instruction[3].u.operand;
+    int registerOffset = instruction[4].u.operand;
+    int proto = instruction[5].u.operand;
+    int thisRegister = instruction[6].u.operand;
+
+    emitPutJITStubArg(regT0, 1);
+    emitPutJITStubArg(regT1, 2);
+    emitPutJITStubArgConstant(registerOffset, 3);
+    emitPutJITStubArgConstant(argCount, 5);
+    emitPutJITStubArgFromVirtualRegister(proto, 7, regT2, regT3);
+    emitPutJITStubArgConstant(thisRegister, 9);
+}
+
+void JIT::compileOpCallVarargsSetupArgs(Instruction*)
 {
-    // When the JSFunction is deleted the pointer embedded in the instruction stream will no longer be valid
-    // (and, if a new JSFunction happened to be constructed at the same location, we could get a false positive
-    // match).  Reset the check so it no longer matches.
-    DataLabelPtr::patch(callLinkInfo->hotPathBegin, JSValuePtr::encode(jsImpossibleValue()));
+    emitPutJITStubArg(regT0, 1);
+    emitPutJITStubArg(regT1, 2);
+    emitPutJITStubArg(regT3, 3); // registerOffset
+    emitPutJITStubArg(regT2, 5); // argCount
 }
 
-void JIT::linkCall(JSFunction* callee, CodeBlock* calleeCodeBlock, void* ctiCode, CallLinkInfo* callLinkInfo, int callerArgCount)
+void JIT::compileOpCallVarargs(Instruction* instruction)
 {
-    // Currently we only link calls with the exact number of arguments.
-    if (callerArgCount == calleeCodeBlock->m_numParameters) {
-        ASSERT(!callLinkInfo->isLinked());
+    int dst = instruction[1].u.operand;
+    int callee = instruction[2].u.operand;
+    int argCountRegister = instruction[3].u.operand;
+    int registerOffset = instruction[4].u.operand;
+
+    emitLoad(callee, regT1, regT0);
+    emitLoadPayload(argCountRegister, regT2); // argCount
+    addPtr(Imm32(registerOffset), regT2, regT3); // registerOffset
+
+    compileOpCallVarargsSetupArgs(instruction);
+
+    emitJumpSlowCaseIfNotJSCell(callee, regT1);
+    addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr)));
+
+    // Speculatively roll the callframe, assuming argCount will match the arity.
+    mul32(Imm32(sizeof(Register)), regT3, regT3);
+    addPtr(callFrameRegister, regT3);
+    storePtr(callFrameRegister, Address(regT3, RegisterFile::CallerFrame * static_cast<int>(sizeof(Register))));
+    move(regT3, callFrameRegister);
+
+    move(regT2, regT1); // argCount
+
+    emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
+
+    emitStore(dst, regT1, regT0);
     
-        calleeCodeBlock->addCaller(callLinkInfo);
+    sampleCodeBlock(m_codeBlock);
+}
+
+void JIT::compileOpCallVarargsSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    int dst = instruction[1].u.operand;
+    int callee = instruction[2].u.operand;
+
+    linkSlowCaseIfNotJSCell(iter, callee);
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_call_NotJSFunction);
+    stubCall.call(dst); // In the interpreter, the callee puts the return value in dst.
+
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_call_varargs), dst, regT1, regT0);
+    sampleCodeBlock(m_codeBlock);
+}
+
+void JIT::emit_op_ret(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+
+    // We could JIT generate the deref, only calling out to C when the refcount hits zero.
+    if (m_codeBlock->needsFullScopeChain())
+        JITStubCall(this, cti_op_ret_scopeChain).call();
+
+    emitLoad(dst, regT1, regT0);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT2);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
+
+    restoreReturnAddressBeforeReturn(regT2);
+    ret();
+}
+
+void JIT::emit_op_construct_verify(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+
+    emitLoad(dst, regT1, regT0);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    addSlowCase(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType)));
+}
+
+void JIT::emitSlow_op_construct_verify(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src = currentInstruction[2].u.operand;
+
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    emitLoad(src, regT1, regT0);
+    emitStore(dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    compileOpCallSlowCase(currentInstruction, iter, m_callLinkInfoIndex++, op_call);
+}
+
+void JIT::emitSlow_op_call_eval(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    compileOpCallSlowCase(currentInstruction, iter, m_callLinkInfoIndex++, op_call_eval);
+}
+
+void JIT::emitSlow_op_call_varargs(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    compileOpCallVarargsSlowCase(currentInstruction, iter);
+}
+
+void JIT::emitSlow_op_construct(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    compileOpCallSlowCase(currentInstruction, iter, m_callLinkInfoIndex++, op_construct);
+}
+
+void JIT::emit_op_call(Instruction* currentInstruction)
+{
+    compileOpCall(op_call, currentInstruction, m_callLinkInfoIndex++);
+}
+
+void JIT::emit_op_call_eval(Instruction* currentInstruction)
+{
+    compileOpCall(op_call_eval, currentInstruction, m_callLinkInfoIndex++);
+}
+
+void JIT::emit_op_load_varargs(Instruction* currentInstruction)
+{
+    int argCountDst = currentInstruction[1].u.operand;
+    int argsOffset = currentInstruction[2].u.operand;
+
+    JITStubCall stubCall(this, cti_op_load_varargs);
+    stubCall.addArgument(Imm32(argsOffset));
+    stubCall.call();
+    // Stores a naked int32 in the register file.
+    store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register)));
+}
+
+void JIT::emit_op_call_varargs(Instruction* currentInstruction)
+{
+    compileOpCallVarargs(currentInstruction);
+}
+
+void JIT::emit_op_construct(Instruction* currentInstruction)
+{
+    compileOpCall(op_construct, currentInstruction, m_callLinkInfoIndex++);
+}
+
+#if !ENABLE(JIT_OPTIMIZE_CALL)
+
+/* ------------------------------ BEGIN: !ENABLE(JIT_OPTIMIZE_CALL) ------------------------------ */
+
+void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
+{
+    int dst = instruction[1].u.operand;
+    int callee = instruction[2].u.operand;
+    int argCount = instruction[3].u.operand;
+    int registerOffset = instruction[4].u.operand;
+
+    Jump wasEval1;
+    Jump wasEval2;
+    if (opcodeID == op_call_eval) {
+        JITStubCall stubCall(this, cti_op_call_eval);
+        stubCall.addArgument(callee);
+        stubCall.addArgument(JIT::Imm32(registerOffset));
+        stubCall.addArgument(JIT::Imm32(argCount));
+        stubCall.call();
+        wasEval1 = branchTest32(NonZero, regT0);
+        wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+    }
+
+    emitLoad(callee, regT1, regT2);
+
+    if (opcodeID == op_call)
+        compileOpCallSetupArgs(instruction);
+    else if (opcodeID == op_construct)
+        compileOpConstructSetupArgs(instruction);
+
+    emitJumpSlowCaseIfNotJSCell(callee, regT1);
+    addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr)));
+
+    // First, in the case of a construct, allocate the new object.
+    if (opcodeID == op_construct) {
+        JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
+        emitLoad(callee, regT1, regT2);
+    }
+
+    // Speculatively roll the callframe, assuming argCount will match the arity.
+    storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
+    addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
+    move(Imm32(argCount), regT1);
+
+    emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
+
+    if (opcodeID == op_call_eval) {
+        wasEval1.link(this);
+        wasEval2.link(this);
+    }
+
+    emitStore(dst, regT1, regT0);;
+
+    sampleCodeBlock(m_codeBlock);
+}
+
+void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned, OpcodeID opcodeID)
+{
+    int dst = instruction[1].u.operand;
+    int callee = instruction[2].u.operand;
+
+    linkSlowCaseIfNotJSCell(iter, callee);
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, opcodeID == op_construct ? cti_op_construct_NotJSConstruct : cti_op_call_NotJSFunction);
+    stubCall.call(dst); // In the interpreter, the callee puts the return value in dst.
+
+    sampleCodeBlock(m_codeBlock);
+}
+
+#else // !ENABLE(JIT_OPTIMIZE_CALL)
+
+/* ------------------------------ BEGIN: ENABLE(JIT_OPTIMIZE_CALL) ------------------------------ */
+
+void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned callLinkInfoIndex)
+{
+    int dst = instruction[1].u.operand;
+    int callee = instruction[2].u.operand;
+    int argCount = instruction[3].u.operand;
+    int registerOffset = instruction[4].u.operand;
+
+    Jump wasEval1;
+    Jump wasEval2;
+    if (opcodeID == op_call_eval) {
+        JITStubCall stubCall(this, cti_op_call_eval);
+        stubCall.addArgument(callee);
+        stubCall.addArgument(JIT::Imm32(registerOffset));
+        stubCall.addArgument(JIT::Imm32(argCount));
+        stubCall.call();
+        wasEval1 = branchTest32(NonZero, regT0);
+        wasEval2 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+    }
+
+    emitLoad(callee, regT1, regT0);
+
+    DataLabelPtr addressOfLinkedFunctionCheck;
+    Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT0, addressOfLinkedFunctionCheck, ImmPtr(0));
+    addSlowCase(jumpToSlow);
+    ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump);
+    m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
+
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+
+    // The following is the fast case, only used whan a callee can be linked.
+
+    // In the case of OpConstruct, call out to a cti_ function to create the new object.
+    if (opcodeID == op_construct) {
+        int proto = instruction[5].u.operand;
+        int thisRegister = instruction[6].u.operand;
+
+        JITStubCall stubCall(this, cti_op_construct_JSConstruct);
+        stubCall.addArgument(regT1, regT0);
+        stubCall.addArgument(Imm32(0)); // FIXME: Remove this unused JITStub argument.
+        stubCall.addArgument(Imm32(0)); // FIXME: Remove this unused JITStub argument.
+        stubCall.addArgument(proto);
+        stubCall.call(thisRegister);
+
+        emitLoad(callee, regT1, regT0);
+    }
+
+    // Fast version of stack frame initialization, directly relative to edi.
+    // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
+    emitStore(registerOffset + RegisterFile::OptionalCalleeArguments, JSValue());
+    emitStore(registerOffset + RegisterFile::Callee, regT1, regT0);
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain
+    store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register))));
+    storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register))));
+    storePtr(regT1, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
+    addPtr(Imm32(registerOffset * sizeof(Register)), callFrameRegister);
+
+    // Call to the callee
+    m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall();
     
-        DataLabelPtr::patch(callLinkInfo->hotPathBegin, callee);
-        Jump::patch(callLinkInfo->hotPathOther, ctiCode);
+    if (opcodeID == op_call_eval) {
+        wasEval1.link(this);
+        wasEval2.link(this);
     }
 
-    // patch the instruction that jumps out to the cold path, so that we only try to link once.
-    void* patchCheck = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(callLinkInfo->hotPathBegin) + patchOffsetOpCallCompareToJump);
-    Jump::patch(patchCheck, callLinkInfo->coldPathOther);
+    // Put the return value in dst. In the interpreter, op_ret does this.
+    emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + opcodeLengths[opcodeID], dst, regT1, regT0);
+
+    sampleCodeBlock(m_codeBlock);
+}
+
+void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter, unsigned callLinkInfoIndex, OpcodeID opcodeID)
+{
+    int dst = instruction[1].u.operand;
+    int callee = instruction[2].u.operand;
+    int argCount = instruction[3].u.operand;
+    int registerOffset = instruction[4].u.operand;
+
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+
+    // The arguments have been set up on the hot path for op_call_eval
+    if (opcodeID == op_call)
+        compileOpCallSetupArgs(instruction);
+    else if (opcodeID == op_construct)
+        compileOpConstructSetupArgs(instruction);
+
+    // Fast check for JS function.
+    Jump callLinkFailNotObject = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+    Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsFunctionVPtr));
+
+    // First, in the case of a construct, allocate the new object.
+    if (opcodeID == op_construct) {
+        JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
+        emitLoad(callee, regT1, regT0);
+    }
+
+    // Speculatively roll the callframe, assuming argCount will match the arity.
+    storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
+    addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
+    move(Imm32(argCount), regT1);
+
+    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallPreLink());
+
+    // Put the return value in dst.
+    emitStore(dst, regT1, regT0);;
+    sampleCodeBlock(m_codeBlock);
+
+    // If not, we need an extra case in the if below!
+    ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_eval));
+
+    // Done! - return back to the hot path.
+    if (opcodeID == op_construct)
+        emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_construct));
+    else
+        emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_call));
+
+    // This handles host functions
+    callLinkFailNotObject.link(this);
+    callLinkFailNotJSFunction.link(this);
+    JITStubCall(this, opcodeID == op_construct ? cti_op_construct_NotJSConstruct : cti_op_call_NotJSFunction).call();
+
+    emitStore(dst, regT1, regT0);;
+    sampleCodeBlock(m_codeBlock);
 }
 
+/* ------------------------------ END: !ENABLE / ENABLE(JIT_OPTIMIZE_CALL) ------------------------------ */
+
+#endif // !ENABLE(JIT_OPTIMIZE_CALL)
+
+#else // USE(JSVALUE32_64)
+
 void JIT::compileOpCallInitializeCallFrame()
 {
-    store32(X86::edx, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
+    store32(regT1, Address(callFrameRegister, RegisterFile::ArgumentCount * static_cast<int>(sizeof(Register))));
 
-    loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), X86::edx); // newScopeChain
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain
 
-    storePtr(ImmPtr(JSValuePtr::encode(noValue())), Address(callFrameRegister, RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register))));
-    storePtr(X86::ecx, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));
-    storePtr(X86::edx, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register))));
+    storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register))));
+    storePtr(regT2, Address(callFrameRegister, RegisterFile::Callee * static_cast<int>(sizeof(Register))));
+    storePtr(regT1, Address(callFrameRegister, RegisterFile::ScopeChain * static_cast<int>(sizeof(Register))));
 }
 
 void JIT::compileOpCallSetupArgs(Instruction* instruction)
@@ -86,20 +452,20 @@ void JIT::compileOpCallSetupArgs(Instruction* instruction)
     int registerOffset = instruction[4].u.operand;
 
     // ecx holds func
-    emitPutJITStubArg(X86::ecx, 1);
-    emitPutJITStubArgConstant(registerOffset, 2);
+    emitPutJITStubArg(regT2, 1);
     emitPutJITStubArgConstant(argCount, 3);
+    emitPutJITStubArgConstant(registerOffset, 2);
 }
-
-void JIT::compileOpCallEvalSetupArgs(Instruction* instruction)
+          
+void JIT::compileOpCallVarargsSetupArgs(Instruction* instruction)
 {
-    int argCount = instruction[3].u.operand;
     int registerOffset = instruction[4].u.operand;
-
+    
     // ecx holds func
-    emitPutJITStubArg(X86::ecx, 1);
-    emitPutJITStubArgConstant(registerOffset, 2);
-    emitPutJITStubArgConstant(argCount, 3);
+    emitPutJITStubArg(regT2, 1);
+    emitPutJITStubArg(regT1, 3);
+    addPtr(Imm32(registerOffset), regT1, regT0);
+    emitPutJITStubArg(regT0, 2);
 }
 
 void JIT::compileOpConstructSetupArgs(Instruction* instruction)
@@ -110,15 +476,58 @@ void JIT::compileOpConstructSetupArgs(Instruction* instruction)
     int thisRegister = instruction[6].u.operand;
 
     // ecx holds func
-    emitPutJITStubArg(X86::ecx, 1);
+    emitPutJITStubArg(regT2, 1);
     emitPutJITStubArgConstant(registerOffset, 2);
     emitPutJITStubArgConstant(argCount, 3);
-    emitPutJITStubArgFromVirtualRegister(proto, 4, X86::eax);
+    emitPutJITStubArgFromVirtualRegister(proto, 4, regT0);
     emitPutJITStubArgConstant(thisRegister, 5);
 }
 
+void JIT::compileOpCallVarargs(Instruction* instruction)
+{
+    int dst = instruction[1].u.operand;
+    int callee = instruction[2].u.operand;
+    int argCountRegister = instruction[3].u.operand;
+
+    emitGetVirtualRegister(argCountRegister, regT1);
+    emitGetVirtualRegister(callee, regT2);
+    compileOpCallVarargsSetupArgs(instruction);
+
+    // Check for JSFunctions.
+    emitJumpSlowCaseIfNotJSCell(regT2);
+    addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr)));
+    
+    // Speculatively roll the callframe, assuming argCount will match the arity.
+    mul32(Imm32(sizeof(Register)), regT0, regT0);
+    intptr_t offset = (intptr_t)sizeof(Register) * (intptr_t)RegisterFile::CallerFrame;
+    addPtr(Imm32((int32_t)offset), regT0, regT3);
+    addPtr(callFrameRegister, regT3);
+    storePtr(callFrameRegister, regT3);
+    addPtr(regT0, callFrameRegister);
+    emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
+
+    // Put the return value in dst. In the interpreter, op_ret does this.
+    emitPutVirtualRegister(dst);
+    
+    sampleCodeBlock(m_codeBlock);
+}
+
+void JIT::compileOpCallVarargsSlowCase(Instruction* instruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    int dst = instruction[1].u.operand;
+    
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_call_NotJSFunction);
+    stubCall.call(dst); // In the interpreter, the callee puts the return value in dst.
+    
+    sampleCodeBlock(m_codeBlock);
+}
+    
 #if !ENABLE(JIT_OPTIMIZE_CALL)
 
+/* ------------------------------ BEGIN: !ENABLE(JIT_OPTIMIZE_CALL) ------------------------------ */
+
 void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
 {
     int dst = instruction[1].u.operand;
@@ -129,14 +538,15 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
     // Handle eval
     Jump wasEval;
     if (opcodeID == op_call_eval) {
-        emitGetVirtualRegister(callee, X86::ecx);
-        compileOpCallEvalSetupArgs(instruction);
-
-        emitCTICall(Interpreter::cti_op_call_eval);
-        wasEval = jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
+        JITStubCall stubCall(this, cti_op_call_eval);
+        stubCall.addArgument(callee, regT2);
+        stubCall.addArgument(JIT::Imm32(registerOffset));
+        stubCall.addArgument(JIT::Imm32(argCount));
+        stubCall.call();
+        wasEval = branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue())));
     }
 
-    emitGetVirtualRegister(callee, X86::ecx);
+    emitGetVirtualRegister(callee, regT2);
     // The arguments have been set up on the hot path for op_call_eval
     if (opcodeID == op_call)
         compileOpCallSetupArgs(instruction);
@@ -144,22 +554,21 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned)
         compileOpConstructSetupArgs(instruction);
 
     // Check for JSFunctions.
-    emitJumpSlowCaseIfNotJSCell(X86::ecx);
-    addSlowCase(jnePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr)));
+    emitJumpSlowCaseIfNotJSCell(regT2);
+    addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr)));
 
     // First, in the case of a construct, allocate the new object.
     if (opcodeID == op_construct) {
-        emitCTICall(Interpreter::cti_op_construct_JSConstruct);
-        emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
-        emitGetVirtualRegister(callee, X86::ecx);
+        JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
+        emitGetVirtualRegister(callee, regT2);
     }
 
     // Speculatively roll the callframe, assuming argCount will match the arity.
     storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
     addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
-    move(Imm32(argCount), X86::edx);
+    move(Imm32(argCount), regT1);
 
-    emitNakedCall(m_interpreter->m_ctiVirtualCall);
+    emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
 
     if (opcodeID == op_call_eval)
         wasEval.link(this);
@@ -176,22 +585,15 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
 
     linkSlowCase(iter);
     linkSlowCase(iter);
-
-    // This handles host functions
-    emitCTICall(((opcodeID == op_construct) ? Interpreter::cti_op_construct_NotJSConstruct : Interpreter::cti_op_call_NotJSFunction));
-    // Put the return value in dst. In the interpreter, op_ret does this.
-    emitPutVirtualRegister(dst);
+    JITStubCall stubCall(this, opcodeID == op_construct ? cti_op_construct_NotJSConstruct : cti_op_call_NotJSFunction);
+    stubCall.call(dst); // In the interpreter, the callee puts the return value in dst.
 
     sampleCodeBlock(m_codeBlock);
 }
 
-#else
+#else // !ENABLE(JIT_OPTIMIZE_CALL)
 
-static NO_RETURN void unreachable()
-{
-    ASSERT_NOT_REACHED();
-    exit(1);
-}
+/* ------------------------------ BEGIN: ENABLE(JIT_OPTIMIZE_CALL) ------------------------------ */
 
 void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned callLinkInfoIndex)
 {
@@ -203,18 +605,19 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
     // Handle eval
     Jump wasEval;
     if (opcodeID == op_call_eval) {
-        emitGetVirtualRegister(callee, X86::ecx);
-        compileOpCallEvalSetupArgs(instruction);
-
-        emitCTICall(Interpreter::cti_op_call_eval);
-        wasEval = jnePtr(X86::eax, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
+        JITStubCall stubCall(this, cti_op_call_eval);
+        stubCall.addArgument(callee, regT2);
+        stubCall.addArgument(JIT::Imm32(registerOffset));
+        stubCall.addArgument(JIT::Imm32(argCount));
+        stubCall.call();
+        wasEval = branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue())));
     }
 
     // This plants a check for a cached JSFunction value, so we can plant a fast link to the callee.
     // This deliberately leaves the callee in ecx, used when setting up the stack frame below
-    emitGetVirtualRegister(callee, X86::ecx);
+    emitGetVirtualRegister(callee, regT2);
     DataLabelPtr addressOfLinkedFunctionCheck;
-    Jump jumpToSlow = jnePtrWithPatch(X86::ecx, addressOfLinkedFunctionCheck, ImmPtr(JSValuePtr::encode(jsImpossibleValue())));
+    Jump jumpToSlow = branchPtrWithPatch(NotEqual, regT2, addressOfLinkedFunctionCheck, ImmPtr(JSValue::encode(JSValue())));
     addSlowCase(jumpToSlow);
     ASSERT(differenceBetween(addressOfLinkedFunctionCheck, jumpToSlow) == patchOffsetOpCallCompareToJump);
     m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = addressOfLinkedFunctionCheck;
@@ -226,25 +629,25 @@ void JIT::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned ca
         int proto = instruction[5].u.operand;
         int thisRegister = instruction[6].u.operand;
 
-        emitPutJITStubArg(X86::ecx, 1);
-        emitPutJITStubArgFromVirtualRegister(proto, 4, X86::eax);
-        emitCTICall(Interpreter::cti_op_construct_JSConstruct);
-        emitPutVirtualRegister(thisRegister);
-        emitGetVirtualRegister(callee, X86::ecx);
+        emitPutJITStubArg(regT2, 1);
+        emitPutJITStubArgFromVirtualRegister(proto, 4, regT0);
+        JITStubCall stubCall(this, cti_op_construct_JSConstruct);
+        stubCall.call(thisRegister);
+        emitGetVirtualRegister(callee, regT2);
     }
 
     // Fast version of stack frame initialization, directly relative to edi.
     // Note that this omits to set up RegisterFile::CodeBlock, which is set in the callee
-    storePtr(ImmPtr(JSValuePtr::encode(noValue())), Address(callFrameRegister, (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register))));
-    storePtr(X86::ecx, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));
-    loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_scopeChain) + FIELD_OFFSET(ScopeChain, m_node)), X86::edx); // newScopeChain
+    storePtr(ImmPtr(JSValue::encode(JSValue())), Address(callFrameRegister, (registerOffset + RegisterFile::OptionalCalleeArguments) * static_cast<int>(sizeof(Register))));
+    storePtr(regT2, Address(callFrameRegister, (registerOffset + RegisterFile::Callee) * static_cast<int>(sizeof(Register))));
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data) + OBJECT_OFFSETOF(ScopeChain, m_node)), regT1); // newScopeChain
     store32(Imm32(argCount), Address(callFrameRegister, (registerOffset + RegisterFile::ArgumentCount) * static_cast<int>(sizeof(Register))));
     storePtr(callFrameRegister, Address(callFrameRegister, (registerOffset + RegisterFile::CallerFrame) * static_cast<int>(sizeof(Register))));
-    storePtr(X86::edx, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
+    storePtr(regT1, Address(callFrameRegister, (registerOffset + RegisterFile::ScopeChain) * static_cast<int>(sizeof(Register))));
     addPtr(Imm32(registerOffset * sizeof(Register)), callFrameRegister);
 
     // Call to the callee
-    m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall(reinterpret_cast<void*>(unreachable));
+    m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathOther = emitNakedCall();
     
     if (opcodeID == op_call_eval)
         wasEval.link(this);
@@ -271,74 +674,49 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
         compileOpConstructSetupArgs(instruction);
 
     // Fast check for JS function.
-    Jump callLinkFailNotObject = emitJumpIfNotJSCell(X86::ecx);
-    Jump callLinkFailNotJSFunction = jnePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr));
+    Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT2);
+    Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunctionVPtr));
 
     // First, in the case of a construct, allocate the new object.
     if (opcodeID == op_construct) {
-        emitCTICall(Interpreter::cti_op_construct_JSConstruct);
-        emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
-        emitGetVirtualRegister(callee, X86::ecx);
+        JITStubCall(this, cti_op_construct_JSConstruct).call(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
+        emitGetVirtualRegister(callee, regT2);
     }
 
-    move(Imm32(argCount), X86::edx);
-
     // Speculatively roll the callframe, assuming argCount will match the arity.
     storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
     addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
+    move(Imm32(argCount), regT1);
 
-    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation =
-        emitNakedCall(m_interpreter->m_ctiVirtualCallPreLink);
+    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallPreLink());
 
-    Jump storeResultForFirstRun = jump();
+    // Put the return value in dst.
+    emitPutVirtualRegister(dst);
+    sampleCodeBlock(m_codeBlock);
 
-// FIXME: this label can be removed, since it is a fixed offset from 'callReturnLocation'.
-    // This is the address for the cold path *after* the first run (which tries to link the call).
-    m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = MacroAssembler::Label(this);
+    // If not, we need an extra case in the if below!
+    ASSERT(OPCODE_LENGTH(op_call) == OPCODE_LENGTH(op_call_eval));
 
-    // The arguments have been set up on the hot path for op_call_eval
-    if (opcodeID == op_call)
-        compileOpCallSetupArgs(instruction);
-    else if (opcodeID == op_construct)
-        compileOpConstructSetupArgs(instruction);
-
-    // Check for JSFunctions.
-    Jump isNotObject = emitJumpIfNotJSCell(X86::ecx);
-    Jump isJSFunction = jePtr(Address(X86::ecx), ImmPtr(m_interpreter->m_jsFunctionVptr));
+    // Done! - return back to the hot path.
+    if (opcodeID == op_construct)
+        emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_construct));
+    else
+        emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_call));
 
     // This handles host functions
-    isNotObject.link(this);
     callLinkFailNotObject.link(this);
     callLinkFailNotJSFunction.link(this);
-    emitCTICall(((opcodeID == op_construct) ? Interpreter::cti_op_construct_NotJSConstruct : Interpreter::cti_op_call_NotJSFunction));
-    Jump wasNotJSFunction = jump();
-
-    // Next, handle JSFunctions...
-    isJSFunction.link(this);
+    JITStubCall(this, opcodeID == op_construct ? cti_op_construct_NotJSConstruct : cti_op_call_NotJSFunction).call();
 
-    // First, in the case of a construct, allocate the new object.
-    if (opcodeID == op_construct) {
-        emitCTICall(Interpreter::cti_op_construct_JSConstruct);
-        emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
-        emitGetVirtualRegister(callee, X86::ecx);
-    }
-
-    // Speculatively roll the callframe, assuming argCount will match the arity.
-    storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::CallerFrame + registerOffset) * static_cast<int>(sizeof(Register))));
-    addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
-    move(Imm32(argCount), X86::edx);
-
-    emitNakedCall(m_interpreter->m_ctiVirtualCall);
-
-    // Put the return value in dst. In the interpreter, op_ret does this.
-    wasNotJSFunction.link(this);
-    storeResultForFirstRun.link(this);
     emitPutVirtualRegister(dst);
-
     sampleCodeBlock(m_codeBlock);
 }
 
-#endif
+/* ------------------------------ END: !ENABLE / ENABLE(JIT_OPTIMIZE_CALL) ------------------------------ */
+
+#endif // !ENABLE(JIT_OPTIMIZE_CALL)
+
+#endif // USE(JSVALUE32_64)
 
 } // namespace JSC
 
diff --git a/jit/JITCode.h b/jit/JITCode.h
new file mode 100644 (file)
index 0000000..b502c8a
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JITCode_h
+#define JITCode_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(JIT)
+
+#include "CallFrame.h"
+#include "JSValue.h"
+#include "MacroAssemblerCodeRef.h"
+#include "Profiler.h"
+
+namespace JSC {
+
+    class JSGlobalData;
+    class RegisterFile;
+
+    class JITCode {
+        typedef MacroAssemblerCodeRef CodeRef;
+        typedef MacroAssemblerCodePtr CodePtr;
+    public:
+        JITCode()
+        {
+        }
+
+        JITCode(const CodeRef ref)
+            : m_ref(ref)
+        {
+        }
+
+        bool operator !() const
+        {
+            return !m_ref.m_code.executableAddress();
+        }
+
+        CodePtr addressForCall()
+        {
+            return m_ref.m_code;
+        }
+
+        // This function returns the offset in bytes of 'pointerIntoCode' into
+        // this block of code.  The pointer provided must be a pointer into this
+        // block of code.  It is ASSERTed that no codeblock >4gb in size.
+        unsigned offsetOf(void* pointerIntoCode)
+        {
+            intptr_t result = reinterpret_cast<intptr_t>(pointerIntoCode) - reinterpret_cast<intptr_t>(m_ref.m_code.executableAddress());
+            ASSERT(static_cast<intptr_t>(static_cast<unsigned>(result)) == result);
+            return static_cast<unsigned>(result);
+        }
+
+        // Execute the code!
+        inline JSValue execute(RegisterFile* registerFile, CallFrame* callFrame, JSGlobalData* globalData, JSValue* exception)
+        {
+            return JSValue::decode(ctiTrampoline(
+#if PLATFORM(X86_64)
+                0, 0, 0, 0, 0, 0,
+#endif
+                m_ref.m_code.executableAddress(), registerFile, callFrame, exception, Profiler::enabledProfilerReference(), globalData));
+        }
+
+        void* start()
+        {
+            return m_ref.m_code.dataLocation();
+        }
+
+        size_t size()
+        {
+            ASSERT(m_ref.m_code.executableAddress());
+            return m_ref.m_size;
+        }
+
+        ExecutablePool* getExecutablePool()
+        {
+            return m_ref.m_executablePool.get();
+        }
+
+        // Host functions are a bit special; they have a m_code pointer but they
+        // do not individully ref the executable pool containing the trampoline.
+        static JITCode HostFunction(CodePtr code)
+        {
+            return JITCode(code.dataLocation(), 0, 0);
+        }
+
+    private:
+        JITCode(void* code, PassRefPtr<ExecutablePool> executablePool, size_t size)
+            : m_ref(code, executablePool, size)
+        {
+        }
+
+        CodeRef m_ref;
+    };
+
+};
+
+#endif
+
+#endif
index 7a97cd89bd7c33efc12ac6ebf55b531e96f23912..c22a6921a523af364a5f249ae67bd995a8e871b1 100644 (file)
 
 #if ENABLE(JIT)
 
-#if PLATFORM(WIN)
-#undef FIELD_OFFSET // Fix conflict with winnt.h.
+namespace JSC {
+
+/* Deprecated: Please use JITStubCall instead. */
+
+// puts an arg onto the stack, as an arg to a context threaded function.
+ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID src, unsigned argumentNumber)
+{
+    poke(src, argumentNumber);
+}
+
+/* Deprecated: Please use JITStubCall instead. */
+
+ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber)
+{
+    poke(Imm32(value), argumentNumber);
+}
+
+/* Deprecated: Please use JITStubCall instead. */
+
+ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(void* value, unsigned argumentNumber)
+{
+    poke(ImmPtr(value), argumentNumber);
+}
+
+/* Deprecated: Please use JITStubCall instead. */
+
+ALWAYS_INLINE void JIT::emitGetJITStubArg(unsigned argumentNumber, RegisterID dst)
+{
+    peek(dst, argumentNumber);
+}
+
+ALWAYS_INLINE JSValue JIT::getConstantOperand(unsigned src)
+{
+    ASSERT(m_codeBlock->isConstantRegisterIndex(src));
+    return m_codeBlock->getConstant(src);
+}
+
+ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
+{
+    storePtr(from, Address(callFrameRegister, entry * sizeof(Register)));
+}
+
+ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry)
+{
+    storePtr(ImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
+}
+
+ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
+{
+    loadPtr(Address(from, entry * sizeof(Register)), to);
+#if !USE(JSVALUE32_64)
+    killLastResultRegister();
 #endif
+}
 
-// FIELD_OFFSET: Like the C++ offsetof macro, but you can use it with classes.
-// The magic number 0x4000 is insignificant. We use it to avoid using NULL, since
-// NULL can cause compiler problems, especially in cases of multiple inheritance.
-#define FIELD_OFFSET(class, field) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->field)) - 0x4000)
+ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
+{
+    load32(Address(from, entry * sizeof(Register)), to);
+#if !USE(JSVALUE32_64)
+    killLastResultRegister();
+#endif
+}
 
-namespace JSC {
+ALWAYS_INLINE JIT::Call JIT::emitNakedCall(CodePtr function)
+{
+    ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
 
-ALWAYS_INLINE void JIT::killLastResultRegister()
+    Call nakedCall = nearCall();
+    m_calls.append(CallRecord(nakedCall, m_bytecodeIndex, function.executableAddress()));
+    return nakedCall;
+}
+
+#if PLATFORM(X86) || PLATFORM(X86_64)
+
+ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
 {
-    m_lastResultBytecodeRegister = std::numeric_limits<int>::max();
+    pop(reg);
 }
 
-// get arg puts an arg from the SF register array into a h/w register
-ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, RegisterID dst)
+ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg)
+{
+    push(reg);
+}
+
+ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
+{
+    push(address);
+}
+
+#elif PLATFORM_ARM_ARCH(7)
+
+ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
+{
+    move(linkRegister, reg);
+}
+
+ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg)
+{
+    move(reg, linkRegister);
+}
+
+ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
+{
+    loadPtr(address, linkRegister);
+}
+
+#endif
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+ALWAYS_INLINE void JIT::restoreArgumentReference()
+{
+    poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*));
+}
+ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() {}
+#else
+ALWAYS_INLINE void JIT::restoreArgumentReference()
+{
+    move(stackPointerRegister, firstArgumentRegister);
+    poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*));
+}
+ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
+{
+#if PLATFORM(X86)
+    // Within a trampoline the return address will be on the stack at this point.
+    addPtr(Imm32(sizeof(void*)), stackPointerRegister, firstArgumentRegister);
+#elif PLATFORM_ARM_ARCH(7)
+    move(stackPointerRegister, firstArgumentRegister);
+#endif
+    // In the trampoline on x86-64, the first argument register is not overwritten.
+}
+#endif
+
+ALWAYS_INLINE JIT::Jump JIT::checkStructure(RegisterID reg, Structure* structure)
+{
+    return branchPtr(NotEqual, Address(reg, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(structure));
+}
+
+ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, int vReg)
+{
+    if (!m_codeBlock->isKnownNotImmediate(vReg))
+        linkSlowCase(iter);
+}
+
+ALWAYS_INLINE void JIT::addSlowCase(Jump jump)
 {
     ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
 
-    // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
-    if (m_codeBlock->isConstantRegisterIndex(src)) {
-        JSValuePtr value = m_codeBlock->getConstant(src);
-        move(ImmPtr(JSValuePtr::encode(value)), dst);
-        killLastResultRegister();
+    m_slowCases.append(SlowCaseEntry(jump, m_bytecodeIndex));
+}
+
+ALWAYS_INLINE void JIT::addSlowCase(JumpList jumpList)
+{
+    ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+    const JumpList::JumpVector& jumpVector = jumpList.jumps();
+    size_t size = jumpVector.size();
+    for (size_t i = 0; i < size; ++i)
+        m_slowCases.append(SlowCaseEntry(jumpVector[i], m_bytecodeIndex));
+}
+
+ALWAYS_INLINE void JIT::addJump(Jump jump, int relativeOffset)
+{
+    ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+    m_jmpTable.append(JumpTable(jump, m_bytecodeIndex + relativeOffset));
+}
+
+ALWAYS_INLINE void JIT::emitJumpSlowToHot(Jump jump, int relativeOffset)
+{
+    ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+
+    jump.linkTo(m_labels[m_bytecodeIndex + relativeOffset], this);
+}
+
+#if ENABLE(SAMPLING_FLAGS)
+ALWAYS_INLINE void JIT::setSamplingFlag(int32_t flag)
+{
+    ASSERT(flag >= 1);
+    ASSERT(flag <= 32);
+    or32(Imm32(1u << (flag - 1)), AbsoluteAddress(&SamplingFlags::s_flags));
+}
+
+ALWAYS_INLINE void JIT::clearSamplingFlag(int32_t flag)
+{
+    ASSERT(flag >= 1);
+    ASSERT(flag <= 32);
+    and32(Imm32(~(1u << (flag - 1))), AbsoluteAddress(&SamplingFlags::s_flags));
+}
+#endif
+
+#if ENABLE(SAMPLING_COUNTERS)
+ALWAYS_INLINE void JIT::emitCount(AbstractSamplingCounter& counter, uint32_t count)
+{
+#if PLATFORM(X86_64) // Or any other 64-bit plattform.
+    addPtr(Imm32(count), AbsoluteAddress(&counter.m_counter));
+#elif PLATFORM(X86) // Or any other little-endian 32-bit plattform.
+    intptr_t hiWord = reinterpret_cast<intptr_t>(&counter.m_counter) + sizeof(int32_t);
+    add32(Imm32(count), AbsoluteAddress(&counter.m_counter));
+    addWithCarry32(Imm32(0), AbsoluteAddress(reinterpret_cast<void*>(hiWord)));
+#else
+#error "SAMPLING_FLAGS not implemented on this platform."
+#endif
+}
+#endif
+
+#if ENABLE(OPCODE_SAMPLING)
+#if PLATFORM(X86_64)
+ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction)
+{
+    move(ImmPtr(m_interpreter->sampler()->sampleSlot()), X86::ecx);
+    storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), X86::ecx);
+}
+#else
+ALWAYS_INLINE void JIT::sampleInstruction(Instruction* instruction, bool inHostFunction)
+{
+    storePtr(ImmPtr(m_interpreter->sampler()->encodeSample(instruction, inHostFunction)), m_interpreter->sampler()->sampleSlot());
+}
+#endif
+#endif
+
+#if ENABLE(CODEBLOCK_SAMPLING)
+#if PLATFORM(X86_64)
+ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
+{
+    move(ImmPtr(m_interpreter->sampler()->codeBlockSlot()), X86::ecx);
+    storePtr(ImmPtr(codeBlock), X86::ecx);
+}
+#else
+ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
+{
+    storePtr(ImmPtr(codeBlock), m_interpreter->sampler()->codeBlockSlot());
+}
+#endif
+#endif
+
+#if USE(JSVALUE32_64)
+
+inline JIT::Address JIT::tagFor(unsigned index, RegisterID base)
+{
+    return Address(base, (index * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.tag));
+}
+
+inline JIT::Address JIT::payloadFor(unsigned index, RegisterID base)
+{
+    return Address(base, (index * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload));
+}
+
+inline JIT::Address JIT::addressFor(unsigned index, RegisterID base)
+{
+    return Address(base, (index * sizeof(Register)));
+}
+
+inline void JIT::emitLoadTag(unsigned index, RegisterID tag)
+{
+    RegisterID mappedTag;
+    if (getMappedTag(index, mappedTag)) {
+        move(mappedTag, tag);
+        unmap(tag);
         return;
     }
 
-    if (src == m_lastResultBytecodeRegister && m_codeBlock->isTemporaryRegisterIndex(src)) {
-        bool atJumpTarget = false;
-        while (m_jumpTargetsPosition < m_codeBlock->numberOfJumpTargets() && m_codeBlock->jumpTarget(m_jumpTargetsPosition) <= m_bytecodeIndex) {
-            if (m_codeBlock->jumpTarget(m_jumpTargetsPosition) == m_bytecodeIndex)
-                atJumpTarget = true;
-            ++m_jumpTargetsPosition;
-        }
+    if (m_codeBlock->isConstantRegisterIndex(index)) {
+        move(Imm32(getConstantOperand(index).tag()), tag);
+        unmap(tag);
+        return;
+    }
 
-        if (!atJumpTarget) {
-            // The argument we want is already stored in eax
-            if (dst != X86::eax)
-                move(X86::eax, dst);
-            killLastResultRegister();
-            return;
-        }
+    load32(tagFor(index), tag);
+    unmap(tag);
+}
+
+inline void JIT::emitLoadPayload(unsigned index, RegisterID payload)
+{
+    RegisterID mappedPayload;
+    if (getMappedPayload(index, mappedPayload)) {
+        move(mappedPayload, payload);
+        unmap(payload);
+        return;
     }
 
-    loadPtr(Address(callFrameRegister, src * sizeof(Register)), dst);
-    killLastResultRegister();
+    if (m_codeBlock->isConstantRegisterIndex(index)) {
+        move(Imm32(getConstantOperand(index).payload()), payload);
+        unmap(payload);
+        return;
+    }
+
+    load32(payloadFor(index), payload);
+    unmap(payload);
 }
 
-ALWAYS_INLINE void JIT::emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2)
+inline void JIT::emitLoad(const JSValue& v, RegisterID tag, RegisterID payload)
 {
-    if (src2 == m_lastResultBytecodeRegister) {
-        emitGetVirtualRegister(src2, dst2);
-        emitGetVirtualRegister(src1, dst1);
-    } else {
-        emitGetVirtualRegister(src1, dst1);
-        emitGetVirtualRegister(src2, dst2);
+    move(Imm32(v.payload()), payload);
+    move(Imm32(v.tag()), tag);
+}
+
+inline void JIT::emitLoad(unsigned index, RegisterID tag, RegisterID payload, RegisterID base)
+{
+    ASSERT(tag != payload);
+
+    if (base == callFrameRegister) {
+        ASSERT(payload != base);
+        emitLoadPayload(index, payload);
+        emitLoadTag(index, tag);
+        return;
     }
+
+    if (payload == base) { // avoid stomping base
+        load32(tagFor(index, base), tag);
+        load32(payloadFor(index, base), payload);
+        return;
+    }
+
+    load32(payloadFor(index, base), payload);
+    load32(tagFor(index, base), tag);
 }
 
-// puts an arg onto the stack, as an arg to a context threaded function.
-ALWAYS_INLINE void JIT::emitPutJITStubArg(RegisterID src, unsigned argumentNumber)
+inline void JIT::emitLoad2(unsigned index1, RegisterID tag1, RegisterID payload1, unsigned index2, RegisterID tag2, RegisterID payload2)
 {
-    poke(src, argumentNumber);
+    if (isMapped(index1)) {
+        emitLoad(index1, tag1, payload1);
+        emitLoad(index2, tag2, payload2);
+        return;
+    }
+    emitLoad(index2, tag2, payload2);
+    emitLoad(index1, tag1, payload1);
 }
 
-ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(unsigned value, unsigned argumentNumber)
+inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value)
 {
-    poke(Imm32(value), argumentNumber);
+    if (m_codeBlock->isConstantRegisterIndex(index)) {
+        Register& inConstantPool = m_codeBlock->constantRegister(index);
+        loadDouble(&inConstantPool, value);
+    } else
+        loadDouble(addressFor(index), value);
 }
 
-ALWAYS_INLINE void JIT::emitPutJITStubArgConstant(void* value, unsigned argumentNumber)
+inline void JIT::emitLoadInt32ToDouble(unsigned index, FPRegisterID value)
 {
-    poke(ImmPtr(value), argumentNumber);
+    if (m_codeBlock->isConstantRegisterIndex(index)) {
+        Register& inConstantPool = m_codeBlock->constantRegister(index);
+        char* bytePointer = reinterpret_cast<char*>(&inConstantPool);
+        convertInt32ToDouble(AbsoluteAddress(bytePointer + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), value);
+    } else
+        convertInt32ToDouble(payloadFor(index), value);
 }
 
-ALWAYS_INLINE void JIT::emitGetJITStubArg(unsigned argumentNumber, RegisterID dst)
+inline void JIT::emitStore(unsigned index, RegisterID tag, RegisterID payload, RegisterID base)
 {
-    peek(dst, argumentNumber);
+    store32(payload, payloadFor(index, base));
+    store32(tag, tagFor(index, base));
 }
 
-ALWAYS_INLINE JSValuePtr JIT::getConstantOperand(unsigned src)
+inline void JIT::emitStoreInt32(unsigned index, RegisterID payload, bool indexIsInt32)
 {
-    ASSERT(m_codeBlock->isConstantRegisterIndex(src));
-    return m_codeBlock->getConstant(src);
+    store32(payload, payloadFor(index, callFrameRegister));
+    if (!indexIsInt32)
+        store32(Imm32(JSValue::Int32Tag), tagFor(index, callFrameRegister));
 }
 
-ALWAYS_INLINE int32_t JIT::getConstantOperandImmediateInt(unsigned src)
+inline void JIT::emitStoreInt32(unsigned index, Imm32 payload, bool indexIsInt32)
 {
-    return getConstantOperand(src).getInt32Fast();
+    store32(payload, payloadFor(index, callFrameRegister));
+    if (!indexIsInt32)
+        store32(Imm32(JSValue::Int32Tag), tagFor(index, callFrameRegister));
 }
 
-ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(unsigned src)
+inline void JIT::emitStoreCell(unsigned index, RegisterID payload, bool indexIsCell)
 {
-    return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isInt32Fast();
+    store32(payload, payloadFor(index, callFrameRegister));
+    if (!indexIsCell)
+        store32(Imm32(JSValue::CellTag), tagFor(index, callFrameRegister));
 }
 
-// get arg puts an arg from the SF register array onto the stack, as an arg to a context threaded function.
-ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch)
+inline void JIT::emitStoreBool(unsigned index, RegisterID tag, bool indexIsBool)
 {
-    if (m_codeBlock->isConstantRegisterIndex(src)) {
-        JSValuePtr value = m_codeBlock->getConstant(src);
-        emitPutJITStubArgConstant(JSValuePtr::encode(value), argumentNumber);
-    } else {
-        loadPtr(Address(callFrameRegister, src * sizeof(Register)), scratch);
-        emitPutJITStubArg(scratch, argumentNumber);
-    }
+    if (!indexIsBool)
+        store32(Imm32(0), payloadFor(index, callFrameRegister));
+    store32(tag, tagFor(index, callFrameRegister));
+}
 
-    killLastResultRegister();
+inline void JIT::emitStoreDouble(unsigned index, FPRegisterID value)
+{
+    storeDouble(value, addressFor(index));
 }
 
-ALWAYS_INLINE void JIT::emitPutCTIParam(void* value, unsigned name)
+inline void JIT::emitStore(unsigned index, const JSValue constant, RegisterID base)
 {
-    poke(ImmPtr(value), name);
+    store32(Imm32(constant.payload()), payloadFor(index, base));
+    store32(Imm32(constant.tag()), tagFor(index, base));
 }
 
-ALWAYS_INLINE void JIT::emitPutCTIParam(RegisterID from, unsigned name)
+ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst)
 {
-    poke(from, name);
+    emitStore(dst, jsUndefined());
 }
 
-ALWAYS_INLINE void JIT::emitGetCTIParam(unsigned name, RegisterID to)
+inline bool JIT::isLabeled(unsigned bytecodeIndex)
 {
-    peek(to, name);
-    killLastResultRegister();
+    for (size_t numberOfJumpTargets = m_codeBlock->numberOfJumpTargets(); m_jumpTargetIndex != numberOfJumpTargets; ++m_jumpTargetIndex) {
+        unsigned jumpTarget = m_codeBlock->jumpTarget(m_jumpTargetIndex);
+        if (jumpTarget == bytecodeIndex)
+            return true;
+        if (jumpTarget > bytecodeIndex)
+            return false;
+    }
+    return false;
 }
 
-ALWAYS_INLINE void JIT::emitPutToCallFrameHeader(RegisterID from, RegisterFile::CallFrameHeaderEntry entry)
+inline void JIT::map(unsigned bytecodeIndex, unsigned virtualRegisterIndex, RegisterID tag, RegisterID payload)
 {
-    storePtr(from, Address(callFrameRegister, entry * sizeof(Register)));
+    if (isLabeled(bytecodeIndex))
+        return;
+
+    m_mappedBytecodeIndex = bytecodeIndex;
+    m_mappedVirtualRegisterIndex = virtualRegisterIndex;
+    m_mappedTag = tag;
+    m_mappedPayload = payload;
 }
 
-ALWAYS_INLINE void JIT::emitPutImmediateToCallFrameHeader(void* value, RegisterFile::CallFrameHeaderEntry entry)
+inline void JIT::unmap(RegisterID registerID)
 {
-    storePtr(ImmPtr(value), Address(callFrameRegister, entry * sizeof(Register)));
+    if (m_mappedTag == registerID)
+        m_mappedTag = (RegisterID)-1;
+    else if (m_mappedPayload == registerID)
+        m_mappedPayload = (RegisterID)-1;
 }
 
-ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader(RegisterFile::CallFrameHeaderEntry entry, RegisterID to)
+inline void JIT::unmap()
 {
-    loadPtr(Address(callFrameRegister, entry * sizeof(Register)), to);
-    killLastResultRegister();
+    m_mappedBytecodeIndex = (unsigned)-1;
+    m_mappedVirtualRegisterIndex = (unsigned)-1;
+    m_mappedTag = (RegisterID)-1;
+    m_mappedPayload = (RegisterID)-1;
 }
 
-ALWAYS_INLINE void JIT::emitPutVirtualRegister(unsigned dst, RegisterID from)
+inline bool JIT::isMapped(unsigned virtualRegisterIndex)
 {
-    storePtr(from, Address(callFrameRegister, dst * sizeof(Register)));
-    m_lastResultBytecodeRegister = (from == X86::eax) ? dst : std::numeric_limits<int>::max();
-    // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
+    if (m_mappedBytecodeIndex != m_bytecodeIndex)
+        return false;
+    if (m_mappedVirtualRegisterIndex != virtualRegisterIndex)
+        return false;
+    return true;
 }
 
-ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst)
+inline bool JIT::getMappedPayload(unsigned virtualRegisterIndex, RegisterID& payload)
 {
-    storePtr(ImmPtr(JSValuePtr::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register)));
-    // FIXME: #ifndef NDEBUG, Write the correct m_type to the register.
+    if (m_mappedBytecodeIndex != m_bytecodeIndex)
+        return false;
+    if (m_mappedVirtualRegisterIndex != virtualRegisterIndex)
+        return false;
+    if (m_mappedPayload == (RegisterID)-1)
+        return false;
+    payload = m_mappedPayload;
+    return true;
 }
 
-ALWAYS_INLINE JIT::Jump JIT::emitNakedCall(X86::RegisterID r)
+inline bool JIT::getMappedTag(unsigned virtualRegisterIndex, RegisterID& tag)
 {
-    ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+    if (m_mappedBytecodeIndex != m_bytecodeIndex)
+        return false;
+    if (m_mappedVirtualRegisterIndex != virtualRegisterIndex)
+        return false;
+    if (m_mappedTag == (RegisterID)-1)
+        return false;
+    tag = m_mappedTag;
+    return true;
+}
 
-    Jump nakedCall = call(r);
-    m_calls.append(CallRecord(nakedCall, m_bytecodeIndex));
-    return nakedCall;
+inline void JIT::emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex)
+{
+    if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex))
+        addSlowCase(branch32(NotEqual, tagFor(virtualRegisterIndex), Imm32(JSValue::CellTag)));
 }
 
-ALWAYS_INLINE JIT::Jump JIT::emitNakedCall(void* function)
+inline void JIT::emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex, RegisterID tag)
 {
-    ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+    if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex))
+        addSlowCase(branch32(NotEqual, tag, Imm32(JSValue::CellTag)));
+}
 
-    Jump nakedCall = call();
-    m_calls.append(CallRecord(nakedCall, m_bytecodeIndex, function));
-    return nakedCall;
+inline void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, unsigned virtualRegisterIndex)
+{
+    if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex))
+        linkSlowCase(iter);
 }
 
-#if USE(JIT_STUB_ARGUMENT_REGISTER)
-ALWAYS_INLINE void JIT::restoreArgumentReference()
+ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(unsigned src)
 {
-#if PLATFORM(X86_64)
-    move(X86::esp, X86::edi);
-#else
-    move(X86::esp, X86::ecx);
-#endif
-    emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
+    return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isInt32();
 }
-ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline()
+
+ALWAYS_INLINE bool JIT::getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant)
 {
-    // In the trampoline on x86-64, the first argument register is not overwritten.
-#if !PLATFORM(X86_64)
-    move(X86::esp, X86::ecx);
-    addPtr(Imm32(sizeof(void*)), X86::ecx);
-#endif
+    if (isOperandConstantImmediateInt(op1)) {
+        constant = getConstantOperand(op1).asInt32();
+        op = op2;
+        return true;
+    }
+
+    if (isOperandConstantImmediateInt(op2)) {
+        constant = getConstantOperand(op2).asInt32();
+        op = op1;
+        return true;
+    }
+    
+    return false;
 }
-#elif USE(JIT_STUB_ARGUMENT_STACK)
-ALWAYS_INLINE void JIT::restoreArgumentReference()
+
+ALWAYS_INLINE bool JIT::isOperandConstantImmediateDouble(unsigned src)
 {
-    storePtr(X86::esp, X86::esp);
-    emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
+    return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isDouble();
 }
-ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() {}
-#else // JIT_STUB_ARGUMENT_VA_LIST
-ALWAYS_INLINE void JIT::restoreArgumentReference()
+
+/* Deprecated: Please use JITStubCall instead. */
+
+ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch1, RegisterID scratch2)
 {
-    emitPutCTIParam(callFrameRegister, STUB_ARGS_callFrame);
+    if (m_codeBlock->isConstantRegisterIndex(src)) {
+        JSValue constant = m_codeBlock->getConstant(src);
+        poke(Imm32(constant.payload()), argumentNumber);
+        poke(Imm32(constant.tag()), argumentNumber + 1);
+    } else {
+        emitLoad(src, scratch1, scratch2);
+        poke(scratch2, argumentNumber);
+        poke(scratch1, argumentNumber + 1);
+    }
+}
+
+#else // USE(JSVALUE32_64)
+
+ALWAYS_INLINE void JIT::killLastResultRegister()
+{
+    m_lastResultBytecodeRegister = std::numeric_limits<int>::max();
 }
-ALWAYS_INLINE void JIT::restoreArgumentReferenceForTrampoline() {}
-#endif
 
-ALWAYS_INLINE JIT::Jump JIT::emitCTICall_internal(void* helper)
+// get arg puts an arg from the SF register array into a h/w register
+ALWAYS_INLINE void JIT::emitGetVirtualRegister(int src, RegisterID dst)
 {
     ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
 
-#if ENABLE(OPCODE_SAMPLING)
-    sampleInstruction(m_codeBlock->instructions().begin() + m_bytecodeIndex, true);
-#endif
-    restoreArgumentReference();
-    Jump ctiCall = call();
-    m_calls.append(CallRecord(ctiCall, m_bytecodeIndex, helper));
-#if ENABLE(OPCODE_SAMPLING)
-    sampleInstruction(m_codeBlock->instructions().begin() + m_bytecodeIndex, false);
-#endif
+    // TODO: we want to reuse values that are already in registers if we can - add a register allocator!
+    if (m_codeBlock->isConstantRegisterIndex(src)) {
+        JSValue value = m_codeBlock->getConstant(src);
+        move(ImmPtr(JSValue::encode(value)), dst);
+        killLastResultRegister();
+        return;
+    }
+
+    if (src == m_lastResultBytecodeRegister && m_codeBlock->isTemporaryRegisterIndex(src)) {
+        bool atJumpTarget = false;
+        while (m_jumpTargetsPosition < m_codeBlock->numberOfJumpTargets() && m_codeBlock->jumpTarget(m_jumpTargetsPosition) <= m_bytecodeIndex) {
+            if (m_codeBlock->jumpTarget(m_jumpTargetsPosition) == m_bytecodeIndex)
+                atJumpTarget = true;
+            ++m_jumpTargetsPosition;
+        }
+
+        if (!atJumpTarget) {
+            // The argument we want is already stored in eax
+            if (dst != cachedResultRegister)
+                move(cachedResultRegister, dst);
+            killLastResultRegister();
+            return;
+        }
+    }
+
+    loadPtr(Address(callFrameRegister, src * sizeof(Register)), dst);
     killLastResultRegister();
+}
+
+ALWAYS_INLINE void JIT::emitGetVirtualRegisters(int src1, RegisterID dst1, int src2, RegisterID dst2)
+{
+    if (src2 == m_lastResultBytecodeRegister) {
+        emitGetVirtualRegister(src2, dst2);
+        emitGetVirtualRegister(src1, dst1);
+    } else {
+        emitGetVirtualRegister(src1, dst1);
+        emitGetVirtualRegister(src2, dst2);
+    }
+}
 
-    return ctiCall;
+ALWAYS_INLINE int32_t JIT::getConstantOperandImmediateInt(unsigned src)
+{
+    return getConstantOperand(src).asInt32();
 }
 
-ALWAYS_INLINE JIT::Jump JIT::checkStructure(RegisterID reg, Structure* structure)
+ALWAYS_INLINE bool JIT::isOperandConstantImmediateInt(unsigned src)
+{
+    return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isInt32();
+}
+
+ALWAYS_INLINE void JIT::emitPutVirtualRegister(unsigned dst, RegisterID from)
 {
-    return jnePtr(Address(reg, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(structure));
+    storePtr(from, Address(callFrameRegister, dst * sizeof(Register)));
+    m_lastResultBytecodeRegister = (from == cachedResultRegister) ? dst : std::numeric_limits<int>::max();
+}
+
+ALWAYS_INLINE void JIT::emitInitRegister(unsigned dst)
+{
+    storePtr(ImmPtr(JSValue::encode(jsUndefined())), Address(callFrameRegister, dst * sizeof(Register)));
 }
 
 ALWAYS_INLINE JIT::Jump JIT::emitJumpIfJSCell(RegisterID reg)
 {
-#if USE(ALTERNATE_JSIMMEDIATE)
-    return jzPtr(reg, tagMaskRegister);
+#if USE(JSVALUE64)
+    return branchTestPtr(Zero, reg, tagMaskRegister);
 #else
-    return jz32(reg, Imm32(JSImmediate::TagMask));
+    return branchTest32(Zero, reg, Imm32(JSImmediate::TagMask));
 #endif
 }
 
@@ -284,10 +655,10 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfJSCell(RegisterID reg)
 
 ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotJSCell(RegisterID reg)
 {
-#if USE(ALTERNATE_JSIMMEDIATE)
-    return jnzPtr(reg, tagMaskRegister);
+#if USE(JSVALUE64)
+    return branchTestPtr(NonZero, reg, tagMaskRegister);
 #else
-    return jnz32(reg, Imm32(JSImmediate::TagMask));
+    return branchTest32(NonZero, reg, Imm32(JSImmediate::TagMask));
 #endif
 }
 
@@ -302,38 +673,32 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg, int vReg)
         emitJumpSlowCaseIfNotJSCell(reg);
 }
 
-ALWAYS_INLINE void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, int vReg)
-{
-    if (!m_codeBlock->isKnownNotImmediate(vReg))
-        linkSlowCase(iter);
-}
-
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
 ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateNumber(RegisterID reg)
 {
-    return jnzPtr(reg, tagTypeNumberRegister);
+    return branchTestPtr(NonZero, reg, tagTypeNumberRegister);
 }
 ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateNumber(RegisterID reg)
 {
-    return jzPtr(reg, tagTypeNumberRegister);
+    return branchTestPtr(Zero, reg, tagTypeNumberRegister);
 }
 #endif
 
 ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateInteger(RegisterID reg)
 {
-#if USE(ALTERNATE_JSIMMEDIATE)
-    return jaePtr(reg, tagTypeNumberRegister);
+#if USE(JSVALUE64)
+    return branchPtr(AboveOrEqual, reg, tagTypeNumberRegister);
 #else
-    return jnz32(reg, Imm32(JSImmediate::TagTypeNumber));
+    return branchTest32(NonZero, reg, Imm32(JSImmediate::TagTypeNumber));
 #endif
 }
 
 ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateInteger(RegisterID reg)
 {
-#if USE(ALTERNATE_JSIMMEDIATE)
-    return jbPtr(reg, tagTypeNumberRegister);
+#if USE(JSVALUE64)
+    return branchPtr(Below, reg, tagTypeNumberRegister);
 #else
-    return jz32(reg, Imm32(JSImmediate::TagTypeNumber));
+    return branchTest32(Zero, reg, Imm32(JSImmediate::TagTypeNumber));
 #endif
 }
 
@@ -354,7 +719,7 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotImmediateIntegers(RegisterID reg1,
     addSlowCase(emitJumpIfNotImmediateIntegers(reg1, reg2, scratch));
 }
 
-#if !USE(ALTERNATE_JSIMMEDIATE)
+#if !USE(JSVALUE64)
 ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg)
 {
     subPtr(Imm32(JSImmediate::TagTypeNumber), reg);
@@ -362,13 +727,13 @@ ALWAYS_INLINE void JIT::emitFastArithDeTagImmediate(RegisterID reg)
 
 ALWAYS_INLINE JIT::Jump JIT::emitFastArithDeTagImmediateJumpIfZero(RegisterID reg)
 {
-    return jzSubPtr(Imm32(JSImmediate::TagTypeNumber), reg);
+    return branchSubPtr(Zero, Imm32(JSImmediate::TagTypeNumber), reg);
 }
 #endif
 
 ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID dest)
 {
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
     emitFastArithIntToImmNoCheck(src, dest);
 #else
     if (src != dest)
@@ -379,7 +744,7 @@ ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID d
 
 ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg)
 {
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
     UNUSED_PARAM(reg);
 #else
     rshiftPtr(Imm32(JSImmediate::IntegerPayloadShift), reg);
@@ -389,7 +754,7 @@ ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg)
 // operand is int32_t, must have been zero-extended if register is 64-bit.
 ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest)
 {
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
     if (src != dest)
         move(src, dest);
     orPtr(tagTypeNumberRegister, dest);
@@ -406,28 +771,25 @@ ALWAYS_INLINE void JIT::emitTagAsBoolImmediate(RegisterID reg)
     or32(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), reg);
 }
 
-ALWAYS_INLINE void JIT::addSlowCase(Jump jump)
-{
-    ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
-
-    m_slowCases.append(SlowCaseEntry(jump, m_bytecodeIndex));
-}
+/* Deprecated: Please use JITStubCall instead. */
 
-ALWAYS_INLINE void JIT::addJump(Jump jump, int relativeOffset)
+// get arg puts an arg from the SF register array onto the stack, as an arg to a context threaded function.
+ALWAYS_INLINE void JIT::emitPutJITStubArgFromVirtualRegister(unsigned src, unsigned argumentNumber, RegisterID scratch)
 {
-    ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+    if (m_codeBlock->isConstantRegisterIndex(src)) {
+        JSValue value = m_codeBlock->getConstant(src);
+        emitPutJITStubArgConstant(JSValue::encode(value), argumentNumber);
+    } else {
+        loadPtr(Address(callFrameRegister, src * sizeof(Register)), scratch);
+        emitPutJITStubArg(scratch, argumentNumber);
+    }
 
-    m_jmpTable.append(JumpTable(jump, m_bytecodeIndex + relativeOffset));
+    killLastResultRegister();
 }
 
-ALWAYS_INLINE void JIT::emitJumpSlowToHot(Jump jump, int relativeOffset)
-{
-    ASSERT(m_bytecodeIndex != (unsigned)-1); // This method should only be called during hot/cold path generation, so that m_bytecodeIndex is set.
+#endif // USE(JSVALUE32_64)
 
-    jump.linkTo(m_labels[m_bytecodeIndex + relativeOffset], this);
-}
-
-}
+} // namespace JSC
 
 #endif // ENABLE(JIT)
 
diff --git a/jit/JITOpcodes.cpp b/jit/JITOpcodes.cpp
new file mode 100644 (file)
index 0000000..85997c2
--- /dev/null
@@ -0,0 +1,3033 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "JIT.h"
+
+#if ENABLE(JIT)
+
+#include "JITInlineMethods.h"
+#include "JITStubCall.h"
+#include "JSArray.h"
+#include "JSCell.h"
+#include "JSFunction.h"
+#include "LinkBuffer.h"
+
+namespace JSC {
+
+#if USE(JSVALUE32_64)
+
+void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
+{
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+    // (1) This function provides fast property access for string length
+    Label stringLengthBegin = align();
+    
+    // regT0 holds payload, regT1 holds tag
+    
+    Jump string_failureCases1 = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+    Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
+
+    // Checks out okay! - get the length from the Ustring.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSString, m_value) + OBJECT_OFFSETOF(UString, m_rep)), regT2);
+    load32(Address(regT2, OBJECT_OFFSETOF(UString::Rep, len)), regT2);
+
+    Jump string_failureCases3 = branch32(Above, regT2, Imm32(INT_MAX));
+    move(regT2, regT0);
+    move(Imm32(JSValue::Int32Tag), regT1);
+
+    ret();
+#endif
+
+    // (2) Trampolines for the slow cases of op_call / op_call_eval / op_construct.
+
+#if ENABLE(JIT_OPTIMIZE_CALL)
+    /* VirtualCallPreLink Trampoline */
+    Label virtualCallPreLinkBegin = align();
+
+    // regT0 holds callee, regT1 holds argCount.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_body)), regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT2);
+    Jump hasCodeBlock1 = branchTestPtr(NonZero, regT2);
+
+    // Lazily generate a CodeBlock.
+    preserveReturnAddressAfterCall(regT3); // return address
+    restoreArgumentReference();
+    Call callJSFunction1 = call();
+    move(regT0, regT2);
+    emitGetJITStubArg(1, regT0); // callee
+    emitGetJITStubArg(5, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3); // return address
+    hasCodeBlock1.link(this);
+
+    // regT2 holds codeBlock.
+    Jump isNativeFunc1 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
+
+    // Check argCount matches callee arity.
+    Jump arityCheckOkay1 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 3); // return address
+    emitPutJITStubArg(regT2, 7); // codeBlock
+    restoreArgumentReference();
+    Call callArityCheck1 = call();
+    move(regT1, callFrameRegister);
+    emitGetJITStubArg(1, regT0); // callee
+    emitGetJITStubArg(5, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3); // return address
+
+    arityCheckOkay1.link(this);
+    isNativeFunc1.link(this);
+    
+    compileOpCallInitializeCallFrame();
+
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 3);
+    restoreArgumentReference();
+    Call callDontLazyLinkCall = call();
+    restoreReturnAddressBeforeReturn(regT3);
+    jump(regT0);
+
+    /* VirtualCallLink Trampoline */
+    Label virtualCallLinkBegin = align();
+
+    // regT0 holds callee, regT1 holds argCount.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_body)), regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT2);
+    Jump hasCodeBlock2 = branchTestPtr(NonZero, regT2);
+
+    // Lazily generate a CodeBlock.
+    preserveReturnAddressAfterCall(regT3); // return address
+    restoreArgumentReference();
+    Call callJSFunction2 = call();
+    move(regT0, regT2);
+    emitGetJITStubArg(1, regT0); // callee
+    emitGetJITStubArg(5, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3); // return address
+    hasCodeBlock2.link(this);
+
+    // regT2 holds codeBlock.
+    Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
+
+    // Check argCount matches callee arity.
+    Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 3); // return address
+    emitPutJITStubArg(regT2, 7); // codeBlock
+    restoreArgumentReference();
+    Call callArityCheck2 = call();
+    move(regT1, callFrameRegister);
+    emitGetJITStubArg(1, regT0); // callee
+    emitGetJITStubArg(5, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3); // return address
+
+    arityCheckOkay2.link(this);
+    isNativeFunc2.link(this);
+
+    compileOpCallInitializeCallFrame();
+
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 3);
+    restoreArgumentReference();
+    Call callLazyLinkCall = call();
+    restoreReturnAddressBeforeReturn(regT3);
+    jump(regT0);
+#endif // ENABLE(JIT_OPTIMIZE_CALL)
+
+    /* VirtualCall Trampoline */
+    Label virtualCallBegin = align();
+
+    // regT0 holds callee, regT1 holds argCount.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_body)), regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT2);
+    Jump hasCodeBlock3 = branchTestPtr(NonZero, regT2);
+
+    // Lazily generate a CodeBlock.
+    preserveReturnAddressAfterCall(regT3); // return address
+    restoreArgumentReference();
+    Call callJSFunction3 = call();
+    move(regT0, regT2);
+    emitGetJITStubArg(1, regT0); // callee
+    emitGetJITStubArg(5, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3); // return address
+    hasCodeBlock3.link(this);
+    
+    // regT2 holds codeBlock.
+    Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
+    
+    // Check argCount matches callee.
+    Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 3); // return address
+    emitPutJITStubArg(regT2, 7); // codeBlock
+    restoreArgumentReference();
+    Call callArityCheck3 = call();
+    move(regT1, callFrameRegister);
+    emitGetJITStubArg(1, regT0); // callee
+    emitGetJITStubArg(5, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3); // return address
+
+    arityCheckOkay3.link(this);
+    isNativeFunc3.link(this);
+    compileOpCallInitializeCallFrame();
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_body)), regT0);
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(FunctionBodyNode, m_jitCode)), regT0);
+    jump(regT0);
+
+#if PLATFORM(X86)
+    Label nativeCallThunk = align();
+    preserveReturnAddressAfterCall(regT0);
+    emitPutToCallFrameHeader(regT0, RegisterFile::ReturnPC); // Push return address
+
+    // Load caller frame's scope chain into this callframe so that whatever we call can
+    // get to its global data.
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT1);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT1);
+    emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+    
+    emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+
+    /* We have two structs that we use to describe the stackframe we set up for our
+     * call to native code.  NativeCallFrameStructure describes the how we set up the stack
+     * in advance of the call.  NativeFunctionCalleeSignature describes the callframe
+     * as the native code expects it.  We do this as we are using the fastcall calling
+     * convention which results in the callee popping its arguments off the stack, but
+     * not the rest of the callframe so we need a nice way to ensure we increment the
+     * stack pointer by the right amount after the call.
+     */
+
+#if COMPILER(MSVC) || PLATFORM(LINUX)
+#if COMPILER(MSVC)
+#pragma pack(push)
+#pragma pack(4)
+#endif // COMPILER(MSVC)
+    struct NativeCallFrameStructure {
+      //  CallFrame* callFrame; // passed in EDX
+        JSObject* callee;
+        JSValue thisValue;
+        ArgList* argPointer;
+        ArgList args;
+        JSValue result;
+    };
+    struct NativeFunctionCalleeSignature {
+        JSObject* callee;
+        JSValue thisValue;
+        ArgList* argPointer;
+    };
+#if COMPILER(MSVC)
+#pragma pack(pop)
+#endif // COMPILER(MSVC)
+#else
+    struct NativeCallFrameStructure {
+      //  CallFrame* callFrame; // passed in ECX
+      //  JSObject* callee; // passed in EDX
+        JSValue thisValue;
+        ArgList* argPointer;
+        ArgList args;
+    };
+    struct NativeFunctionCalleeSignature {
+        JSValue thisValue;
+        ArgList* argPointer;
+    };
+#endif
+    
+    const int NativeCallFrameSize = (sizeof(NativeCallFrameStructure) + 15) & ~15;
+    // Allocate system stack frame
+    subPtr(Imm32(NativeCallFrameSize), stackPointerRegister);
+
+    // Set up arguments
+    subPtr(Imm32(1), regT0); // Don't include 'this' in argcount
+
+    // push argcount
+    storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_argCount)));
+    
+    // Calculate the start of the callframe header, and store in regT1
+    addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * (int)sizeof(Register)), callFrameRegister, regT1);
+    
+    // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT0)
+    mul32(Imm32(sizeof(Register)), regT0, regT0);
+    subPtr(regT0, regT1);
+    storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_args)));
+
+    // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register)
+    addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, args)), stackPointerRegister, regT0);
+    storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, argPointer)));
+
+    // regT1 currently points to the first argument, regT1 - sizeof(Register) points to 'this'
+    loadPtr(Address(regT1, -(int)sizeof(Register) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
+    loadPtr(Address(regT1, -(int)sizeof(Register) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT3);
+    storePtr(regT2, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+    storePtr(regT3, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
+
+#if COMPILER(MSVC) || PLATFORM(LINUX)
+    // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register)
+    addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86::ecx);
+
+    // Plant callee
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86::eax);
+    storePtr(X86::eax, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, callee)));
+
+    // Plant callframe
+    move(callFrameRegister, X86::edx);
+
+    call(Address(X86::eax, OBJECT_OFFSETOF(JSFunction, m_data)));
+
+    // JSValue is a non-POD type, so eax points to it
+    emitLoad(0, regT1, regT0, X86::eax);
+#else
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86::edx); // callee
+    move(callFrameRegister, X86::ecx); // callFrame
+    call(Address(X86::edx, OBJECT_OFFSETOF(JSFunction, m_data)));
+#endif
+
+    // We've put a few temporaries on the stack in addition to the actual arguments
+    // so pull them off now
+    addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister);
+
+    // Check for an exception
+    // FIXME: Maybe we can optimize this comparison to JSValue().
+    move(ImmPtr(&globalData->exception), regT2);
+    Jump sawException1 = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::CellTag));
+    Jump sawException2 = branch32(NonZero, payloadFor(0, regT2), Imm32(0));
+
+    // Grab the return address.
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT3);
+    
+    // Restore our caller's "r".
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
+    
+    // Return.
+    restoreReturnAddressBeforeReturn(regT3);
+    ret();
+
+    // Handle an exception
+    sawException1.link(this);
+    sawException2.link(this);
+    // Grab the return address.
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
+    move(ImmPtr(&globalData->exceptionLocation), regT2);
+    storePtr(regT1, regT2);
+    move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
+    poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*));
+    restoreReturnAddressBeforeReturn(regT2);
+    ret();
+
+#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
+#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
+#else
+    breakpoint();
+#endif
+    
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+    Call string_failureCases1Call = makeTailRecursiveCall(string_failureCases1);
+    Call string_failureCases2Call = makeTailRecursiveCall(string_failureCases2);
+    Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3);
+#endif
+
+    // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
+    LinkBuffer patchBuffer(this, m_globalData->executableAllocator.poolForSize(m_assembler.size()));
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+    patchBuffer.link(string_failureCases1Call, FunctionPtr(cti_op_get_by_id_string_fail));
+    patchBuffer.link(string_failureCases2Call, FunctionPtr(cti_op_get_by_id_string_fail));
+    patchBuffer.link(string_failureCases3Call, FunctionPtr(cti_op_get_by_id_string_fail));
+#endif
+#if ENABLE(JIT_OPTIMIZE_CALL)
+    patchBuffer.link(callArityCheck1, FunctionPtr(cti_op_call_arityCheck));
+    patchBuffer.link(callJSFunction1, FunctionPtr(cti_op_call_JSFunction));
+    patchBuffer.link(callArityCheck2, FunctionPtr(cti_op_call_arityCheck));
+    patchBuffer.link(callJSFunction2, FunctionPtr(cti_op_call_JSFunction));
+    patchBuffer.link(callDontLazyLinkCall, FunctionPtr(cti_vm_dontLazyLinkCall));
+    patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall));
+#endif
+    patchBuffer.link(callArityCheck3, FunctionPtr(cti_op_call_arityCheck));
+    patchBuffer.link(callJSFunction3, FunctionPtr(cti_op_call_JSFunction));
+
+    CodeRef finalCode = patchBuffer.finalizeCode();
+    *executablePool = finalCode.m_executablePool;
+
+    *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
+    *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk);
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+    *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
+#else
+    UNUSED_PARAM(ctiStringLengthTrampoline);
+#endif
+#if ENABLE(JIT_OPTIMIZE_CALL)
+    *ctiVirtualCallPreLink = trampolineAt(finalCode, virtualCallPreLinkBegin);
+    *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
+#else
+    UNUSED_PARAM(ctiVirtualCallPreLink);
+    UNUSED_PARAM(ctiVirtualCallLink);
+#endif
+}
+
+void JIT::emit_op_mov(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src = currentInstruction[2].u.operand;
+
+    if (m_codeBlock->isConstantRegisterIndex(src))
+        emitStore(dst, getConstantOperand(src));
+    else {
+        emitLoad(src, regT1, regT0);
+        emitStore(dst, regT1, regT0);
+        map(m_bytecodeIndex + OPCODE_LENGTH(op_mov), dst, regT1, regT0);
+    }
+}
+
+void JIT::emit_op_end(Instruction* currentInstruction)
+{
+    if (m_codeBlock->needsFullScopeChain())
+        JITStubCall(this, cti_op_end).call();
+    ASSERT(returnValueRegister != callFrameRegister);
+    emitLoad(currentInstruction[1].u.operand, regT1, regT0);
+    restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register))));
+    ret();
+}
+
+void JIT::emit_op_jmp(Instruction* currentInstruction)
+{
+    unsigned target = currentInstruction[1].u.operand;
+    addJump(jump(), target + 1);
+}
+
+void JIT::emit_op_loop(Instruction* currentInstruction)
+{
+    unsigned target = currentInstruction[1].u.operand;
+    emitTimeoutCheck();
+    addJump(jump(), target + 1);
+}
+
+void JIT::emit_op_loop_if_less(Instruction* currentInstruction)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    emitTimeoutCheck();
+
+    if (isOperandConstantImmediateInt(op1)) {
+        emitLoad(op2, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(GreaterThan, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3);
+        return;
+    }
+    
+    if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3);
+        return;
+    }
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    addJump(branch32(LessThan, regT0, regT2), target + 3);
+}
+
+void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+        linkSlowCase(iter); // int32 check
+    linkSlowCase(iter); // int32 check
+
+    JITStubCall stubCall(this, cti_op_loop_if_less);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+}
+
+void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    emitTimeoutCheck();
+
+    if (isOperandConstantImmediateInt(op1)) {
+        emitLoad(op2, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target + 3);
+        return;
+    }
+
+    if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target + 3);
+        return;
+    }
+
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    addJump(branch32(LessThanOrEqual, regT0, regT2), target + 3);
+}
+
+void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
+        linkSlowCase(iter); // int32 check
+    linkSlowCase(iter); // int32 check
+
+    JITStubCall stubCall(this, cti_op_loop_if_lesseq);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+}
+
+void JIT::emit_op_new_object(Instruction* currentInstruction)
+{
+    JITStubCall(this, cti_op_new_object).call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_instanceof(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned value = currentInstruction[2].u.operand;
+    unsigned baseVal = currentInstruction[3].u.operand;
+    unsigned proto = currentInstruction[4].u.operand;
+
+    // Load the operands (baseVal, proto, and value respectively) into registers.
+    // We use regT0 for baseVal since we will be done with this first, and we can then use it for the result.
+    emitLoadPayload(proto, regT1);
+    emitLoadPayload(baseVal, regT0);
+    emitLoadPayload(value, regT2);
+
+    // Check that baseVal & proto are cells.
+    emitJumpSlowCaseIfNotJSCell(proto);
+    emitJumpSlowCaseIfNotJSCell(baseVal);
+
+    // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+    addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType))); // FIXME: Maybe remove this test.
+    addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsHasInstance))); // FIXME: TOT checks ImplementsDefaultHasInstance.
+
+    // If value is not an Object, return false.
+    emitLoadTag(value, regT0);
+    Jump valueIsImmediate = branch32(NotEqual, regT0, Imm32(JSValue::CellTag));
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+    Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)); // FIXME: Maybe remove this test.
+
+    // Check proto is object.
+    loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+    addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+
+    // Optimistically load the result true, and start looping.
+    // Initially, regT1 still contains proto and regT2 still contains value.
+    // As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
+    move(Imm32(JSValue::TrueTag), regT0);
+    Label loop(this);
+
+    // Load the prototype of the object in regT2.  If this is equal to regT1 - WIN!
+    // Otherwise, check if we've hit null - if we have then drop out of the loop, if not go again.
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    load32(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
+    Jump isInstance = branchPtr(Equal, regT2, regT1);
+    branch32(NotEqual, regT2, Imm32(0), loop);
+
+    // We get here either by dropping out of the loop, or if value was not an Object.  Result is false.
+    valueIsImmediate.link(this);
+    valueIsNotObject.link(this);
+    move(Imm32(JSValue::FalseTag), regT0);
+
+    // isInstance jumps right down to here, to skip setting the result to false (it has already set true).
+    isInstance.link(this);
+    emitStoreBool(dst, regT0);
+}
+
+void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned value = currentInstruction[2].u.operand;
+    unsigned baseVal = currentInstruction[3].u.operand;
+    unsigned proto = currentInstruction[4].u.operand;
+
+    linkSlowCaseIfNotJSCell(iter, baseVal);
+    linkSlowCaseIfNotJSCell(iter, proto);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_instanceof);
+    stubCall.addArgument(value);
+    stubCall.addArgument(baseVal);
+    stubCall.addArgument(proto);
+    stubCall.call(dst);
+}
+
+void JIT::emit_op_new_func(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_new_func);
+    stubCall.addArgument(ImmPtr(m_codeBlock->function(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_get_global_var(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(currentInstruction[2].u.jsCell);
+    ASSERT(globalObject->isGlobalObject());
+    int index = currentInstruction[3].u.operand;
+
+    loadPtr(&globalObject->d()->registers, regT2);
+
+    emitLoad(index, regT1, regT0, regT2);
+    emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_get_global_var), dst, regT1, regT0);
+}
+
+void JIT::emit_op_put_global_var(Instruction* currentInstruction)
+{
+    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(currentInstruction[1].u.jsCell);
+    ASSERT(globalObject->isGlobalObject());
+    int index = currentInstruction[2].u.operand;
+    int value = currentInstruction[3].u.operand;
+
+    emitLoad(value, regT1, regT0);
+
+    loadPtr(&globalObject->d()->registers, regT2);
+    emitStore(index, regT1, regT0, regT2);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_put_global_var), value, regT1, regT0);
+}
+
+void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int index = currentInstruction[2].u.operand;
+    int skip = currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain();
+
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2);
+    while (skip--)
+        loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
+
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, object)), regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject, d)), regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), regT2);
+
+    emitLoad(index, regT1, regT0, regT2);
+    emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_get_scoped_var), dst, regT1, regT0);
+}
+
+void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
+{
+    int index = currentInstruction[1].u.operand;
+    int skip = currentInstruction[2].u.operand + m_codeBlock->needsFullScopeChain();
+    int value = currentInstruction[3].u.operand;
+
+    emitLoad(value, regT1, regT0);
+
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT2);
+    while (skip--)
+        loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, next)), regT2);
+
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(ScopeChainNode, object)), regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject, d)), regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSVariableObject::JSVariableObjectData, registers)), regT2);
+
+    emitStore(index, regT1, regT0, regT2);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_put_scoped_var), value, regT1, regT0);
+}
+
+void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_tear_off_activation);
+    stubCall.addArgument(currentInstruction[1].u.operand);
+    stubCall.call();
+}
+
+void JIT::emit_op_tear_off_arguments(Instruction*)
+{
+    JITStubCall(this, cti_op_tear_off_arguments).call();
+}
+
+void JIT::emit_op_new_array(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_new_array);
+    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+    stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_resolve(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_resolve);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_to_primitive(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int src = currentInstruction[2].u.operand;
+
+    emitLoad(src, regT1, regT0);
+
+    Jump isImm = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+    addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)));
+    isImm.link(this);
+
+    if (dst != src)
+        emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_to_primitive), dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    int dst = currentInstruction[1].u.operand;
+
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_to_primitive);
+    stubCall.addArgument(regT1, regT0);
+    stubCall.call(dst);
+}
+
+void JIT::emit_op_strcat(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_strcat);
+    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+    stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_loop_if_true(Instruction* currentInstruction)
+{
+    unsigned cond = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    emitTimeoutCheck();
+
+    emitLoad(cond, regT1, regT0);
+
+    Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+    addJump(branch32(NotEqual, regT0, Imm32(0)), target + 2);
+    Jump isNotZero = jump();
+
+    isNotInteger.link(this);
+
+    addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::FalseTag)));
+
+    isNotZero.link(this);
+}
+
+void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned cond = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_jtrue);
+    stubCall.addArgument(cond);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2);
+}
+
+void JIT::emit_op_resolve_base(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_resolve_base);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_resolve_skip(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_resolve_skip);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.addArgument(Imm32(currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain()));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_resolve_global(Instruction* currentInstruction)
+{
+    // FIXME: Optimize to use patching instead of so many memory accesses.
+
+    unsigned dst = currentInstruction[1].u.operand;
+    void* globalObject = currentInstruction[2].u.jsCell;
+    
+    unsigned currentIndex = m_globalResolveInfoIndex++;
+    void* structureAddress = &(m_codeBlock->globalResolveInfo(currentIndex).structure);
+    void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);
+
+    // Verify structure.
+    move(ImmPtr(globalObject), regT0);
+    loadPtr(structureAddress, regT1);
+    addSlowCase(branchPtr(NotEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure))));
+
+    // Load property.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT2);
+    load32(offsetAddr, regT3);
+    load32(BaseIndex(regT2, regT3, TimesEight), regT0); // payload
+    load32(BaseIndex(regT2, regT3, TimesEight, 4), regT1); // tag
+    emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_resolve_global), dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_resolve_global(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    void* globalObject = currentInstruction[2].u.jsCell;
+    Identifier* ident = &m_codeBlock->identifier(currentInstruction[3].u.operand);
+
+    unsigned currentIndex = m_globalResolveInfoIndex++;
+
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_resolve_global);
+    stubCall.addArgument(ImmPtr(globalObject));
+    stubCall.addArgument(ImmPtr(ident));
+    stubCall.addArgument(Imm32(currentIndex));
+    stubCall.call(dst);
+}
+
+void JIT::emit_op_not(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src = currentInstruction[2].u.operand;
+
+    emitLoadTag(src, regT0);
+
+    xor32(Imm32(JSValue::FalseTag), regT0);
+    addSlowCase(branchTest32(NonZero, regT0, Imm32(~1)));
+    xor32(Imm32(JSValue::TrueTag), regT0);
+
+    emitStoreBool(dst, regT0, (dst == src));
+}
+
+void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src = currentInstruction[2].u.operand;
+
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_not);
+    stubCall.addArgument(src);
+    stubCall.call(dst);
+}
+
+void JIT::emit_op_jfalse(Instruction* currentInstruction)
+{
+    unsigned cond = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    emitLoad(cond, regT1, regT0);
+
+    Jump isTrue = branch32(Equal, regT1, Imm32(JSValue::TrueTag));
+    addJump(branch32(Equal, regT1, Imm32(JSValue::FalseTag)), target + 2);
+
+    Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+    Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0));
+    addJump(jump(), target + 2);
+
+    if (supportsFloatingPoint()) {
+        isNotInteger.link(this);
+
+        addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+
+        zeroDouble(fpRegT0);
+        emitLoadDouble(cond, fpRegT1);
+        addJump(branchDouble(DoubleEqual, fpRegT0, fpRegT1), target + 2);
+    } else
+        addSlowCase(isNotInteger);
+
+    isTrue.link(this);
+    isTrue2.link(this);
+}
+
+void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned cond = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_jtrue);
+    stubCall.addArgument(cond);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(Zero, regT0), target + 2); // Inverted.
+}
+
+void JIT::emit_op_jtrue(Instruction* currentInstruction)
+{
+    unsigned cond = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    emitLoad(cond, regT1, regT0);
+
+    Jump isFalse = branch32(Equal, regT1, Imm32(JSValue::FalseTag));
+    addJump(branch32(Equal, regT1, Imm32(JSValue::TrueTag)), target + 2);
+
+    Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+    Jump isFalse2 = branch32(Equal, regT0, Imm32(0));
+    addJump(jump(), target + 2);
+
+    if (supportsFloatingPoint()) {
+        isNotInteger.link(this);
+
+        addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+
+        zeroDouble(fpRegT0);
+        emitLoadDouble(cond, fpRegT1);
+        addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target + 2);
+    } else
+        addSlowCase(isNotInteger);
+
+    isFalse.link(this);
+    isFalse2.link(this);
+}
+
+void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned cond = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_jtrue);
+    stubCall.addArgument(cond);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2);
+}
+
+void JIT::emit_op_jeq_null(Instruction* currentInstruction)
+{
+    unsigned src = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    emitLoad(src, regT1, regT0);
+
+    Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+
+    // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+
+    Jump wasNotImmediate = jump();
+
+    // Now handle the immediate cases - undefined & null
+    isImmediate.link(this);
+
+    set32(Equal, regT1, Imm32(JSValue::NullTag), regT2);
+    set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1);
+    or32(regT2, regT1);
+
+    addJump(branchTest32(NonZero, regT1), target + 2);
+
+    wasNotImmediate.link(this);
+}
+
+void JIT::emit_op_jneq_null(Instruction* currentInstruction)
+{
+    unsigned src = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    emitLoad(src, regT1, regT0);
+
+    Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+
+    // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+
+    Jump wasNotImmediate = jump();
+
+    // Now handle the immediate cases - undefined & null
+    isImmediate.link(this);
+
+    set32(Equal, regT1, Imm32(JSValue::NullTag), regT2);
+    set32(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1);
+    or32(regT2, regT1);
+
+    addJump(branchTest32(Zero, regT1), target + 2);
+
+    wasNotImmediate.link(this);
+}
+
+void JIT::emit_op_jneq_ptr(Instruction* currentInstruction)
+{
+    unsigned src = currentInstruction[1].u.operand;
+    JSCell* ptr = currentInstruction[2].u.jsCell;
+    unsigned target = currentInstruction[3].u.operand;
+
+    emitLoad(src, regT1, regT0);
+    addJump(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)), target + 3);
+    addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target + 3);
+}
+
+void JIT::emit_op_jsr(Instruction* currentInstruction)
+{
+    int retAddrDst = currentInstruction[1].u.operand;
+    int target = currentInstruction[2].u.operand;
+    DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst));
+    addJump(jump(), target + 2);
+    m_jsrSites.append(JSRInfo(storeLocation, label()));
+}
+
+void JIT::emit_op_sret(Instruction* currentInstruction)
+{
+    jump(Address(callFrameRegister, sizeof(Register) * currentInstruction[1].u.operand));
+}
+
+void JIT::emit_op_eq(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src1 = currentInstruction[2].u.operand;
+    unsigned src2 = currentInstruction[3].u.operand;
+    
+    emitLoad2(src1, regT1, regT0, src2, regT3, regT2);
+    addSlowCase(branch32(NotEqual, regT1, regT3));
+    addSlowCase(branch32(Equal, regT1, Imm32(JSValue::CellTag)));
+    addSlowCase(branch32(Below, regT1, Imm32(JSValue::LowestTag)));
+
+    set8(Equal, regT0, regT2, regT0);
+    or32(Imm32(JSValue::FalseTag), regT0);
+
+    emitStoreBool(dst, regT0);
+}
+
+void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    
+    JumpList storeResult;
+    JumpList genericCase;
+    
+    genericCase.append(getSlowCase(iter)); // tags not equal
+
+    linkSlowCase(iter); // tags equal and JSCell
+    genericCase.append(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)));
+    genericCase.append(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsStringVPtr)));
+
+    // String case.
+    JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
+    stubCallEqStrings.addArgument(regT0);
+    stubCallEqStrings.addArgument(regT2);
+    stubCallEqStrings.call();
+    storeResult.append(jump());
+
+    // Generic case.
+    genericCase.append(getSlowCase(iter)); // doubles
+    genericCase.link(this);
+    JITStubCall stubCallEq(this, cti_op_eq);
+    stubCallEq.addArgument(op1);
+    stubCallEq.addArgument(op2);
+    stubCallEq.call(regT0);
+
+    storeResult.link(this);
+    or32(Imm32(JSValue::FalseTag), regT0);
+    emitStoreBool(dst, regT0);
+}
+
+void JIT::emit_op_neq(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src1 = currentInstruction[2].u.operand;
+    unsigned src2 = currentInstruction[3].u.operand;
+    
+    emitLoad2(src1, regT1, regT0, src2, regT3, regT2);
+    addSlowCase(branch32(NotEqual, regT1, regT3));
+    addSlowCase(branch32(Equal, regT1, Imm32(JSValue::CellTag)));
+    addSlowCase(branch32(Below, regT1, Imm32(JSValue::LowestTag)));
+
+    set8(NotEqual, regT0, regT2, regT0);
+    or32(Imm32(JSValue::FalseTag), regT0);
+
+    emitStoreBool(dst, regT0);
+}
+
+void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    
+    JumpList storeResult;
+    JumpList genericCase;
+    
+    genericCase.append(getSlowCase(iter)); // tags not equal
+
+    linkSlowCase(iter); // tags equal and JSCell
+    genericCase.append(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)));
+    genericCase.append(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsStringVPtr)));
+
+    // String case.
+    JITStubCall stubCallEqStrings(this, cti_op_eq_strings);
+    stubCallEqStrings.addArgument(regT0);
+    stubCallEqStrings.addArgument(regT2);
+    stubCallEqStrings.call(regT0);
+    storeResult.append(jump());
+
+    // Generic case.
+    genericCase.append(getSlowCase(iter)); // doubles
+    genericCase.link(this);
+    JITStubCall stubCallEq(this, cti_op_eq);
+    stubCallEq.addArgument(regT1, regT0);
+    stubCallEq.addArgument(regT3, regT2);
+    stubCallEq.call(regT0);
+
+    storeResult.link(this);
+    xor32(Imm32(0x1), regT0);
+    or32(Imm32(JSValue::FalseTag), regT0);
+    emitStoreBool(dst, regT0);
+}
+
+void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqType type)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src1 = currentInstruction[2].u.operand;
+    unsigned src2 = currentInstruction[3].u.operand;
+
+    emitLoadTag(src1, regT0);
+    emitLoadTag(src2, regT1);
+
+    // Jump to a slow case if either operand is double, or if both operands are
+    // cells and/or Int32s.
+    move(regT0, regT2);
+    and32(regT1, regT2);
+    addSlowCase(branch32(Below, regT2, Imm32(JSValue::LowestTag)));
+    addSlowCase(branch32(AboveOrEqual, regT2, Imm32(JSValue::CellTag)));
+
+    if (type == OpStrictEq)
+        set8(Equal, regT0, regT1, regT0);
+    else
+        set8(NotEqual, regT0, regT1, regT0);
+
+    or32(Imm32(JSValue::FalseTag), regT0);
+
+    emitStoreBool(dst, regT0);
+}
+
+void JIT::emit_op_stricteq(Instruction* currentInstruction)
+{
+    compileOpStrictEq(currentInstruction, OpStrictEq);
+}
+
+void JIT::emitSlow_op_stricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src1 = currentInstruction[2].u.operand;
+    unsigned src2 = currentInstruction[3].u.operand;
+
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_stricteq);
+    stubCall.addArgument(src1);
+    stubCall.addArgument(src2);
+    stubCall.call(dst);
+}
+
+void JIT::emit_op_nstricteq(Instruction* currentInstruction)
+{
+    compileOpStrictEq(currentInstruction, OpNStrictEq);
+}
+
+void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src1 = currentInstruction[2].u.operand;
+    unsigned src2 = currentInstruction[3].u.operand;
+
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_nstricteq);
+    stubCall.addArgument(src1);
+    stubCall.addArgument(src2);
+    stubCall.call(dst);
+}
+
+void JIT::emit_op_eq_null(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src = currentInstruction[2].u.operand;
+
+    emitLoad(src, regT1, regT0);
+    Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
+    setTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT1);
+
+    Jump wasNotImmediate = jump();
+
+    isImmediate.link(this);
+
+    set8(Equal, regT1, Imm32(JSValue::NullTag), regT2);
+    set8(Equal, regT1, Imm32(JSValue::UndefinedTag), regT1);
+    or32(regT2, regT1);
+
+    wasNotImmediate.link(this);
+
+    or32(Imm32(JSValue::FalseTag), regT1);
+
+    emitStoreBool(dst, regT1);
+}
+
+void JIT::emit_op_neq_null(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src = currentInstruction[2].u.operand;
+
+    emitLoad(src, regT1, regT0);
+    Jump isImmediate = branch32(NotEqual, regT1, Imm32(JSValue::CellTag));
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
+    setTest8(Zero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT1);
+
+    Jump wasNotImmediate = jump();
+
+    isImmediate.link(this);
+
+    set8(NotEqual, regT1, Imm32(JSValue::NullTag), regT2);
+    set8(NotEqual, regT1, Imm32(JSValue::UndefinedTag), regT1);
+    and32(regT2, regT1);
+
+    wasNotImmediate.link(this);
+
+    or32(Imm32(JSValue::FalseTag), regT1);
+
+    emitStoreBool(dst, regT1);
+}
+
+void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_resolve_with_base);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
+    stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+    stubCall.call(currentInstruction[2].u.operand);
+}
+
+void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_new_func_exp);
+    stubCall.addArgument(ImmPtr(m_codeBlock->functionExpression(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_new_regexp(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_new_regexp);
+    stubCall.addArgument(ImmPtr(m_codeBlock->regexp(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_throw(Instruction* currentInstruction)
+{
+    unsigned exception = currentInstruction[1].u.operand;
+    JITStubCall stubCall(this, cti_op_throw);
+    stubCall.addArgument(exception);
+    stubCall.call();
+
+#ifndef NDEBUG
+    // cti_op_throw always changes it's return address,
+    // this point in the code should never be reached.
+    breakpoint();
+#endif
+}
+
+void JIT::emit_op_next_pname(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int iter = currentInstruction[2].u.operand;
+    int target = currentInstruction[3].u.operand;
+
+    load32(Address(callFrameRegister, (iter * sizeof(Register))), regT0);
+
+    JITStubCall stubCall(this, cti_op_next_pname);
+    stubCall.addArgument(regT0);
+    stubCall.call();
+
+    Jump endOfIter = branchTestPtr(Zero, regT0);
+    emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_next_pname), dst, regT1, regT0);
+    addJump(jump(), target + 3);
+    endOfIter.link(this);
+}
+
+void JIT::emit_op_push_scope(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_push_scope);
+    stubCall.addArgument(currentInstruction[1].u.operand);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_pop_scope(Instruction*)
+{
+    JITStubCall(this, cti_op_pop_scope).call();
+}
+
+void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int src = currentInstruction[2].u.operand;
+
+    emitLoad(src, regT1, regT0);
+
+    Jump isInt32 = branch32(Equal, regT1, Imm32(JSValue::Int32Tag));
+    addSlowCase(branch32(AboveOrEqual, regT1, Imm32(JSValue::DeletedValueTag)));
+    isInt32.link(this);
+
+    if (src != dst)
+        emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_to_jsnumber), dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    int dst = currentInstruction[1].u.operand;
+
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_to_jsnumber);
+    stubCall.addArgument(regT1, regT0);
+    stubCall.call(dst);
+}
+
+void JIT::emit_op_push_new_scope(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_push_new_scope);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.addArgument(currentInstruction[3].u.operand);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_catch(Instruction* currentInstruction)
+{
+    unsigned exception = currentInstruction[1].u.operand;
+
+    // This opcode only executes after a return from cti_op_throw.
+
+    // cti_op_throw may have taken us to a call frame further up the stack; reload
+    // the call frame pointer to adjust.
+    peek(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*));
+
+    // Now store the exception returned by cti_op_throw.
+    emitStore(exception, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_catch), exception, regT1, regT0);
+}
+
+void JIT::emit_op_jmp_scopes(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_jmp_scopes);
+    stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+    stubCall.call();
+    addJump(jump(), currentInstruction[2].u.operand + 2);
+}
+
+void JIT::emit_op_switch_imm(Instruction* currentInstruction)
+{
+    unsigned tableIndex = currentInstruction[1].u.operand;
+    unsigned defaultOffset = currentInstruction[2].u.operand;
+    unsigned scrutinee = currentInstruction[3].u.operand;
+
+    // create jump table for switch destinations, track this switch statement.
+    SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTable(tableIndex);
+    m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Immediate));
+    jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+
+    JITStubCall stubCall(this, cti_op_switch_imm);
+    stubCall.addArgument(scrutinee);
+    stubCall.addArgument(Imm32(tableIndex));
+    stubCall.call();
+    jump(regT0);
+}
+
+void JIT::emit_op_switch_char(Instruction* currentInstruction)
+{
+    unsigned tableIndex = currentInstruction[1].u.operand;
+    unsigned defaultOffset = currentInstruction[2].u.operand;
+    unsigned scrutinee = currentInstruction[3].u.operand;
+
+    // create jump table for switch destinations, track this switch statement.
+    SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTable(tableIndex);
+    m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Character));
+    jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+
+    JITStubCall stubCall(this, cti_op_switch_char);
+    stubCall.addArgument(scrutinee);
+    stubCall.addArgument(Imm32(tableIndex));
+    stubCall.call();
+    jump(regT0);
+}
+
+void JIT::emit_op_switch_string(Instruction* currentInstruction)
+{
+    unsigned tableIndex = currentInstruction[1].u.operand;
+    unsigned defaultOffset = currentInstruction[2].u.operand;
+    unsigned scrutinee = currentInstruction[3].u.operand;
+
+    // create jump table for switch destinations, track this switch statement.
+    StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex);
+    m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset));
+
+    JITStubCall stubCall(this, cti_op_switch_string);
+    stubCall.addArgument(scrutinee);
+    stubCall.addArgument(Imm32(tableIndex));
+    stubCall.call();
+    jump(regT0);
+}
+
+void JIT::emit_op_new_error(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned type = currentInstruction[2].u.operand;
+    unsigned message = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_new_error);
+    stubCall.addArgument(Imm32(type));
+    stubCall.addArgument(m_codeBlock->getConstant(message));
+    stubCall.addArgument(Imm32(m_bytecodeIndex));
+    stubCall.call(dst);
+}
+
+void JIT::emit_op_debug(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_debug);
+    stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+    stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+    stubCall.call();
+}
+
+
+void JIT::emit_op_enter(Instruction*)
+{
+    // Even though JIT code doesn't use them, we initialize our constant
+    // registers to zap stale pointers, to avoid unnecessarily prolonging
+    // object lifetime and increasing GC pressure.
+    for (int i = 0; i < m_codeBlock->m_numVars; ++i)
+        emitStore(i, jsUndefined());
+}
+
+void JIT::emit_op_enter_with_activation(Instruction* currentInstruction)
+{
+    emit_op_enter(currentInstruction);
+
+    JITStubCall(this, cti_op_push_activation).call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_create_arguments(Instruction*)
+{
+    Jump argsNotCell = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::CellTag));
+    Jump argsNotNull = branchTestPtr(NonZero, payloadFor(RegisterFile::ArgumentsRegister, callFrameRegister));
+
+    // If we get here the arguments pointer is a null cell - i.e. arguments need lazy creation.
+    if (m_codeBlock->m_numParameters == 1)
+        JITStubCall(this, cti_op_create_arguments_no_params).call();
+    else
+        JITStubCall(this, cti_op_create_arguments).call();
+
+    argsNotCell.link(this);
+    argsNotNull.link(this);
+}
+    
+void JIT::emit_op_init_arguments(Instruction*)
+{
+    emitStore(RegisterFile::ArgumentsRegister, JSValue(), callFrameRegister);
+}
+
+void JIT::emit_op_convert_this(Instruction* currentInstruction)
+{
+    unsigned thisRegister = currentInstruction[1].u.operand;
+    
+    emitLoad(thisRegister, regT1, regT0);
+
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    addSlowCase(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_convert_this), thisRegister, regT1, regT0);
+}
+
+void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned thisRegister = currentInstruction[1].u.operand;
+
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_convert_this);
+    stubCall.addArgument(regT1, regT0);
+    stubCall.call(thisRegister);
+}
+
+void JIT::emit_op_profile_will_call(Instruction* currentInstruction)
+{
+    peek(regT2, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*));
+    Jump noProfiler = branchTestPtr(Zero, Address(regT2));
+
+    JITStubCall stubCall(this, cti_op_profile_will_call);
+    stubCall.addArgument(currentInstruction[1].u.operand);
+    stubCall.call();
+    noProfiler.link(this);
+}
+
+void JIT::emit_op_profile_did_call(Instruction* currentInstruction)
+{
+    peek(regT2, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*));
+    Jump noProfiler = branchTestPtr(Zero, Address(regT2));
+
+    JITStubCall stubCall(this, cti_op_profile_did_call);
+    stubCall.addArgument(currentInstruction[1].u.operand);
+    stubCall.call();
+    noProfiler.link(this);
+}
+
+#else // USE(JSVALUE32_64)
+
+#define RECORD_JUMP_TARGET(targetOffset) \
+   do { m_labels[m_bytecodeIndex + (targetOffset)].used(); } while (false)
+
+void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallPreLink, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
+{
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+    // (2) The second function provides fast property access for string length
+    Label stringLengthBegin = align();
+
+    // Check eax is a string
+    Jump string_failureCases1 = emitJumpIfNotJSCell(regT0);
+    Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
+
+    // Checks out okay! - get the length from the Ustring.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSString, m_value) + OBJECT_OFFSETOF(UString, m_rep)), regT0);
+    load32(Address(regT0, OBJECT_OFFSETOF(UString::Rep, len)), regT0);
+
+    Jump string_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt));
+
+    // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
+    emitFastArithIntToImmNoCheck(regT0, regT0);
+    
+    ret();
+#endif
+
+    // (3) Trampolines for the slow cases of op_call / op_call_eval / op_construct.
+    COMPILE_ASSERT(sizeof(CodeType) == 4, CodeTypeEnumMustBe32Bit);
+
+    Label virtualCallPreLinkBegin = align();
+
+    // Load the callee CodeBlock* into eax
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3);
+    loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT0);
+    Jump hasCodeBlock1 = branchTestPtr(NonZero, regT0);
+    preserveReturnAddressAfterCall(regT3);
+    restoreArgumentReference();
+    Call callJSFunction1 = call();
+    emitGetJITStubArg(1, regT2);
+    emitGetJITStubArg(3, regT1);
+    restoreReturnAddressBeforeReturn(regT3);
+    hasCodeBlock1.link(this);
+
+    Jump isNativeFunc1 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
+
+    // Check argCount matches callee arity.
+    Jump arityCheckOkay1 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 2);
+    emitPutJITStubArg(regT0, 4);
+    restoreArgumentReference();
+    Call callArityCheck1 = call();
+    move(regT1, callFrameRegister);
+    emitGetJITStubArg(1, regT2);
+    emitGetJITStubArg(3, regT1);
+    restoreReturnAddressBeforeReturn(regT3);
+    arityCheckOkay1.link(this);
+    isNativeFunc1.link(this);
+    
+    compileOpCallInitializeCallFrame();
+
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 2);
+    restoreArgumentReference();
+    Call callDontLazyLinkCall = call();
+    emitGetJITStubArg(1, regT2);
+    restoreReturnAddressBeforeReturn(regT3);
+
+    jump(regT0);
+
+    Label virtualCallLinkBegin = align();
+
+    // Load the callee CodeBlock* into eax
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3);
+    loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT0);
+    Jump hasCodeBlock2 = branchTestPtr(NonZero, regT0);
+    preserveReturnAddressAfterCall(regT3);
+    restoreArgumentReference();
+    Call callJSFunction2 = call();
+    emitGetJITStubArg(1, regT2);
+    emitGetJITStubArg(3, regT1);
+    restoreReturnAddressBeforeReturn(regT3);
+    hasCodeBlock2.link(this);
+
+    Jump isNativeFunc2 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
+
+    // Check argCount matches callee arity.
+    Jump arityCheckOkay2 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 2);
+    emitPutJITStubArg(regT0, 4);
+    restoreArgumentReference();
+    Call callArityCheck2 = call();
+    move(regT1, callFrameRegister);
+    emitGetJITStubArg(1, regT2);
+    emitGetJITStubArg(3, regT1);
+    restoreReturnAddressBeforeReturn(regT3);
+    arityCheckOkay2.link(this);
+    isNativeFunc2.link(this);
+
+    compileOpCallInitializeCallFrame();
+
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 2);
+    restoreArgumentReference();
+    Call callLazyLinkCall = call();
+    restoreReturnAddressBeforeReturn(regT3);
+
+    jump(regT0);
+
+    Label virtualCallBegin = align();
+
+    // Load the callee CodeBlock* into eax
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3);
+    loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionBodyNode, m_code)), regT0);
+    Jump hasCodeBlock3 = branchTestPtr(NonZero, regT0);
+    preserveReturnAddressAfterCall(regT3);
+    restoreArgumentReference();
+    Call callJSFunction3 = call();
+    emitGetJITStubArg(1, regT2);
+    emitGetJITStubArg(3, regT1);
+    restoreReturnAddressBeforeReturn(regT3);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3); // reload the function body nody, so we can reload the code pointer.
+    hasCodeBlock3.link(this);
+    
+    Jump isNativeFunc3 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_codeType)), Imm32(NativeCode));
+
+    // Check argCount matches callee arity.
+    Jump arityCheckOkay3 = branch32(Equal, Address(regT0, OBJECT_OFFSETOF(CodeBlock, m_numParameters)), regT1);
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 2);
+    emitPutJITStubArg(regT0, 4);
+    restoreArgumentReference();
+    Call callArityCheck3 = call();
+    move(regT1, callFrameRegister);
+    emitGetJITStubArg(1, regT2);
+    emitGetJITStubArg(3, regT1);
+    restoreReturnAddressBeforeReturn(regT3);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_body)), regT3); // reload the function body nody, so we can reload the code pointer.
+    arityCheckOkay3.link(this);
+    isNativeFunc3.link(this);
+
+    // load ctiCode from the new codeBlock.
+    loadPtr(Address(regT3, OBJECT_OFFSETOF(FunctionBodyNode, m_jitCode)), regT0);
+    
+    compileOpCallInitializeCallFrame();
+    jump(regT0);
+
+    
+    Label nativeCallThunk = align();
+    preserveReturnAddressAfterCall(regT0);
+    emitPutToCallFrameHeader(regT0, RegisterFile::ReturnPC); // Push return address
+
+    // Load caller frame's scope chain into this callframe so that whatever we call can
+    // get to its global data.
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT1);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT1);
+    emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
+    
+
+#if PLATFORM(X86_64)
+    emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, X86::ecx);
+
+    // Allocate stack space for our arglist
+    subPtr(Imm32(sizeof(ArgList)), stackPointerRegister);
+    COMPILE_ASSERT((sizeof(ArgList) & 0xf) == 0, ArgList_should_by_16byte_aligned);
+    
+    // Set up arguments
+    subPtr(Imm32(1), X86::ecx); // Don't include 'this' in argcount
+
+    // Push argcount
+    storePtr(X86::ecx, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_argCount)));
+
+    // Calculate the start of the callframe header, and store in edx
+    addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * (int32_t)sizeof(Register)), callFrameRegister, X86::edx);
+    
+    // Calculate start of arguments as callframe header - sizeof(Register) * argcount (ecx)
+    mul32(Imm32(sizeof(Register)), X86::ecx, X86::ecx);
+    subPtr(X86::ecx, X86::edx);
+
+    // push pointer to arguments
+    storePtr(X86::edx, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_args)));
+    
+    // ArgList is passed by reference so is stackPointerRegister
+    move(stackPointerRegister, X86::ecx);
+    
+    // edx currently points to the first argument, edx-sizeof(Register) points to 'this'
+    loadPtr(Address(X86::edx, -(int32_t)sizeof(Register)), X86::edx);
+    
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86::esi);
+
+    move(callFrameRegister, X86::edi); 
+
+    call(Address(X86::esi, OBJECT_OFFSETOF(JSFunction, m_data)));
+    
+    addPtr(Imm32(sizeof(ArgList)), stackPointerRegister);
+#elif PLATFORM(X86)
+    emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+
+    /* We have two structs that we use to describe the stackframe we set up for our
+     * call to native code.  NativeCallFrameStructure describes the how we set up the stack
+     * in advance of the call.  NativeFunctionCalleeSignature describes the callframe
+     * as the native code expects it.  We do this as we are using the fastcall calling
+     * convention which results in the callee popping its arguments off the stack, but
+     * not the rest of the callframe so we need a nice way to ensure we increment the
+     * stack pointer by the right amount after the call.
+     */
+#if COMPILER(MSVC) || PLATFORM(LINUX)
+    struct NativeCallFrameStructure {
+      //  CallFrame* callFrame; // passed in EDX
+        JSObject* callee;
+        JSValue thisValue;
+        ArgList* argPointer;
+        ArgList args;
+        JSValue result;
+    };
+    struct NativeFunctionCalleeSignature {
+        JSObject* callee;
+        JSValue thisValue;
+        ArgList* argPointer;
+    };
+#else
+    struct NativeCallFrameStructure {
+      //  CallFrame* callFrame; // passed in ECX
+      //  JSObject* callee; // passed in EDX
+        JSValue thisValue;
+        ArgList* argPointer;
+        ArgList args;
+    };
+    struct NativeFunctionCalleeSignature {
+        JSValue thisValue;
+        ArgList* argPointer;
+    };
+#endif
+    const int NativeCallFrameSize = (sizeof(NativeCallFrameStructure) + 15) & ~15;
+    // Allocate system stack frame
+    subPtr(Imm32(NativeCallFrameSize), stackPointerRegister);
+
+    // Set up arguments
+    subPtr(Imm32(1), regT0); // Don't include 'this' in argcount
+
+    // push argcount
+    storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_argCount)));
+    
+    // Calculate the start of the callframe header, and store in regT1
+    addPtr(Imm32(-RegisterFile::CallFrameHeaderSize * (int)sizeof(Register)), callFrameRegister, regT1);
+    
+    // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT0)
+    mul32(Imm32(sizeof(Register)), regT0, regT0);
+    subPtr(regT0, regT1);
+    storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, args) + OBJECT_OFFSETOF(ArgList, m_args)));
+
+    // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register)
+    addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, args)), stackPointerRegister, regT0);
+    storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, argPointer)));
+
+    // regT1 currently points to the first argument, regT1 - sizeof(Register) points to 'this'
+    loadPtr(Address(regT1, -(int)sizeof(Register)), regT1);
+    storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, thisValue)));
+
+#if COMPILER(MSVC) || PLATFORM(LINUX)
+    // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register)
+    addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86::ecx);
+
+    // Plant callee
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86::eax);
+    storePtr(X86::eax, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, callee)));
+
+    // Plant callframe
+    move(callFrameRegister, X86::edx);
+
+    call(Address(X86::eax, OBJECT_OFFSETOF(JSFunction, m_data)));
+
+    // JSValue is a non-POD type
+    loadPtr(Address(X86::eax), X86::eax);
+#else
+    // Plant callee
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86::edx);
+
+    // Plant callframe
+    move(callFrameRegister, X86::ecx);
+    call(Address(X86::edx, OBJECT_OFFSETOF(JSFunction, m_data)));
+#endif
+
+    // We've put a few temporaries on the stack in addition to the actual arguments
+    // so pull them off now
+    addPtr(Imm32(NativeCallFrameSize - sizeof(NativeFunctionCalleeSignature)), stackPointerRegister);
+
+#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
+#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
+#else
+    breakpoint();
+#endif
+
+    // Check for an exception
+    loadPtr(&(globalData->exception), regT2);
+    Jump exceptionHandler = branchTestPtr(NonZero, regT2);
+
+    // Grab the return address.
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
+    
+    // Restore our caller's "r".
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
+    
+    // Return.
+    restoreReturnAddressBeforeReturn(regT1);
+    ret();
+
+    // Handle an exception
+    exceptionHandler.link(this);
+    // Grab the return address.
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
+    move(ImmPtr(&globalData->exceptionLocation), regT2);
+    storePtr(regT1, regT2);
+    move(ImmPtr(reinterpret_cast<void*>(ctiVMThrowTrampoline)), regT2);
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
+    poke(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*));
+    restoreReturnAddressBeforeReturn(regT2);
+    ret();
+    
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+    Call string_failureCases1Call = makeTailRecursiveCall(string_failureCases1);
+    Call string_failureCases2Call = makeTailRecursiveCall(string_failureCases2);
+    Call string_failureCases3Call = makeTailRecursiveCall(string_failureCases3);
+#endif
+
+    // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
+    LinkBuffer patchBuffer(this, m_globalData->executableAllocator.poolForSize(m_assembler.size()));
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+    patchBuffer.link(string_failureCases1Call, FunctionPtr(cti_op_get_by_id_string_fail));
+    patchBuffer.link(string_failureCases2Call, FunctionPtr(cti_op_get_by_id_string_fail));
+    patchBuffer.link(string_failureCases3Call, FunctionPtr(cti_op_get_by_id_string_fail));
+#endif
+    patchBuffer.link(callArityCheck1, FunctionPtr(cti_op_call_arityCheck));
+    patchBuffer.link(callArityCheck2, FunctionPtr(cti_op_call_arityCheck));
+    patchBuffer.link(callArityCheck3, FunctionPtr(cti_op_call_arityCheck));
+    patchBuffer.link(callJSFunction1, FunctionPtr(cti_op_call_JSFunction));
+    patchBuffer.link(callJSFunction2, FunctionPtr(cti_op_call_JSFunction));
+    patchBuffer.link(callJSFunction3, FunctionPtr(cti_op_call_JSFunction));
+    patchBuffer.link(callDontLazyLinkCall, FunctionPtr(cti_vm_dontLazyLinkCall));
+    patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall));
+
+    CodeRef finalCode = patchBuffer.finalizeCode();
+    *executablePool = finalCode.m_executablePool;
+
+    *ctiVirtualCallPreLink = trampolineAt(finalCode, virtualCallPreLinkBegin);
+    *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
+    *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
+    *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk);
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+    *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
+#else
+    UNUSED_PARAM(ctiStringLengthTrampoline);
+#endif
+}
+
+void JIT::emit_op_mov(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int src = currentInstruction[2].u.operand;
+
+    if (m_codeBlock->isConstantRegisterIndex(src)) {
+        storePtr(ImmPtr(JSValue::encode(getConstantOperand(src))), Address(callFrameRegister, dst * sizeof(Register)));
+        if (dst == m_lastResultBytecodeRegister)
+            killLastResultRegister();
+    } else if ((src == m_lastResultBytecodeRegister) || (dst == m_lastResultBytecodeRegister)) {
+        // If either the src or dst is the cached register go though
+        // get/put registers to make sure we track this correctly.
+        emitGetVirtualRegister(src, regT0);
+        emitPutVirtualRegister(dst);
+    } else {
+        // Perform the copy via regT1; do not disturb any mapping in regT0.
+        loadPtr(Address(callFrameRegister, src * sizeof(Register)), regT1);
+        storePtr(regT1, Address(callFrameRegister, dst * sizeof(Register)));
+    }
+}
+
+void JIT::emit_op_end(Instruction* currentInstruction)
+{
+    if (m_codeBlock->needsFullScopeChain())
+        JITStubCall(this, cti_op_end).call();
+    ASSERT(returnValueRegister != callFrameRegister);
+    emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
+    restoreReturnAddressBeforeReturn(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register))));
+    ret();
+}
+
+void JIT::emit_op_jmp(Instruction* currentInstruction)
+{
+    unsigned target = currentInstruction[1].u.operand;
+    addJump(jump(), target + 1);
+    RECORD_JUMP_TARGET(target + 1);
+}
+
+void JIT::emit_op_loop(Instruction* currentInstruction)
+{
+    emitTimeoutCheck();
+
+    unsigned target = currentInstruction[1].u.operand;
+    addJump(jump(), target + 1);
+}
+
+void JIT::emit_op_loop_if_less(Instruction* currentInstruction)
+{
+    emitTimeoutCheck();
+
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+    if (isOperandConstantImmediateInt(op2)) {
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+        int32_t op2imm = getConstantOperandImmediateInt(op2);
+#else
+        int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
+#endif
+        addJump(branch32(LessThan, regT0, Imm32(op2imm)), target + 3);
+    } else if (isOperandConstantImmediateInt(op1)) {
+        emitGetVirtualRegister(op2, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+        int32_t op1imm = getConstantOperandImmediateInt(op1);
+#else
+        int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
+#endif
+        addJump(branch32(GreaterThan, regT0, Imm32(op1imm)), target + 3);
+    } else {
+        emitGetVirtualRegisters(op1, regT0, op2, regT1);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT1);
+        addJump(branch32(LessThan, regT0, regT1), target + 3);
+    }
+}
+
+void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
+{
+    emitTimeoutCheck();
+
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+    if (isOperandConstantImmediateInt(op2)) {
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+        int32_t op2imm = getConstantOperandImmediateInt(op2);
+#else
+        int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
+#endif
+        addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target + 3);
+    } else {
+        emitGetVirtualRegisters(op1, regT0, op2, regT1);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT1);
+        addJump(branch32(LessThanOrEqual, regT0, regT1), target + 3);
+    }
+}
+
+void JIT::emit_op_new_object(Instruction* currentInstruction)
+{
+    JITStubCall(this, cti_op_new_object).call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_instanceof(Instruction* currentInstruction)
+{
+    // Load the operands (baseVal, proto, and value respectively) into registers.
+    // We use regT0 for baseVal since we will be done with this first, and we can then use it for the result.
+    emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
+    emitGetVirtualRegister(currentInstruction[4].u.operand, regT1);
+    emitGetVirtualRegister(currentInstruction[2].u.operand, regT2);
+
+    // Check that baseVal & proto are cells.
+    emitJumpSlowCaseIfNotJSCell(regT0);
+    emitJumpSlowCaseIfNotJSCell(regT1);
+
+    // Check that baseVal is an object, that it 'ImplementsHasInstance' but that it does not 'OverridesHasInstance'.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+    addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+    addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
+
+    // If value is not an Object, return false.
+    Jump valueIsImmediate = emitJumpIfNotJSCell(regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+    Jump valueIsNotObject = branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType));
+
+    // Check proto is object.
+    loadPtr(Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+    addSlowCase(branch32(NotEqual, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+
+    // Optimistically load the result true, and start looping.
+    // Initially, regT1 still contains proto and regT2 still contains value.
+    // As we loop regT2 will be updated with its prototype, recursively walking the prototype chain.
+    move(ImmPtr(JSValue::encode(jsBoolean(true))), regT0);
+    Label loop(this);
+
+    // Load the prototype of the object in regT2.  If this is equal to regT1 - WIN!
+    // Otherwise, check if we've hit null - if we have then drop out of the loop, if not go again.
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
+    Jump isInstance = branchPtr(Equal, regT2, regT1);
+    branchPtr(NotEqual, regT2, ImmPtr(JSValue::encode(jsNull())), loop);
+
+    // We get here either by dropping out of the loop, or if value was not an Object.  Result is false.
+    valueIsImmediate.link(this);
+    valueIsNotObject.link(this);
+    move(ImmPtr(JSValue::encode(jsBoolean(false))), regT0);
+
+    // isInstance jumps right down to here, to skip setting the result to false (it has already set true).
+    isInstance.link(this);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_new_func(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_new_func);
+    stubCall.addArgument(ImmPtr(m_codeBlock->function(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_call(Instruction* currentInstruction)
+{
+    compileOpCall(op_call, currentInstruction, m_callLinkInfoIndex++);
+}
+
+void JIT::emit_op_call_eval(Instruction* currentInstruction)
+{
+    compileOpCall(op_call_eval, currentInstruction, m_callLinkInfoIndex++);
+}
+
+void JIT::emit_op_load_varargs(Instruction* currentInstruction)
+{
+    int argCountDst = currentInstruction[1].u.operand;
+    int argsOffset = currentInstruction[2].u.operand;
+
+    JITStubCall stubCall(this, cti_op_load_varargs);
+    stubCall.addArgument(Imm32(argsOffset));
+    stubCall.call();
+    // Stores a naked int32 in the register file.
+    store32(returnValueRegister, Address(callFrameRegister, argCountDst * sizeof(Register)));
+}
+
+void JIT::emit_op_call_varargs(Instruction* currentInstruction)
+{
+    compileOpCallVarargs(currentInstruction);
+}
+
+void JIT::emit_op_construct(Instruction* currentInstruction)
+{
+    compileOpCall(op_construct, currentInstruction, m_callLinkInfoIndex++);
+}
+
+void JIT::emit_op_get_global_var(Instruction* currentInstruction)
+{
+    JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[2].u.jsCell);
+    move(ImmPtr(globalObject), regT0);
+    emitGetVariableObjectRegister(regT0, currentInstruction[3].u.operand, regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_put_global_var(Instruction* currentInstruction)
+{
+    emitGetVirtualRegister(currentInstruction[3].u.operand, regT1);
+    JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[1].u.jsCell);
+    move(ImmPtr(globalObject), regT0);
+    emitPutVariableObjectRegister(regT1, regT0, currentInstruction[2].u.operand);
+}
+
+void JIT::emit_op_get_scoped_var(Instruction* currentInstruction)
+{
+    int skip = currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain();
+
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT0);
+    while (skip--)
+        loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, next)), regT0);
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, object)), regT0);
+    emitGetVariableObjectRegister(regT0, currentInstruction[2].u.operand, regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_put_scoped_var(Instruction* currentInstruction)
+{
+    int skip = currentInstruction[2].u.operand + m_codeBlock->needsFullScopeChain();
+
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1);
+    emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
+    while (skip--)
+        loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, next)), regT1);
+
+    loadPtr(Address(regT1, OBJECT_OFFSETOF(ScopeChainNode, object)), regT1);
+    emitPutVariableObjectRegister(regT0, regT1, currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_tear_off_activation(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_tear_off_activation);
+    stubCall.addArgument(currentInstruction[1].u.operand, regT2);
+    stubCall.call();
+}
+
+void JIT::emit_op_tear_off_arguments(Instruction*)
+{
+    JITStubCall(this, cti_op_tear_off_arguments).call();
+}
+
+void JIT::emit_op_ret(Instruction* currentInstruction)
+{
+    // We could JIT generate the deref, only calling out to C when the refcount hits zero.
+    if (m_codeBlock->needsFullScopeChain())
+        JITStubCall(this, cti_op_ret_scopeChain).call();
+
+    ASSERT(callFrameRegister != regT1);
+    ASSERT(regT1 != returnValueRegister);
+    ASSERT(returnValueRegister != callFrameRegister);
+
+    // Return the result in %eax.
+    emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
+
+    // Grab the return address.
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
+
+    // Restore our caller's "r".
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
+
+    // Return.
+    restoreReturnAddressBeforeReturn(regT1);
+    ret();
+}
+
+void JIT::emit_op_new_array(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_new_array);
+    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+    stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_resolve(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_resolve);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_construct_verify(Instruction* currentInstruction)
+{
+    emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+
+    emitJumpSlowCaseIfNotJSCell(regT0);
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    addSlowCase(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType)));
+
+}
+
+void JIT::emit_op_to_primitive(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int src = currentInstruction[2].u.operand;
+
+    emitGetVirtualRegister(src, regT0);
+    
+    Jump isImm = emitJumpIfNotJSCell(regT0);
+    addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr)));
+    isImm.link(this);
+
+    if (dst != src)
+        emitPutVirtualRegister(dst);
+
+}
+
+void JIT::emit_op_strcat(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_strcat);
+    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+    stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_loop_if_true(Instruction* currentInstruction)
+{
+    emitTimeoutCheck();
+
+    unsigned target = currentInstruction[2].u.operand;
+    emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+
+    Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0))));
+    addJump(emitJumpIfImmediateInteger(regT0), target + 2);
+
+    addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2);
+    addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))));
+
+    isZero.link(this);
+};
+void JIT::emit_op_resolve_base(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_resolve_base);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_resolve_skip(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_resolve_skip);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.addArgument(Imm32(currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain()));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_resolve_global(Instruction* currentInstruction)
+{
+    // Fast case
+    void* globalObject = currentInstruction[2].u.jsCell;
+    Identifier* ident = &m_codeBlock->identifier(currentInstruction[3].u.operand);
+    
+    unsigned currentIndex = m_globalResolveInfoIndex++;
+    void* structureAddress = &(m_codeBlock->globalResolveInfo(currentIndex).structure);
+    void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);
+
+    // Check Structure of global object
+    move(ImmPtr(globalObject), regT0);
+    loadPtr(structureAddress, regT1);
+    Jump noMatch = branchPtr(NotEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure))); // Structures don't match
+
+    // Load cached property
+    // Assume that the global object always uses external storage.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSGlobalObject, m_externalStorage)), regT0);
+    load32(offsetAddr, regT1);
+    loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+    Jump end = jump();
+
+    // Slow case
+    noMatch.link(this);
+    JITStubCall stubCall(this, cti_op_resolve_global);
+    stubCall.addArgument(ImmPtr(globalObject));
+    stubCall.addArgument(ImmPtr(ident));
+    stubCall.addArgument(Imm32(currentIndex));
+    stubCall.call(currentInstruction[1].u.operand);
+    end.link(this);
+}
+
+void JIT::emit_op_not(Instruction* currentInstruction)
+{
+    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
+    xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
+    addSlowCase(branchTestPtr(NonZero, regT0, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
+    xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_jfalse(Instruction* currentInstruction)
+{
+    unsigned target = currentInstruction[2].u.operand;
+    emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+
+    addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0)))), target + 2);
+    Jump isNonZero = emitJumpIfImmediateInteger(regT0);
+
+    addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))), target + 2);
+    addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))));
+
+    isNonZero.link(this);
+    RECORD_JUMP_TARGET(target + 2);
+};
+void JIT::emit_op_jeq_null(Instruction* currentInstruction)
+{
+    unsigned src = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    emitGetVirtualRegister(src, regT0);
+    Jump isImmediate = emitJumpIfNotJSCell(regT0);
+
+    // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    addJump(branchTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+    Jump wasNotImmediate = jump();
+
+    // Now handle the immediate cases - undefined & null
+    isImmediate.link(this);
+    andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+    addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2);            
+
+    wasNotImmediate.link(this);
+    RECORD_JUMP_TARGET(target + 2);
+};
+void JIT::emit_op_jneq_null(Instruction* currentInstruction)
+{
+    unsigned src = currentInstruction[1].u.operand;
+    unsigned target = currentInstruction[2].u.operand;
+
+    emitGetVirtualRegister(src, regT0);
+    Jump isImmediate = emitJumpIfNotJSCell(regT0);
+
+    // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    addJump(branchTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
+    Jump wasNotImmediate = jump();
+
+    // Now handle the immediate cases - undefined & null
+    isImmediate.link(this);
+    andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+    addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsNull()))), target + 2);            
+
+    wasNotImmediate.link(this);
+    RECORD_JUMP_TARGET(target + 2);
+}
+
+void JIT::emit_op_jneq_ptr(Instruction* currentInstruction)
+{
+    unsigned src = currentInstruction[1].u.operand;
+    JSCell* ptr = currentInstruction[2].u.jsCell;
+    unsigned target = currentInstruction[3].u.operand;
+    
+    emitGetVirtualRegister(src, regT0);
+    addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(JSValue(ptr)))), target + 3);            
+
+    RECORD_JUMP_TARGET(target + 3);
+}
+
+void JIT::emit_op_jsr(Instruction* currentInstruction)
+{
+    int retAddrDst = currentInstruction[1].u.operand;
+    int target = currentInstruction[2].u.operand;
+    DataLabelPtr storeLocation = storePtrWithPatch(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * retAddrDst));
+    addJump(jump(), target + 2);
+    m_jsrSites.append(JSRInfo(storeLocation, label()));
+    killLastResultRegister();
+    RECORD_JUMP_TARGET(target + 2);
+}
+
+void JIT::emit_op_sret(Instruction* currentInstruction)
+{
+    jump(Address(callFrameRegister, sizeof(Register) * currentInstruction[1].u.operand));
+    killLastResultRegister();
+}
+
+void JIT::emit_op_eq(Instruction* currentInstruction)
+{
+    emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+    emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
+    set32(Equal, regT1, regT0, regT0);
+    emitTagAsBoolImmediate(regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_bitnot(Instruction* currentInstruction)
+{
+    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
+    emitJumpSlowCaseIfNotImmediateInteger(regT0);
+#if USE(JSVALUE64)
+    not32(regT0);
+    emitFastArithIntToImmNoCheck(regT0, regT0);
+#else
+    xorPtr(Imm32(~JSImmediate::TagTypeNumber), regT0);
+#endif
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_resolve_with_base);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
+    stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+    stubCall.call(currentInstruction[2].u.operand);
+}
+
+void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_new_func_exp);
+    stubCall.addArgument(ImmPtr(m_codeBlock->functionExpression(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_jtrue(Instruction* currentInstruction)
+{
+    unsigned target = currentInstruction[2].u.operand;
+    emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+
+    Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsNumber(m_globalData, 0))));
+    addJump(emitJumpIfImmediateInteger(regT0), target + 2);
+
+    addJump(branchPtr(Equal, regT0, ImmPtr(JSValue::encode(jsBoolean(true)))), target + 2);
+    addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValue::encode(jsBoolean(false)))));
+
+    isZero.link(this);
+    RECORD_JUMP_TARGET(target + 2);
+}
+
+void JIT::emit_op_neq(Instruction* currentInstruction)
+{
+    emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+    emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
+    set32(NotEqual, regT1, regT0, regT0);
+    emitTagAsBoolImmediate(regT0);
+
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+
+}
+
+void JIT::emit_op_bitxor(Instruction* currentInstruction)
+{
+    emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+    emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
+    xorPtr(regT1, regT0);
+    emitFastArithReTagImmediate(regT0, regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_new_regexp(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_new_regexp);
+    stubCall.addArgument(ImmPtr(m_codeBlock->regexp(currentInstruction[2].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_bitor(Instruction* currentInstruction)
+{
+    emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+    emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
+    orPtr(regT1, regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_throw(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_throw);
+    stubCall.addArgument(currentInstruction[1].u.operand, regT2);
+    stubCall.call();
+    ASSERT(regT0 == returnValueRegister);
+#ifndef NDEBUG
+    // cti_op_throw always changes it's return address,
+    // this point in the code should never be reached.
+    breakpoint();
+#endif
+}
+
+void JIT::emit_op_next_pname(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_next_pname);
+    stubCall.addArgument(currentInstruction[2].u.operand, regT2);
+    stubCall.call();
+    Jump endOfIter = branchTestPtr(Zero, regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+    addJump(jump(), currentInstruction[3].u.operand + 3);
+    endOfIter.link(this);
+}
+
+void JIT::emit_op_push_scope(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_push_scope);
+    stubCall.addArgument(currentInstruction[1].u.operand, regT2);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_pop_scope(Instruction*)
+{
+    JITStubCall(this, cti_op_pop_scope).call();
+}
+
+void JIT::compileOpStrictEq(Instruction* currentInstruction, CompileOpStrictEqType type)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src1 = currentInstruction[2].u.operand;
+    unsigned src2 = currentInstruction[3].u.operand;
+
+    emitGetVirtualRegisters(src1, regT0, src2, regT1);
+
+    // Jump to a slow case if either operand is a number, or if both are JSCell*s.
+    move(regT0, regT2);
+    orPtr(regT1, regT2);
+    addSlowCase(emitJumpIfJSCell(regT2));
+    addSlowCase(emitJumpIfImmediateNumber(regT2));
+
+    if (type == OpStrictEq)
+        set32(Equal, regT1, regT0, regT0);
+    else
+        set32(NotEqual, regT1, regT0, regT0);
+    emitTagAsBoolImmediate(regT0);
+
+    emitPutVirtualRegister(dst);
+}
+
+void JIT::emit_op_stricteq(Instruction* currentInstruction)
+{
+    compileOpStrictEq(currentInstruction, OpStrictEq);
+}
+
+void JIT::emit_op_nstricteq(Instruction* currentInstruction)
+{
+    compileOpStrictEq(currentInstruction, OpNStrictEq);
+}
+
+void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
+{
+    int srcVReg = currentInstruction[2].u.operand;
+    emitGetVirtualRegister(srcVReg, regT0);
+    
+    Jump wasImmediate = emitJumpIfImmediateInteger(regT0);
+
+    emitJumpSlowCaseIfNotJSCell(regT0, srcVReg);
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    addSlowCase(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(NumberType)));
+    
+    wasImmediate.link(this);
+
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_push_new_scope(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_push_new_scope);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.addArgument(currentInstruction[3].u.operand, regT2);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_catch(Instruction* currentInstruction)
+{
+    killLastResultRegister(); // FIXME: Implicitly treat op_catch as a labeled statement, and remove this line of code.
+    peek(callFrameRegister, OBJECT_OFFSETOF(struct JITStackFrame, callFrame) / sizeof (void*));
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_jmp_scopes(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_jmp_scopes);
+    stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+    stubCall.call();
+    addJump(jump(), currentInstruction[2].u.operand + 2);
+    RECORD_JUMP_TARGET(currentInstruction[2].u.operand + 2);
+}
+
+void JIT::emit_op_switch_imm(Instruction* currentInstruction)
+{
+    unsigned tableIndex = currentInstruction[1].u.operand;
+    unsigned defaultOffset = currentInstruction[2].u.operand;
+    unsigned scrutinee = currentInstruction[3].u.operand;
+
+    // create jump table for switch destinations, track this switch statement.
+    SimpleJumpTable* jumpTable = &m_codeBlock->immediateSwitchJumpTable(tableIndex);
+    m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Immediate));
+    jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+
+    JITStubCall stubCall(this, cti_op_switch_imm);
+    stubCall.addArgument(scrutinee, regT2);
+    stubCall.addArgument(Imm32(tableIndex));
+    stubCall.call();
+    jump(regT0);
+}
+
+void JIT::emit_op_switch_char(Instruction* currentInstruction)
+{
+    unsigned tableIndex = currentInstruction[1].u.operand;
+    unsigned defaultOffset = currentInstruction[2].u.operand;
+    unsigned scrutinee = currentInstruction[3].u.operand;
+
+    // create jump table for switch destinations, track this switch statement.
+    SimpleJumpTable* jumpTable = &m_codeBlock->characterSwitchJumpTable(tableIndex);
+    m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset, SwitchRecord::Character));
+    jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
+
+    JITStubCall stubCall(this, cti_op_switch_char);
+    stubCall.addArgument(scrutinee, regT2);
+    stubCall.addArgument(Imm32(tableIndex));
+    stubCall.call();
+    jump(regT0);
+}
+
+void JIT::emit_op_switch_string(Instruction* currentInstruction)
+{
+    unsigned tableIndex = currentInstruction[1].u.operand;
+    unsigned defaultOffset = currentInstruction[2].u.operand;
+    unsigned scrutinee = currentInstruction[3].u.operand;
+
+    // create jump table for switch destinations, track this switch statement.
+    StringJumpTable* jumpTable = &m_codeBlock->stringSwitchJumpTable(tableIndex);
+    m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset));
+
+    JITStubCall stubCall(this, cti_op_switch_string);
+    stubCall.addArgument(scrutinee, regT2);
+    stubCall.addArgument(Imm32(tableIndex));
+    stubCall.call();
+    jump(regT0);
+}
+
+void JIT::emit_op_new_error(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_new_error);
+    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+    stubCall.addArgument(ImmPtr(JSValue::encode(m_codeBlock->getConstant(currentInstruction[3].u.operand))));
+    stubCall.addArgument(Imm32(m_bytecodeIndex));
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_debug(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_debug);
+    stubCall.addArgument(Imm32(currentInstruction[1].u.operand));
+    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+    stubCall.addArgument(Imm32(currentInstruction[3].u.operand));
+    stubCall.call();
+}
+
+void JIT::emit_op_eq_null(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src1 = currentInstruction[2].u.operand;
+
+    emitGetVirtualRegister(src1, regT0);
+    Jump isImmediate = emitJumpIfNotJSCell(regT0);
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    setTest32(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
+
+    Jump wasNotImmediate = jump();
+
+    isImmediate.link(this);
+
+    andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+    setPtr(Equal, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);
+
+    wasNotImmediate.link(this);
+
+    emitTagAsBoolImmediate(regT0);
+    emitPutVirtualRegister(dst);
+
+}
+
+void JIT::emit_op_neq_null(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned src1 = currentInstruction[2].u.operand;
+
+    emitGetVirtualRegister(src1, regT0);
+    Jump isImmediate = emitJumpIfNotJSCell(regT0);
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    setTest32(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
+
+    Jump wasNotImmediate = jump();
+
+    isImmediate.link(this);
+
+    andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
+    setPtr(NotEqual, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);
+
+    wasNotImmediate.link(this);
+
+    emitTagAsBoolImmediate(regT0);
+    emitPutVirtualRegister(dst);
+
+}
+
+void JIT::emit_op_enter(Instruction*)
+{
+    // Even though CTI doesn't use them, we initialize our constant
+    // registers to zap stale pointers, to avoid unnecessarily prolonging
+    // object lifetime and increasing GC pressure.
+    size_t count = m_codeBlock->m_numVars;
+    for (size_t j = 0; j < count; ++j)
+        emitInitRegister(j);
+
+}
+
+void JIT::emit_op_enter_with_activation(Instruction* currentInstruction)
+{
+    // Even though CTI doesn't use them, we initialize our constant
+    // registers to zap stale pointers, to avoid unnecessarily prolonging
+    // object lifetime and increasing GC pressure.
+    size_t count = m_codeBlock->m_numVars;
+    for (size_t j = 0; j < count; ++j)
+        emitInitRegister(j);
+
+    JITStubCall(this, cti_op_push_activation).call(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_create_arguments(Instruction*)
+{
+    Jump argsCreated = branchTestPtr(NonZero, Address(callFrameRegister, sizeof(Register) * RegisterFile::ArgumentsRegister));
+    if (m_codeBlock->m_numParameters == 1)
+        JITStubCall(this, cti_op_create_arguments_no_params).call();
+    else
+        JITStubCall(this, cti_op_create_arguments).call();
+    argsCreated.link(this);
+}
+    
+void JIT::emit_op_init_arguments(Instruction*)
+{
+    storePtr(ImmPtr(0), Address(callFrameRegister, sizeof(Register) * RegisterFile::ArgumentsRegister));
+}
+
+void JIT::emit_op_convert_this(Instruction* currentInstruction)
+{
+    emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
+
+    emitJumpSlowCaseIfNotJSCell(regT0);
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
+    addSlowCase(branchTest32(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
+
+}
+
+void JIT::emit_op_profile_will_call(Instruction* currentInstruction)
+{
+    peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*));
+    Jump noProfiler = branchTestPtr(Zero, Address(regT1));
+
+    JITStubCall stubCall(this, cti_op_profile_will_call);
+    stubCall.addArgument(currentInstruction[1].u.operand, regT1);
+    stubCall.call();
+    noProfiler.link(this);
+
+}
+
+void JIT::emit_op_profile_did_call(Instruction* currentInstruction)
+{
+    peek(regT1, OBJECT_OFFSETOF(JITStackFrame, enabledProfilerReference) / sizeof (void*));
+    Jump noProfiler = branchTestPtr(Zero, Address(regT1));
+
+    JITStubCall stubCall(this, cti_op_profile_did_call);
+    stubCall.addArgument(currentInstruction[1].u.operand, regT1);
+    stubCall.call();
+    noProfiler.link(this);
+}
+
+
+// Slow cases
+
+void JIT::emitSlow_op_convert_this(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_convert_this);
+    stubCall.addArgument(regT0);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_construct_verify(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_to_primitive);
+    stubCall.addArgument(regT0);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    // The slow void JIT::emitSlow_that handles accesses to arrays (below) may jump back up to here. 
+    Label beginGetByValSlow(this);
+
+    Jump notImm = getSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    emitFastArithIntToImmNoCheck(regT1, regT1);
+
+    notImm.link(this);
+    JITStubCall stubCall(this, cti_op_get_by_val);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT1);
+    stubCall.call(currentInstruction[1].u.operand);
+    emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
+
+    // This is slow void JIT::emitSlow_that handles accesses to arrays above the fast cut-off.
+    // First, check if this is an access to the vector
+    linkSlowCase(iter);
+    branch32(AboveOrEqual, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)), beginGetByValSlow);
+
+    // okay, missed the fast region, but it is still in the vector.  Get the value.
+    loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT2);
+    // Check whether the value loaded is zero; if so we need to return undefined.
+    branchTestPtr(Zero, regT2, beginGetByValSlow);
+    move(regT2, regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand, regT0);
+}
+
+void JIT::emitSlow_op_loop_if_less(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+    if (isOperandConstantImmediateInt(op2)) {
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_loop_if_less);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(op2, regT2);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+    } else if (isOperandConstantImmediateInt(op1)) {
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_loop_if_less);
+        stubCall.addArgument(op1, regT2);
+        stubCall.addArgument(regT0);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+    } else {
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_loop_if_less);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(regT1);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+    }
+}
+
+void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+    if (isOperandConstantImmediateInt(op2)) {
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_loop_if_lesseq);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(currentInstruction[2].u.operand, regT2);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+    } else {
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_loop_if_lesseq);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(regT1);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
+    }
+}
+
+void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    // Normal slow cases - either is not an immediate imm, or is an array.
+    Jump notImm = getSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    emitFastArithIntToImmNoCheck(regT1, regT1);
+
+    notImm.link(this); {
+        JITStubCall stubCall(this, cti_op_put_by_val);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(currentInstruction[3].u.operand, regT2);
+        stubCall.call();
+        emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_put_by_val));
+    }
+
+    // slow cases for immediate int accesses to arrays
+    linkSlowCase(iter);
+    linkSlowCase(iter); {
+        JITStubCall stubCall(this, cti_op_put_by_val_array);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(currentInstruction[3].u.operand, regT2);
+        stubCall.call();
+    }
+}
+
+void JIT::emitSlow_op_loop_if_true(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_jtrue);
+    stubCall.addArgument(regT0);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2);
+}
+
+void JIT::emitSlow_op_not(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
+    JITStubCall stubCall(this, cti_op_not);
+    stubCall.addArgument(regT0);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_jtrue);
+    stubCall.addArgument(regT0);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand + 2); // inverted!
+}
+
+void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_bitnot);
+    stubCall.addArgument(regT0);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_jtrue);
+    stubCall.addArgument(regT0);
+    stubCall.call();
+    emitJumpSlowToHot(branchTest32(NonZero, regT0), currentInstruction[2].u.operand + 2);
+}
+
+void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_bitxor);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT1);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_bitor(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_bitor);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT1);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_eq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_eq);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT1);
+    stubCall.call();
+    emitTagAsBoolImmediate(regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_neq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_eq);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT1);
+    stubCall.call();
+    xor32(Imm32(0x1), regT0);
+    emitTagAsBoolImmediate(regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_stricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_stricteq);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT1);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_nstricteq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_nstricteq);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT1);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_instanceof(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_instanceof);
+    stubCall.addArgument(currentInstruction[2].u.operand, regT2);
+    stubCall.addArgument(currentInstruction[3].u.operand, regT2);
+    stubCall.addArgument(currentInstruction[4].u.operand, regT2);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+void JIT::emitSlow_op_call(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    compileOpCallSlowCase(currentInstruction, iter, m_callLinkInfoIndex++, op_call);
+}
+
+void JIT::emitSlow_op_call_eval(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    compileOpCallSlowCase(currentInstruction, iter, m_callLinkInfoIndex++, op_call_eval);
+}
+
+void JIT::emitSlow_op_call_varargs(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    compileOpCallVarargsSlowCase(currentInstruction, iter);
+}
+
+void JIT::emitSlow_op_construct(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    compileOpCallSlowCase(currentInstruction, iter, m_callLinkInfoIndex++, op_construct);
+}
+
+void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    linkSlowCaseIfNotJSCell(iter, currentInstruction[2].u.operand);
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_to_jsnumber);
+    stubCall.addArgument(regT0);
+    stubCall.call(currentInstruction[1].u.operand);
+}
+
+#endif // USE(JSVALUE32_64)
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
index 6740becbea7bb814d486272e3c17a73b0e386555..a6a28316e498c5a578c256be2467fa63a7720de6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #include "CodeBlock.h"
 #include "JITInlineMethods.h"
+#include "JITStubCall.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "Interpreter.h"
+#include "LinkBuffer.h"
+#include "RepatchBuffer.h"
 #include "ResultType.h"
 #include "SamplingTool.h"
 
@@ -44,81 +47,1180 @@ using namespace std;
 
 namespace JSC {
 
+#if USE(JSVALUE32_64)
+
+void JIT::emit_op_put_by_index(Instruction* currentInstruction)
+{
+    unsigned base = currentInstruction[1].u.operand;
+    unsigned property = currentInstruction[2].u.operand;
+    unsigned value = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_put_by_index);
+    stubCall.addArgument(base);
+    stubCall.addArgument(Imm32(property));
+    stubCall.addArgument(value);
+    stubCall.call();
+}
+
+void JIT::emit_op_put_getter(Instruction* currentInstruction)
+{
+    unsigned base = currentInstruction[1].u.operand;
+    unsigned property = currentInstruction[2].u.operand;
+    unsigned function = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_put_getter);
+    stubCall.addArgument(base);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(property)));
+    stubCall.addArgument(function);
+    stubCall.call();
+}
+
+void JIT::emit_op_put_setter(Instruction* currentInstruction)
+{
+    unsigned base = currentInstruction[1].u.operand;
+    unsigned property = currentInstruction[2].u.operand;
+    unsigned function = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_put_setter);
+    stubCall.addArgument(base);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(property)));
+    stubCall.addArgument(function);
+    stubCall.call();
+}
+
+void JIT::emit_op_del_by_id(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned base = currentInstruction[2].u.operand;
+    unsigned property = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_del_by_id);
+    stubCall.addArgument(base);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(property)));
+    stubCall.call(dst);
+}
+
+
 #if !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
 
-void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier* ident, unsigned)
+/* ------------------------------ BEGIN: !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */
+
+// Treat these as nops - the call will be handed as a regular get_by_id/op_call pair.
+void JIT::emit_op_method_check(Instruction*) {}
+void JIT::emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&) { ASSERT_NOT_REACHED(); }
+#if ENABLE(JIT_OPTIMIZE_METHOD_CALLS)
+#error "JIT_OPTIMIZE_METHOD_CALLS requires JIT_OPTIMIZE_PROPERTY_ACCESS"
+#endif
+
+void JIT::emit_op_get_by_val(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned base = currentInstruction[2].u.operand;
+    unsigned property = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_get_by_val);
+    stubCall.addArgument(base);
+    stubCall.addArgument(property);
+    stubCall.call(dst);
+}
+
+void JIT::emitSlow_op_get_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&)
+{
+    ASSERT_NOT_REACHED();
+}
+
+void JIT::emit_op_put_by_val(Instruction* currentInstruction)
+{
+    unsigned base = currentInstruction[1].u.operand;
+    unsigned property = currentInstruction[2].u.operand;
+    unsigned value = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_put_by_val);
+    stubCall.addArgument(base);
+    stubCall.addArgument(property);
+    stubCall.addArgument(value);
+    stubCall.call();
+}
+
+void JIT::emitSlow_op_put_by_val(Instruction*, Vector<SlowCaseEntry>::iterator&)
+{
+    ASSERT_NOT_REACHED();
+}
+
+void JIT::emit_op_get_by_id(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int ident = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_get_by_id_generic);
+    stubCall.addArgument(base);
+    stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident))));
+    stubCall.call(dst);
+
+    m_propertyAccessInstructionIndex++;
+}
+
+void JIT::emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&)
+{
+    m_propertyAccessInstructionIndex++;
+    ASSERT_NOT_REACHED();
+}
+
+void JIT::emit_op_put_by_id(Instruction* currentInstruction)
+{
+    int base = currentInstruction[1].u.operand;
+    int ident = currentInstruction[2].u.operand;
+    int value = currentInstruction[3].u.operand;
+
+    JITStubCall stubCall(this, cti_op_put_by_id_generic);
+    stubCall.addArgument(base);
+    stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident))));
+    stubCall.addArgument(value);
+    stubCall.call();
+
+    m_propertyAccessInstructionIndex++;
+}
+
+void JIT::emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&)
+{
+    m_propertyAccessInstructionIndex++;
+    ASSERT_NOT_REACHED();
+}
+
+#else // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+/* ------------------------------ BEGIN: ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */
+
+#if ENABLE(JIT_OPTIMIZE_METHOD_CALLS)
+
+void JIT::emit_op_method_check(Instruction* currentInstruction)
+{
+    // Assert that the following instruction is a get_by_id.
+    ASSERT(m_interpreter->getOpcodeID((currentInstruction + OPCODE_LENGTH(op_method_check))->u.opcode) == op_get_by_id);
+
+    currentInstruction += OPCODE_LENGTH(op_method_check);
+
+    // Do the method check - check the object & its prototype's structure inline (this is the common case).
+    m_methodCallCompilationInfo.append(MethodCallCompilationInfo(m_propertyAccessInstructionIndex));
+    MethodCallCompilationInfo& info = m_methodCallCompilationInfo.last();
+
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+
+    emitLoad(base, regT1, regT0);
+    emitJumpSlowCaseIfNotJSCell(base, regT1);
+
+    Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), info.structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+    DataLabelPtr protoStructureToCompare, protoObj = moveWithPatch(ImmPtr(0), regT2);
+    Jump protoStructureCheck = branchPtrWithPatch(NotEqual, Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), protoStructureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+
+    // This will be relinked to load the function without doing a load.
+    DataLabelPtr putFunction = moveWithPatch(ImmPtr(0), regT0);
+    move(Imm32(JSValue::CellTag), regT1);
+    Jump match = jump();
+
+    ASSERT(differenceBetween(info.structureToCompare, protoObj) == patchOffsetMethodCheckProtoObj);
+    ASSERT(differenceBetween(info.structureToCompare, protoStructureToCompare) == patchOffsetMethodCheckProtoStruct);
+    ASSERT(differenceBetween(info.structureToCompare, putFunction) == patchOffsetMethodCheckPutFunction);
+
+    // Link the failure cases here.
+    structureCheck.link(this);
+    protoStructureCheck.link(this);
+
+    // Do a regular(ish) get_by_id (the slow case will be link to
+    // cti_op_get_by_id_method_check instead of cti_op_get_by_id.
+    compileGetByIdHotPath();
+
+    match.link(this);
+    emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_method_check), dst, regT1, regT0);
+
+    // We've already generated the following get_by_id, so make sure it's skipped over.
+    m_bytecodeIndex += OPCODE_LENGTH(op_get_by_id);
+}
+
+void JIT::emitSlow_op_method_check(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    currentInstruction += OPCODE_LENGTH(op_method_check);
+
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int ident = currentInstruction[3].u.operand;
+
+    compileGetByIdSlowCase(dst, base, &(m_codeBlock->identifier(ident)), iter, true);
+
+    // We've already generated the following get_by_id, so make sure it's skipped over.
+    m_bytecodeIndex += OPCODE_LENGTH(op_get_by_id);
+}
+
+#else //!ENABLE(JIT_OPTIMIZE_METHOD_CALLS)
+
+// Treat these as nops - the call will be handed as a regular get_by_id/op_call pair.
+void JIT::emit_op_method_check(Instruction*) {}
+void JIT::emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&) { ASSERT_NOT_REACHED(); }
+
+#endif
+
+void JIT::emit_op_get_by_val(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned base = currentInstruction[2].u.operand;
+    unsigned property = currentInstruction[3].u.operand;
+    
+    emitLoad2(base, regT1, regT0, property, regT3, regT2);
+
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    emitJumpSlowCaseIfNotJSCell(base, regT1);
+    addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
+    addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff))));
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0);
+    load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag
+    load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload
+    emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_val), dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_get_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned base = currentInstruction[2].u.operand;
+    unsigned property = currentInstruction[3].u.operand;
+
+    // The slow void JIT::emitSlow_that handles accesses to arrays (below) may jump back up to here. 
+    Label callGetByValJITStub(this);
+
+    linkSlowCase(iter); // property int32 check
+    linkSlowCaseIfNotJSCell(iter, base); // base cell check
+    linkSlowCase(iter); // base array check
+
+    JITStubCall stubCall(this, cti_op_get_by_val);
+    stubCall.addArgument(base);
+    stubCall.addArgument(property);
+    stubCall.call(dst);
+
+    emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
+
+    linkSlowCase(iter); // array fast cut-off check
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT0);
+    branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength)), callGetByValJITStub);
+
+    // Missed the fast region, but it is still in the vector.
+    load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag
+    load32(BaseIndex(regT0, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload
+
+    // FIXME: Maybe we can optimize this comparison to JSValue().
+    Jump skip = branch32(NotEqual, regT0, Imm32(0));
+    branch32(Equal, regT1, Imm32(JSValue::CellTag), callGetByValJITStub);
+
+    skip.link(this);
+    emitStore(dst, regT1, regT0);
+}
+
+void JIT::emit_op_put_by_val(Instruction* currentInstruction)
+{
+    unsigned base = currentInstruction[1].u.operand;
+    unsigned property = currentInstruction[2].u.operand;
+    unsigned value = currentInstruction[3].u.operand;
+
+    emitLoad2(base, regT1, regT0, property, regT3, regT2);
+
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+    emitJumpSlowCaseIfNotJSCell(base, regT1);
+    addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
+
+    Jump inFastVector = branch32(Below, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)));
+
+    // Check if the access is within the vector.
+    addSlowCase(branch32(AboveOrEqual, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength))));
+
+    // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
+    // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. 
+    Jump skip = branch32(NotEqual, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::CellTag));
+    addSlowCase(branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), Imm32(0)));
+    skip.link(this);
+
+    inFastVector.link(this);
+
+    emitLoad(value, regT1, regT0);
+    store32(regT0, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))); // payload
+    store32(regT1, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4)); // tag
+}
+
+void JIT::emitSlow_op_put_by_val(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned base = currentInstruction[1].u.operand;
+    unsigned property = currentInstruction[2].u.operand;
+    unsigned value = currentInstruction[3].u.operand;
+
+    linkSlowCase(iter); // property int32 check
+    linkSlowCaseIfNotJSCell(iter, base); // base cell check
+    linkSlowCase(iter); // base not array check
+
+    JITStubCall stubPutByValCall(this, cti_op_put_by_val);
+    stubPutByValCall.addArgument(base);
+    stubPutByValCall.addArgument(property);
+    stubPutByValCall.addArgument(value);
+    stubPutByValCall.call();
+
+    emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
+
+    // Slow cases for immediate int accesses to arrays.
+    linkSlowCase(iter); // in vector check
+    linkSlowCase(iter); // written to slot check
+
+    JITStubCall stubCall(this, cti_op_put_by_val_array);
+    stubCall.addArgument(regT1, regT0);
+    stubCall.addArgument(regT2);
+    stubCall.addArgument(value);
+    stubCall.call();
+}
+
+void JIT::emit_op_get_by_id(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    
+    emitLoad(base, regT1, regT0);
+    emitJumpSlowCaseIfNotJSCell(base, regT1);
+    compileGetByIdHotPath();
+    emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_id), dst, regT1, regT0);
+}
+
+void JIT::compileGetByIdHotPath()
+{
+    // As for put_by_id, get_by_id requires the offset of the Structure and the offset of the access to be patched.
+    // Additionally, for get_by_id we need patch the offset of the branch to the slow case (we patch this to jump
+    // to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
+    // to jump back to if one of these trampolies finds a match.
+    Label hotPathBegin(this);
+    m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
+    m_propertyAccessInstructionIndex++;
+
+    DataLabelPtr structureToCompare;
+    Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+    addSlowCase(structureCheck);
+    ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetGetByIdStructure);
+    ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase);
+
+    Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT2);
+    Label externalLoadComplete(this);
+    ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad);
+    ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad);
+
+    DataLabel32 displacementLabel1 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT0); // payload
+    ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetGetByIdPropertyMapOffset1);
+    DataLabel32 displacementLabel2 = loadPtrWithAddressOffsetPatch(Address(regT2, patchGetByIdDefaultOffset), regT1); // tag
+    ASSERT(differenceBetween(hotPathBegin, displacementLabel2) == patchOffsetGetByIdPropertyMapOffset2);
+
+    Label putResult(this);
+    ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult);
+}
+
+void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int ident = currentInstruction[3].u.operand;
+
+    compileGetByIdSlowCase(dst, base, &(m_codeBlock->identifier(ident)), iter);
+}
+
+void JIT::compileGetByIdSlowCase(int dst, int base, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck)
+{
+    // As for the hot path of get_by_id, above, we ensure that we can use an architecture specific offset
+    // so that we only need track one pointer into the slow case code - we track a pointer to the location
+    // of the call (which we can use to look up the patch information), but should a array-length or
+    // prototype access trampoline fail we want to bail out back to here.  To do so we can subtract back
+    // the distance from the call to the head of the slow case.
+    linkSlowCaseIfNotJSCell(iter, base);
+    linkSlowCase(iter);
+
+    Label coldPathBegin(this);
+
+    JITStubCall stubCall(this, isMethodCheck ? cti_op_get_by_id_method_check : cti_op_get_by_id);
+    stubCall.addArgument(regT1, regT0);
+    stubCall.addArgument(ImmPtr(ident));
+    Call call = stubCall.call(dst);
+
+    ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall);
+
+    // Track the location of the call; this will be used to recover patch information.
+    m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call;
+    m_propertyAccessInstructionIndex++;
+}
+
+void JIT::emit_op_put_by_id(Instruction* currentInstruction)
+{
+    // In order to be able to patch both the Structure, and the object offset, we store one pointer,
+    // to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code
+    // such that the Structure & offset are always at the same distance from this.
+
+    int base = currentInstruction[1].u.operand;
+    int value = currentInstruction[3].u.operand;
+
+    emitLoad2(base, regT1, regT0, value, regT3, regT2);
+
+    emitJumpSlowCaseIfNotJSCell(base, regT1);
+
+    Label hotPathBegin(this);
+    m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
+    m_propertyAccessInstructionIndex++;
+
+    // It is important that the following instruction plants a 32bit immediate, in order that it can be patched over.
+    DataLabelPtr structureToCompare;
+    addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
+    ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure);
+
+    // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used.
+    Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0);
+    Label externalLoadComplete(this);
+    ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetPutByIdExternalLoad);
+    ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad);
+
+    DataLabel32 displacementLabel1 = storePtrWithAddressOffsetPatch(regT2, Address(regT0, patchGetByIdDefaultOffset)); // payload
+    DataLabel32 displacementLabel2 = storePtrWithAddressOffsetPatch(regT3, Address(regT0, patchGetByIdDefaultOffset)); // tag
+    ASSERT(differenceBetween(hotPathBegin, displacementLabel1) == patchOffsetPutByIdPropertyMapOffset1);
+    ASSERT(differenceBetween(hotPathBegin, displacementLabel2) == patchOffsetPutByIdPropertyMapOffset2);
+}
+
+void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    int base = currentInstruction[1].u.operand;
+    int ident = currentInstruction[2].u.operand;
+
+    linkSlowCaseIfNotJSCell(iter, base);
+    linkSlowCase(iter);
+
+    JITStubCall stubCall(this, cti_op_put_by_id);
+    stubCall.addArgument(regT1, regT0);
+    stubCall.addArgument(ImmPtr(&(m_codeBlock->identifier(ident))));
+    stubCall.addArgument(regT3, regT2); 
+    Call call = stubCall.call();
+
+    // Track the location of the call; this will be used to recover patch information.
+    m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call;
+    m_propertyAccessInstructionIndex++;
+}
+
+// Compile a store into an object's property storage.  May overwrite base.
+void JIT::compilePutDirectOffset(RegisterID base, RegisterID valueTag, RegisterID valuePayload, Structure* structure, size_t cachedOffset)
+{
+    int offset = cachedOffset;
+    if (structure->isUsingInlineStorage())
+        offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) /  sizeof(Register);
+    else
+        loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
+    emitStore(offset, valueTag, valuePayload, base);
+}
+
+// Compile a load from an object's property storage.  May overwrite base.
+void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, Structure* structure, size_t cachedOffset)
+{
+    int offset = cachedOffset;
+    if (structure->isUsingInlineStorage())
+        offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage) / sizeof(Register);
+    else
+        loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
+    emitLoad(offset, resultTag, resultPayload, base);
+}
+
+void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset)
+{
+    if (base->isUsingInlineStorage()) {
+        load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]), resultPayload);
+        load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + 4, resultTag);
+        return;
+    }
+
+    size_t offset = cachedOffset * sizeof(JSValue);
+
+    PropertyStorage* protoPropertyStorage = &base->m_externalStorage;
+    loadPtr(static_cast<void*>(protoPropertyStorage), temp);
+    load32(Address(temp, offset), resultPayload);
+    load32(Address(temp, offset + 4), resultTag);
+}
+
+void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress)
+{
+    // It is assumed that regT0 contains the basePayload and regT1 contains the baseTag.  The value can be found on the stack.
+
+    JumpList failureCases;
+    failureCases.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(oldStructure)));
+
+    // Verify that nothing in the prototype chain has a setter for this property. 
+    for (RefPtr<Structure>* it = chain->head(); *it; ++it) {
+        loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
+        loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+        failureCases.append(branchPtr(NotEqual, regT2, ImmPtr(it->get())));
+    }
+
+    // Reallocate property storage if needed.
+    Call callTarget;
+    bool willNeedStorageRealloc = oldStructure->propertyStorageCapacity() != newStructure->propertyStorageCapacity();
+    if (willNeedStorageRealloc) {
+        // This trampoline was called to like a JIT stub; before we can can call again we need to
+        // remove the return address from the stack, to prevent the stack from becoming misaligned.
+        preserveReturnAddressAfterCall(regT3);
+        JITStubCall stubCall(this, cti_op_put_by_id_transition_realloc);
+        stubCall.skipArgument(); // base
+        stubCall.skipArgument(); // ident
+        stubCall.skipArgument(); // value
+        stubCall.addArgument(Imm32(oldStructure->propertyStorageCapacity()));
+        stubCall.addArgument(Imm32(newStructure->propertyStorageCapacity()));
+        stubCall.call(regT0);
+
+        restoreReturnAddressBeforeReturn(regT3);
+    }
+
+    sub32(Imm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
+    add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount()));
+    storePtr(ImmPtr(newStructure), Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)));
+    load32(Address(stackPointerRegister, offsetof(struct JITStackFrame, args[2]) + sizeof(void*)), regT3);
+    load32(Address(stackPointerRegister, offsetof(struct JITStackFrame, args[2]) + sizeof(void*) + 4), regT2);
+
+    // Write the value
+    compilePutDirectOffset(regT0, regT2, regT3, newStructure, cachedOffset);
+
+    ret();
+    
+    ASSERT(!failureCases.empty());
+    failureCases.link(this);
+    restoreArgumentReferenceForTrampoline();
+    Call failureCall = tailRecursiveCall();
+
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+
+    patchBuffer.link(failureCall, FunctionPtr(cti_op_put_by_id_fail));
+
+    if (willNeedStorageRealloc) {
+        ASSERT(m_calls.size() == 1);
+        patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc));
+    }
+    
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+    stubInfo->stubRoutine = entryLabel;
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relinkCallerToTrampoline(returnAddress, entryLabel);
+}
+
+void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress)
+{
+    RepatchBuffer repatchBuffer(codeBlock);
+
+    // We don't want to patch more than once - in future go to cti_op_get_by_id_generic.
+    // Should probably go to JITStubs::cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
+
+    int offset = sizeof(JSValue) * cachedOffset;
+
+    // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load
+    // and makes the subsequent load's offset automatically correct
+    if (structure->isUsingInlineStorage())
+        repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetGetByIdExternalLoad));
+
+    // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure), structure);
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset1), offset); // payload
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset2), offset + 4); // tag
+}
+
+void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto)
+{
+    RepatchBuffer repatchBuffer(codeBlock);
+
+    ASSERT(!methodCallLinkInfo.cachedStructure);
+    methodCallLinkInfo.cachedStructure = structure;
+    structure->ref();
+
+    Structure* prototypeStructure = proto->structure();
+    ASSERT(!methodCallLinkInfo.cachedPrototypeStructure);
+    methodCallLinkInfo.cachedPrototypeStructure = prototypeStructure;
+    prototypeStructure->ref();
+
+    repatchBuffer.repatch(methodCallLinkInfo.structureLabel, structure);
+    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoObj), proto);
+    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoStruct), prototypeStructure);
+    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckPutFunction), callee);
+}
+
+void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress)
+{
+    RepatchBuffer repatchBuffer(codeBlock);
+
+    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+    // Should probably go to cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_put_by_id_generic));
+
+    int offset = sizeof(JSValue) * cachedOffset;
+
+    // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load
+    // and makes the subsequent load's offset automatically correct
+    if (structure->isUsingInlineStorage())
+        repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetPutByIdExternalLoad));
+
+    // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure), structure);
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset1), offset); // payload
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset2), offset + 4); // tag
+}
+
+void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
+{
+    StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress);
+    
+    // regT0 holds a JSCell*
+
+    // Check for array
+    Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr));
+
+    // Checks out okay! - get the length from the storage
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
+    load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2);
+
+    Jump failureCases2 = branch32(Above, regT2, Imm32(INT_MAX));
+    move(regT2, regT0);
+    move(Imm32(JSValue::Int32Tag), regT1);
+    Jump success = jump();
+
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+
+    // Use the patch information to link the failure cases back to the original slow case routine.
+    CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);
+    patchBuffer.link(failureCases1, slowCaseBegin);
+    patchBuffer.link(failureCases2, slowCaseBegin);
+
+    // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+    // Track the stub we have created so that it will be deleted later.
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+    stubInfo->stubRoutine = entryLabel;
+
+    // Finally patch the jump to slow case back in the hot path to jump here instead.
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
+
+    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail));
+}
+
+void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
+{
+    // regT0 holds a JSCell*
+
+    // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
+    // referencing the prototype object - let's speculatively load it's table nice and early!)
+    JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
+
+    Jump failureCases1 = checkStructure(regT0, structure);
+
+    // Check the prototype object's Structure had not changed.
+    Structure** prototypeStructureAddress = &(protoObject->m_structure);
+#if PLATFORM(X86_64)
+    move(ImmPtr(prototypeStructure), regT3);
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
+#else
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+#endif
+
+    // Checks out okay! - getDirectOffset
+    compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+
+    Jump success = jump();
+
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+
+    // Use the patch information to link the failure cases back to the original slow case routine.
+    CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);
+    patchBuffer.link(failureCases1, slowCaseBegin);
+    patchBuffer.link(failureCases2, slowCaseBegin);
+
+    // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+    // Track the stub we have created so that it will be deleted later.
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+    stubInfo->stubRoutine = entryLabel;
+
+    // Finally patch the jump to slow case back in the hot path to jump here instead.
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
+
+    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
+}
+
+
+void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset)
+{
+    // regT0 holds a JSCell*
+    
+    Jump failureCase = checkStructure(regT0, structure);
+    compileGetDirectOffset(regT0, regT1, regT0, structure, cachedOffset);
+    Jump success = jump();
+
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+
+    // Use the patch information to link the failure cases back to the original slow case routine.
+    CodeLocationLabel lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine;
+    if (!lastProtoBegin)
+        lastProtoBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);
+
+    patchBuffer.link(failureCase, lastProtoBegin);
+
+    // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+
+    structure->ref();
+    polymorphicStructures->list[currentIndex].set(entryLabel, structure);
+
+    // Finally patch the jump to slow case back in the hot path to jump here instead.
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
+}
+
+void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame)
+{
+    // regT0 holds a JSCell*
+    
+    // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
+    // referencing the prototype object - let's speculatively load it's table nice and early!)
+    JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
+
+    // Check eax is an object of the right Structure.
+    Jump failureCases1 = checkStructure(regT0, structure);
+
+    // Check the prototype object's Structure had not changed.
+    Structure** prototypeStructureAddress = &(protoObject->m_structure);
+#if PLATFORM(X86_64)
+    move(ImmPtr(prototypeStructure), regT3);
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
+#else
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+#endif
+
+    compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+
+    Jump success = jump();
+
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+
+    // Use the patch information to link the failure cases back to the original slow case routine.
+    CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
+    patchBuffer.link(failureCases1, lastProtoBegin);
+    patchBuffer.link(failureCases2, lastProtoBegin);
+
+    // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+
+    structure->ref();
+    prototypeStructure->ref();
+    prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure);
+
+    // Finally patch the jump to slow case back in the hot path to jump here instead.
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
+}
+
+void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame)
 {
-    // As for put_by_id, get_by_id requires the offset of the Structure and the offset of the access to be patched.
-    // Additionally, for get_by_id we need patch the offset of the branch to the slow case (we patch this to jump
-    // to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
-    // to jump back to if one of these trampolies finds a match.
+    // regT0 holds a JSCell*
+    
+    ASSERT(count);
+    
+    JumpList bucketsOfFail;
 
-    emitGetVirtualRegister(baseVReg, X86::eax);
+    // Check eax is an object of the right Structure.
+    bucketsOfFail.append(checkStructure(regT0, structure));
 
-    emitPutJITStubArg(X86::eax, 1);
-    emitPutJITStubArgConstant(ident, 2);
-    emitCTICall(Interpreter::cti_op_get_by_id_generic);
-    emitPutVirtualRegister(resultVReg);
+    Structure* currStructure = structure;
+    RefPtr<Structure>* chainEntries = chain->head();
+    JSObject* protoObject = 0;
+    for (unsigned i = 0; i < count; ++i) {
+        protoObject = asObject(currStructure->prototypeForLookup(callFrame));
+        currStructure = chainEntries[i].get();
+
+        // Check the prototype object's Structure had not changed.
+        Structure** prototypeStructureAddress = &(protoObject->m_structure);
+#if PLATFORM(X86_64)
+        move(ImmPtr(currStructure), regT3);
+        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
+#else
+        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+#endif
+    }
+    ASSERT(protoObject);
+
+    compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+    Jump success = jump();
+
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+
+    // Use the patch information to link the failure cases back to the original slow case routine.
+    CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
+
+    patchBuffer.link(bucketsOfFail, lastProtoBegin);
+
+    // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+
+    // Track the stub we have created so that it will be deleted later.
+    structure->ref();
+    chain->ref();
+    prototypeStructures->list[currentIndex].set(entryLabel, structure, chain);
+
+    // Finally patch the jump to slow case back in the hot path to jump here instead.
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
+}
+
+void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
+{
+    // regT0 holds a JSCell*
+    
+    ASSERT(count);
+    
+    JumpList bucketsOfFail;
+
+    // Check eax is an object of the right Structure.
+    bucketsOfFail.append(checkStructure(regT0, structure));
+
+    Structure* currStructure = structure;
+    RefPtr<Structure>* chainEntries = chain->head();
+    JSObject* protoObject = 0;
+    for (unsigned i = 0; i < count; ++i) {
+        protoObject = asObject(currStructure->prototypeForLookup(callFrame));
+        currStructure = chainEntries[i].get();
+
+        // Check the prototype object's Structure had not changed.
+        Structure** prototypeStructureAddress = &(protoObject->m_structure);
+#if PLATFORM(X86_64)
+        move(ImmPtr(currStructure), regT3);
+        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
+#else
+        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+#endif
+    }
+    ASSERT(protoObject);
+
+    compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+    Jump success = jump();
+
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+
+    // Use the patch information to link the failure cases back to the original slow case routine.
+    patchBuffer.link(bucketsOfFail, stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall));
+
+    // On success return back to the hot patch code, at a point it will perform the store to dest for us.
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+    // Track the stub we have created so that it will be deleted later.
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+    stubInfo->stubRoutine = entryLabel;
+
+    // Finally patch the jump to slow case back in the hot path to jump here instead.
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
+
+    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
+}
+
+/* ------------------------------ END: !ENABLE / ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */
+
+#endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+#else // USE(JSVALUE32_64)
+
+void JIT::emit_op_get_by_val(Instruction* currentInstruction)
+{
+    emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
+    emitJumpSlowCaseIfNotImmediateInteger(regT1);
+#if USE(JSVALUE64)
+    // This is technically incorrect - we're zero-extending an int32.  On the hot path this doesn't matter.
+    // We check the value as if it was a uint32 against the m_fastAccessCutoff - which will always fail if
+    // number was signed since m_fastAccessCutoff is always less than intmax (since the total allocation
+    // size is always less than 4Gb).  As such zero extending wil have been correct (and extending the value
+    // to 64-bits is necessary since it's used in the address calculation.  We zero extend rather than sign
+    // extending since it makes it easier to re-tag the value in the slow case.
+    zeroExtend32ToPtr(regT1, regT1);
+#else
+    emitFastArithImmToInt(regT1);
+#endif
+    emitJumpSlowCaseIfNotJSCell(regT0);
+    addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
+
+    // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
+    addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff))));
+
+    // Get the value from the vector
+    loadPtr(BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0);
+    emitPutVirtualRegister(currentInstruction[1].u.operand);
+}
+
+void JIT::emit_op_put_by_val(Instruction* currentInstruction)
+{
+    emitGetVirtualRegisters(currentInstruction[1].u.operand, regT0, currentInstruction[2].u.operand, regT1);
+    emitJumpSlowCaseIfNotImmediateInteger(regT1);
+#if USE(JSVALUE64)
+    // See comment in op_get_by_val.
+    zeroExtend32ToPtr(regT1, regT1);
+#else
+    emitFastArithImmToInt(regT1);
+#endif
+    emitJumpSlowCaseIfNotJSCell(regT0);
+    addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr)));
+
+    // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
+    Jump inFastVector = branch32(Below, regT1, Address(regT0, OBJECT_OFFSETOF(JSArray, m_fastAccessCutoff)));
+    // No; oh well, check if the access if within the vector - if so, we may still be okay.
+    addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_vectorLength))));
+
+    // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
+    // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff. 
+    addSlowCase(branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))));
+
+    // All good - put the value into the array.
+    inFastVector.link(this);
+    emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
+    storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
+}
+
+void JIT::emit_op_put_by_index(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_put_by_index);
+    stubCall.addArgument(currentInstruction[1].u.operand, regT2);
+    stubCall.addArgument(Imm32(currentInstruction[2].u.operand));
+    stubCall.addArgument(currentInstruction[3].u.operand, regT2);
+    stubCall.call();
+}
+
+void JIT::emit_op_put_getter(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_put_getter);
+    stubCall.addArgument(currentInstruction[1].u.operand, regT2);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.addArgument(currentInstruction[3].u.operand, regT2);
+    stubCall.call();
+}
+
+void JIT::emit_op_put_setter(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_put_setter);
+    stubCall.addArgument(currentInstruction[1].u.operand, regT2);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[2].u.operand)));
+    stubCall.addArgument(currentInstruction[3].u.operand, regT2);
+    stubCall.call();
+}
+
+void JIT::emit_op_del_by_id(Instruction* currentInstruction)
+{
+    JITStubCall stubCall(this, cti_op_del_by_id);
+    stubCall.addArgument(currentInstruction[2].u.operand, regT2);
+    stubCall.addArgument(ImmPtr(&m_codeBlock->identifier(currentInstruction[3].u.operand)));
+    stubCall.call(currentInstruction[1].u.operand);
 }
 
 
-void JIT::compileGetByIdSlowCase(int, int, Identifier*, Vector<SlowCaseEntry>::iterator&, unsigned)
+#if !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+/* ------------------------------ BEGIN: !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */
+
+// Treat these as nops - the call will be handed as a regular get_by_id/op_call pair.
+void JIT::emit_op_method_check(Instruction*) {}
+void JIT::emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&) { ASSERT_NOT_REACHED(); }
+#if ENABLE(JIT_OPTIMIZE_METHOD_CALLS)
+#error "JIT_OPTIMIZE_METHOD_CALLS requires JIT_OPTIMIZE_PROPERTY_ACCESS"
+#endif
+
+void JIT::emit_op_get_by_id(Instruction* currentInstruction)
+{
+    unsigned resultVReg = currentInstruction[1].u.operand;
+    unsigned baseVReg = currentInstruction[2].u.operand;
+    Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+    emitGetVirtualRegister(baseVReg, regT0);
+    JITStubCall stubCall(this, cti_op_get_by_id_generic);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(ImmPtr(ident));
+    stubCall.call(resultVReg);
+
+    m_propertyAccessInstructionIndex++;
+}
+
+void JIT::emitSlow_op_get_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&)
 {
     ASSERT_NOT_REACHED();
 }
 
-void JIT::compilePutByIdHotPath(int baseVReg, Identifier* ident, int valueVReg, unsigned)
+void JIT::emit_op_put_by_id(Instruction* currentInstruction)
 {
-    // In order to be able to patch both the Structure, and the object offset, we store one pointer,
-    // to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code
-    // such that the Structure & offset are always at the same distance from this.
+    unsigned baseVReg = currentInstruction[1].u.operand;
+    Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
+    unsigned valueVReg = currentInstruction[3].u.operand;
+
+    emitGetVirtualRegisters(baseVReg, regT0, valueVReg, regT1);
 
-    emitGetVirtualRegisters(baseVReg, X86::eax, valueVReg, X86::edx);
+    JITStubCall stubCall(this, cti_op_put_by_id_generic);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(ImmPtr(ident));
+    stubCall.addArgument(regT1);
+    stubCall.call();
 
-    emitPutJITStubArgConstant(ident, 2);
-    emitPutJITStubArg(X86::eax, 1);
-    emitPutJITStubArg(X86::edx, 3);
-    emitCTICall(Interpreter::cti_op_put_by_id_generic);
+    m_propertyAccessInstructionIndex++;
 }
 
-void JIT::compilePutByIdSlowCase(int, Identifier*, int, Vector<SlowCaseEntry>::iterator&, unsigned)
+void JIT::emitSlow_op_put_by_id(Instruction*, Vector<SlowCaseEntry>::iterator&)
 {
     ASSERT_NOT_REACHED();
 }
 
-#else
+#else // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+/* ------------------------------ BEGIN: ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */
+
+#if ENABLE(JIT_OPTIMIZE_METHOD_CALLS)
+
+void JIT::emit_op_method_check(Instruction* currentInstruction)
+{
+    // Assert that the following instruction is a get_by_id.
+    ASSERT(m_interpreter->getOpcodeID((currentInstruction + OPCODE_LENGTH(op_method_check))->u.opcode) == op_get_by_id);
+
+    currentInstruction += OPCODE_LENGTH(op_method_check);
+    unsigned resultVReg = currentInstruction[1].u.operand;
+    unsigned baseVReg = currentInstruction[2].u.operand;
+    Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+    emitGetVirtualRegister(baseVReg, regT0);
+
+    // Do the method check - check the object & its prototype's structure inline (this is the common case).
+    m_methodCallCompilationInfo.append(MethodCallCompilationInfo(m_propertyAccessInstructionIndex));
+    MethodCallCompilationInfo& info = m_methodCallCompilationInfo.last();
+    Jump notCell = emitJumpIfNotJSCell(regT0);
+    Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), info.structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+    DataLabelPtr protoStructureToCompare, protoObj = moveWithPatch(ImmPtr(0), regT1);
+    Jump protoStructureCheck = branchPtrWithPatch(NotEqual, Address(regT1, OBJECT_OFFSETOF(JSCell, m_structure)), protoStructureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+
+    // This will be relinked to load the function without doing a load.
+    DataLabelPtr putFunction = moveWithPatch(ImmPtr(0), regT0);
+    Jump match = jump();
+
+    ASSERT(differenceBetween(info.structureToCompare, protoObj) == patchOffsetMethodCheckProtoObj);
+    ASSERT(differenceBetween(info.structureToCompare, protoStructureToCompare) == patchOffsetMethodCheckProtoStruct);
+    ASSERT(differenceBetween(info.structureToCompare, putFunction) == patchOffsetMethodCheckPutFunction);
+
+    // Link the failure cases here.
+    notCell.link(this);
+    structureCheck.link(this);
+    protoStructureCheck.link(this);
+
+    // Do a regular(ish) get_by_id (the slow case will be link to
+    // cti_op_get_by_id_method_check instead of cti_op_get_by_id.
+    compileGetByIdHotPath(resultVReg, baseVReg, ident, m_propertyAccessInstructionIndex++);
+
+    match.link(this);
+    emitPutVirtualRegister(resultVReg);
+
+    // We've already generated the following get_by_id, so make sure it's skipped over.
+    m_bytecodeIndex += OPCODE_LENGTH(op_get_by_id);
+}
 
-void JIT::compileGetByIdHotPath(int resultVReg, int baseVReg, Identifier*, unsigned propertyAccessInstructionIndex)
+void JIT::emitSlow_op_method_check(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    currentInstruction += OPCODE_LENGTH(op_method_check);
+    unsigned resultVReg = currentInstruction[1].u.operand;
+    unsigned baseVReg = currentInstruction[2].u.operand;
+    Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+    compileGetByIdSlowCase(resultVReg, baseVReg, ident, iter, true);
+
+    // We've already generated the following get_by_id, so make sure it's skipped over.
+    m_bytecodeIndex += OPCODE_LENGTH(op_get_by_id);
+}
+
+#else //!ENABLE(JIT_OPTIMIZE_METHOD_CALLS)
+
+// Treat these as nops - the call will be handed as a regular get_by_id/op_call pair.
+void JIT::emit_op_method_check(Instruction*) {}
+void JIT::emitSlow_op_method_check(Instruction*, Vector<SlowCaseEntry>::iterator&) { ASSERT_NOT_REACHED(); }
+
+#endif
+
+void JIT::emit_op_get_by_id(Instruction* currentInstruction)
+{
+    unsigned resultVReg = currentInstruction[1].u.operand;
+    unsigned baseVReg = currentInstruction[2].u.operand;
+    Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+    emitGetVirtualRegister(baseVReg, regT0);
+    compileGetByIdHotPath(resultVReg, baseVReg, ident, m_propertyAccessInstructionIndex++);
+    emitPutVirtualRegister(resultVReg);
+}
+
+void JIT::compileGetByIdHotPath(int, int baseVReg, Identifier*, unsigned propertyAccessInstructionIndex)
 {
     // As for put_by_id, get_by_id requires the offset of the Structure and the offset of the access to be patched.
     // Additionally, for get_by_id we need patch the offset of the branch to the slow case (we patch this to jump
     // to array-length / prototype access tranpolines, and finally we also the the property-map access offset as a label
     // to jump back to if one of these trampolies finds a match.
 
-    emitGetVirtualRegister(baseVReg, X86::eax);
-
-    emitJumpSlowCaseIfNotJSCell(X86::eax, baseVReg);
+    emitJumpSlowCaseIfNotJSCell(regT0, baseVReg);
 
     Label hotPathBegin(this);
     m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
 
     DataLabelPtr structureToCompare;
-    Jump structureCheck = jnePtrWithPatch(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
+    Jump structureCheck = branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure)));
     addSlowCase(structureCheck);
     ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetGetByIdStructure);
     ASSERT(differenceBetween(hotPathBegin, structureCheck) == patchOffsetGetByIdBranchToSlowCase);
 
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
-    DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(X86::eax, patchGetByIdDefaultOffset), X86::eax);
+    Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0);
+    Label externalLoadComplete(this);
+    ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetGetByIdExternalLoad);
+    ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthGetByIdExternalLoad);
+
+    DataLabel32 displacementLabel = loadPtrWithAddressOffsetPatch(Address(regT0, patchGetByIdDefaultOffset), regT0);
     ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetGetByIdPropertyMapOffset);
 
     Label putResult(this);
     ASSERT(differenceBetween(hotPathBegin, putResult) == patchOffsetGetByIdPutResult);
-    emitPutVirtualRegister(resultVReg);
 }
 
+void JIT::emitSlow_op_get_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned resultVReg = currentInstruction[1].u.operand;
+    unsigned baseVReg = currentInstruction[2].u.operand;
+    Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
+
+    compileGetByIdSlowCase(resultVReg, baseVReg, ident, iter, false);
+}
 
-void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex)
+void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident, Vector<SlowCaseEntry>::iterator& iter, bool isMethodCheck)
 {
     // As for the hot path of get_by_id, above, we ensure that we can use an architecture specific offset
     // so that we only need track one pointer into the slow case code - we track a pointer to the location
@@ -132,349 +1234,359 @@ void JIT::compileGetByIdSlowCase(int resultVReg, int baseVReg, Identifier* ident
 #ifndef NDEBUG
     Label coldPathBegin(this);
 #endif
-    emitPutJITStubArg(X86::eax, 1);
-    emitPutJITStubArgConstant(ident, 2);
-    Jump call = emitCTICall(Interpreter::cti_op_get_by_id);
-    emitPutVirtualRegister(resultVReg);
+    JITStubCall stubCall(this, isMethodCheck ? cti_op_get_by_id_method_check : cti_op_get_by_id);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(ImmPtr(ident));
+    Call call = stubCall.call(resultVReg);
 
     ASSERT(differenceBetween(coldPathBegin, call) == patchOffsetGetByIdSlowCaseCall);
 
     // Track the location of the call; this will be used to recover patch information.
-    m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
+    m_propertyAccessCompilationInfo[m_propertyAccessInstructionIndex].callReturnLocation = call;
+    m_propertyAccessInstructionIndex++;
 }
 
-void JIT::compilePutByIdHotPath(int baseVReg, Identifier*, int valueVReg, unsigned propertyAccessInstructionIndex)
+void JIT::emit_op_put_by_id(Instruction* currentInstruction)
 {
+    unsigned baseVReg = currentInstruction[1].u.operand;
+    unsigned valueVReg = currentInstruction[3].u.operand;
+
+    unsigned propertyAccessInstructionIndex = m_propertyAccessInstructionIndex++;
+
     // In order to be able to patch both the Structure, and the object offset, we store one pointer,
     // to just after the arguments have been loaded into registers 'hotPathBegin', and we generate code
     // such that the Structure & offset are always at the same distance from this.
 
-    emitGetVirtualRegisters(baseVReg, X86::eax, valueVReg, X86::edx);
+    emitGetVirtualRegisters(baseVReg, regT0, valueVReg, regT1);
 
     // Jump to a slow case if either the base object is an immediate, or if the Structure does not match.
-    emitJumpSlowCaseIfNotJSCell(X86::eax, baseVReg);
+    emitJumpSlowCaseIfNotJSCell(regT0, baseVReg);
 
     Label hotPathBegin(this);
     m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].hotPathBegin = hotPathBegin;
 
     // It is important that the following instruction plants a 32bit immediate, in order that it can be patched over.
     DataLabelPtr structureToCompare;
-    addSlowCase(jnePtrWithPatch(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
+    addSlowCase(branchPtrWithPatch(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), structureToCompare, ImmPtr(reinterpret_cast<void*>(patchGetByIdDefaultStructure))));
     ASSERT(differenceBetween(hotPathBegin, structureToCompare) == patchOffsetPutByIdStructure);
 
     // Plant a load from a bogus ofset in the object's property map; we will patch this later, if it is to be used.
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
-    DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(X86::edx, Address(X86::eax, patchGetByIdDefaultOffset));
+    Label externalLoad = loadPtrWithPatchToLEA(Address(regT0, OBJECT_OFFSETOF(JSObject, m_externalStorage)), regT0);
+    Label externalLoadComplete(this);
+    ASSERT(differenceBetween(hotPathBegin, externalLoad) == patchOffsetPutByIdExternalLoad);
+    ASSERT(differenceBetween(externalLoad, externalLoadComplete) == patchLengthPutByIdExternalLoad);
+
+    DataLabel32 displacementLabel = storePtrWithAddressOffsetPatch(regT1, Address(regT0, patchGetByIdDefaultOffset));
     ASSERT(differenceBetween(hotPathBegin, displacementLabel) == patchOffsetPutByIdPropertyMapOffset);
 }
 
-void JIT::compilePutByIdSlowCase(int baseVReg, Identifier* ident, int, Vector<SlowCaseEntry>::iterator& iter, unsigned propertyAccessInstructionIndex)
+void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
+    unsigned baseVReg = currentInstruction[1].u.operand;
+    Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
+
+    unsigned propertyAccessInstructionIndex = m_propertyAccessInstructionIndex++;
+
     linkSlowCaseIfNotJSCell(iter, baseVReg);
     linkSlowCase(iter);
 
-    emitPutJITStubArgConstant(ident, 2);
-    emitPutJITStubArg(X86::eax, 1);
-    emitPutJITStubArg(X86::edx, 3);
-    Jump call = emitCTICall(Interpreter::cti_op_put_by_id);
+    JITStubCall stubCall(this, cti_op_put_by_id);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(ImmPtr(ident));
+    stubCall.addArgument(regT1);
+    Call call = stubCall.call();
 
     // Track the location of the call; this will be used to recover patch information.
     m_propertyAccessCompilationInfo[propertyAccessInstructionIndex].callReturnLocation = call;
 }
 
-static JSObject* resizePropertyStorage(JSObject* baseObject, int32_t oldSize, int32_t newSize)
+// Compile a store into an object's property storage.  May overwrite the
+// value in objectReg.
+void JIT::compilePutDirectOffset(RegisterID base, RegisterID value, Structure* structure, size_t cachedOffset)
+{
+    int offset = cachedOffset * sizeof(JSValue);
+    if (structure->isUsingInlineStorage())
+        offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage);
+    else
+        loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
+    storePtr(value, Address(base, offset));
+}
+
+// Compile a load from an object's property storage.  May overwrite base.
+void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, Structure* structure, size_t cachedOffset)
 {
-    baseObject->allocatePropertyStorage(oldSize, newSize);
-    return baseObject;
+    int offset = cachedOffset * sizeof(JSValue);
+    if (structure->isUsingInlineStorage())
+        offset += OBJECT_OFFSETOF(JSObject, m_inlineStorage);
+    else
+        loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
+    loadPtr(Address(base, offset), result);
 }
 
-static inline bool transitionWillNeedStorageRealloc(Structure* oldStructure, Structure* newStructure)
+void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset)
 {
-    return oldStructure->propertyStorageCapacity() != newStructure->propertyStorageCapacity();
+    if (base->isUsingInlineStorage())
+        loadPtr(static_cast<void*>(&base->m_inlineStorage[cachedOffset]), result);
+    else {
+        PropertyStorage* protoPropertyStorage = &base->m_externalStorage;
+        loadPtr(static_cast<void*>(protoPropertyStorage), temp);
+        loadPtr(Address(temp, cachedOffset * sizeof(JSValue)), result);
+    } 
 }
 
-void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, void* returnAddress)
+void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress)
 {
     JumpList failureCases;
     // Check eax is an object of the right Structure.
-    failureCases.append(emitJumpIfNotJSCell(X86::eax));
-    failureCases.append(jnePtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(oldStructure)));
+    failureCases.append(emitJumpIfNotJSCell(regT0));
+    failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure)));
     JumpList successCases;
 
-    //  ecx = baseObject
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
+    // ecx = baseObject
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
     // proto(ecx) = baseObject->structure()->prototype()
-    failureCases.append(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
+    failureCases.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType)));
 
-    loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
     
     // ecx = baseObject->m_structure
     for (RefPtr<Structure>* it = chain->head(); *it; ++it) {
         // null check the prototype
-        successCases.append(jePtr(X86::ecx, ImmPtr(JSValuePtr::encode(jsNull()))));
+        successCases.append(branchPtr(Equal, regT2, ImmPtr(JSValue::encode(jsNull()))));
 
         // Check the structure id
-        failureCases.append(jnePtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), ImmPtr(it->get())));
+        failureCases.append(branchPtr(NotEqual, Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(it->get())));
         
-        loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
-        failureCases.append(jne32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
-        loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
+        loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+        failureCases.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo) + OBJECT_OFFSETOF(TypeInfo, m_type)), Imm32(ObjectType)));
+        loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype)), regT2);
     }
 
     successCases.link(this);
 
-    Jump callTarget;
+    Call callTarget;
 
     // emit a call only if storage realloc is needed
-    if (transitionWillNeedStorageRealloc(oldStructure, newStructure)) {
-        pop(X86::ebx);
-#if PLATFORM(X86_64)
-        move(Imm32(newStructure->propertyStorageCapacity()), X86::edx);
-        move(Imm32(oldStructure->propertyStorageCapacity()), X86::esi);
-        move(X86::eax, X86::edi);
-        callTarget = call();
-#else
-        push(Imm32(newStructure->propertyStorageCapacity()));
-        push(Imm32(oldStructure->propertyStorageCapacity()));
-        push(X86::eax);
-        callTarget = call();
-        addPtr(Imm32(3 * sizeof(void*)), X86::esp);
-#endif
-        emitGetJITStubArg(3, X86::edx);
-        push(X86::ebx);
+    bool willNeedStorageRealloc = oldStructure->propertyStorageCapacity() != newStructure->propertyStorageCapacity();
+    if (willNeedStorageRealloc) {
+        // This trampoline was called to like a JIT stub; before we can can call again we need to
+        // remove the return address from the stack, to prevent the stack from becoming misaligned.
+        preserveReturnAddressAfterCall(regT3);
+        JITStubCall stubCall(this, cti_op_put_by_id_transition_realloc);
+        stubCall.skipArgument(); // base
+        stubCall.skipArgument(); // ident
+        stubCall.skipArgument(); // value
+        stubCall.addArgument(Imm32(oldStructure->propertyStorageCapacity()));
+        stubCall.addArgument(Imm32(newStructure->propertyStorageCapacity()));
+        stubCall.call(regT0);
+        emitGetJITStubArg(3, regT1);
+
+        restoreReturnAddressBeforeReturn(regT3);
     }
 
     // Assumes m_refCount can be decremented easily, refcount decrement is safe as 
     // codeblock should ensure oldStructure->m_refCount > 0
     sub32(Imm32(1), AbsoluteAddress(oldStructure->addressOfCount()));
     add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount()));
-    storePtr(ImmPtr(newStructure), Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)));
+    storePtr(ImmPtr(newStructure), Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)));
 
     // write the value
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
-    storePtr(X86::edx, Address(X86::eax, cachedOffset * sizeof(JSValuePtr)));
+    compilePutDirectOffset(regT0, regT1, newStructure, cachedOffset);
 
     ret();
     
-    Jump failureJump;
-    bool plantedFailureJump = false;
-    if (!failureCases.empty()) {
-        failureCases.link(this);
-        restoreArgumentReferenceForTrampoline();
-        failureJump = jump();
-        plantedFailureJump = true;
-    }
+    ASSERT(!failureCases.empty());
+    failureCases.link(this);
+    restoreArgumentReferenceForTrampoline();
+    Call failureCall = tailRecursiveCall();
 
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    PatchBuffer patchBuffer(code);
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
-    if (plantedFailureJump)
-        patchBuffer.link(failureJump, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));
+    patchBuffer.link(failureCall, FunctionPtr(cti_op_put_by_id_fail));
 
-    if (transitionWillNeedStorageRealloc(oldStructure, newStructure))
-        patchBuffer.link(callTarget, reinterpret_cast<void*>(resizePropertyStorage));
-    
-    stubInfo->stubRoutine = code;
+    if (willNeedStorageRealloc) {
+        ASSERT(m_calls.size() == 1);
+        patchBuffer.link(m_calls[0].from, FunctionPtr(cti_op_put_by_id_transition_realloc));
+    }
     
-    Jump::patch(returnAddress, code);
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+    stubInfo->stubRoutine = entryLabel;
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relinkCallerToTrampoline(returnAddress, entryLabel);
 }
 
-void JIT::patchGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+void JIT::patchGetByIdSelf(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress)
 {
+    RepatchBuffer repatchBuffer(codeBlock);
+
     // We don't want to patch more than once - in future go to cti_op_get_by_id_generic.
-    // Should probably go to Interpreter::cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
-    Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));
+    // Should probably go to cti_op_get_by_id_fail, but that doesn't do anything interesting right now.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
+
+    int offset = sizeof(JSValue) * cachedOffset;
+
+    // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load
+    // and makes the subsequent load's offset automatically correct
+    if (structure->isUsingInlineStorage())
+        repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetGetByIdExternalLoad));
 
     // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
-    void* structureAddress = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdStructure);
-    void* displacementAddress = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPropertyMapOffset);
-    DataLabelPtr::patch(structureAddress, structure);
-    DataLabel32::patch(displacementAddress, cachedOffset * sizeof(JSValuePtr));
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetGetByIdStructure), structure);
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetGetByIdPropertyMapOffset), offset);
+}
+
+void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodCallLinkInfo, JSFunction* callee, Structure* structure, JSObject* proto)
+{
+    RepatchBuffer repatchBuffer(codeBlock);
+
+    ASSERT(!methodCallLinkInfo.cachedStructure);
+    methodCallLinkInfo.cachedStructure = structure;
+    structure->ref();
+
+    Structure* prototypeStructure = proto->structure();
+    ASSERT(!methodCallLinkInfo.cachedPrototypeStructure);
+    methodCallLinkInfo.cachedPrototypeStructure = prototypeStructure;
+    prototypeStructure->ref();
+
+    repatchBuffer.repatch(methodCallLinkInfo.structureLabel, structure);
+    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoObj), proto);
+    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckProtoStruct), prototypeStructure);
+    repatchBuffer.repatch(methodCallLinkInfo.structureLabel.dataLabelPtrAtOffset(patchOffsetMethodCheckPutFunction), callee);
 }
 
-void JIT::patchPutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
+void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress)
 {
+    RepatchBuffer repatchBuffer(codeBlock);
+
     // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
-    // Should probably go to Interpreter::cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
-    Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_generic));
+    // Should probably go to cti_op_put_by_id_fail, but that doesn't do anything interesting right now.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_put_by_id_generic));
+
+    int offset = sizeof(JSValue) * cachedOffset;
+
+    // If we're patching to use inline storage, convert the initial load to a lea; this avoids the extra load
+    // and makes the subsequent load's offset automatically correct
+    if (structure->isUsingInlineStorage())
+        repatchBuffer.repatchLoadPtrToLEA(stubInfo->hotPathBegin.instructionAtOffset(patchOffsetPutByIdExternalLoad));
 
     // Patch the offset into the propoerty map to load from, then patch the Structure to look for.
-    void* structureAddress = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetPutByIdStructure;
-    void* displacementAddress = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetPutByIdPropertyMapOffset;
-    DataLabelPtr::patch(structureAddress, structure);
-    DataLabel32::patch(displacementAddress, cachedOffset * sizeof(JSValuePtr));
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabelPtrAtOffset(patchOffsetPutByIdStructure), structure);
+    repatchBuffer.repatch(stubInfo->hotPathBegin.dataLabel32AtOffset(patchOffsetPutByIdPropertyMapOffset), offset);
 }
 
-void JIT::privateCompilePatchGetArrayLength(void* returnAddress)
+void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
 {
     StructureStubInfo* stubInfo = &m_codeBlock->getStubInfo(returnAddress);
 
-    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
-    Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_array_fail));
-
     // Check eax is an array
-    Jump failureCases1 = jnePtr(Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr));
+    Jump failureCases1 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsArrayVPtr));
 
     // Checks out okay! - get the length from the storage
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
-    load32(Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_length)), X86::ecx);
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT2);
+    load32(Address(regT2, OBJECT_OFFSETOF(ArrayStorage, m_length)), regT2);
 
-    Jump failureCases2 = ja32(X86::ecx, Imm32(JSImmediate::maxImmediateInt));
+    Jump failureCases2 = branch32(Above, regT2, Imm32(JSImmediate::maxImmediateInt));
 
-    emitFastArithIntToImmNoCheck(X86::ecx, X86::eax);
+    emitFastArithIntToImmNoCheck(regT2, regT0);
     Jump success = jump();
 
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    PatchBuffer patchBuffer(code);
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
     // Use the patch information to link the failure cases back to the original slow case routine.
-    void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+    CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);
     patchBuffer.link(failureCases1, slowCaseBegin);
     patchBuffer.link(failureCases2, slowCaseBegin);
 
     // On success return back to the hot patch code, at a point it will perform the store to dest for us.
-    void* hotPathPutResult = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
-    patchBuffer.link(success, hotPathPutResult);
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
 
     // Track the stub we have created so that it will be deleted later.
-    stubInfo->stubRoutine = code;
-
-    // Finally patch the jump to sow case back in the hot path to jump here instead.
-    void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
-    Jump::patch(jumpLocation, code);
-}
-
-void JIT::privateCompileGetByIdSelf(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
-{
-    // Check eax is an object of the right Structure.
-    Jump failureCases1 = emitJumpIfNotJSCell(X86::eax);
-    Jump failureCases2 = checkStructure(X86::eax, structure);
-
-    // Checks out okay! - getDirectOffset
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
-    loadPtr(Address(X86::eax, cachedOffset * sizeof(JSValuePtr)), X86::eax);
-    ret();
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+    stubInfo->stubRoutine = entryLabel;
 
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    PatchBuffer patchBuffer(code);
-
-    patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));
-    patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_self_fail));
-
-    stubInfo->stubRoutine = code;
+    // Finally patch the jump to slow case back in the hot path to jump here instead.
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
 
-    Jump::patch(returnAddress, code);
+    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail));
 }
 
-void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, void* returnAddress, CallFrame* callFrame)
+void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
 {
-#if USE(CTI_REPATCH_PIC)
-    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
-    Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list));
-
     // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
     // referencing the prototype object - let's speculatively load it's table nice and early!)
     JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
-    PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
-    loadPtr(static_cast<void*>(protoPropertyStorage), X86::edx);
 
     // Check eax is an object of the right Structure.
-    Jump failureCases1 = checkStructure(X86::eax, structure);
+    Jump failureCases1 = checkStructure(regT0, structure);
 
     // Check the prototype object's Structure had not changed.
     Structure** prototypeStructureAddress = &(protoObject->m_structure);
 #if PLATFORM(X86_64)
-    move(ImmPtr(prototypeStructure), X86::ebx);
-    Jump failureCases2 = jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress));
+    move(ImmPtr(prototypeStructure), regT3);
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
 #else
-    Jump failureCases2 = jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
 #endif
 
     // Checks out okay! - getDirectOffset
-    loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+    compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
 
     Jump success = jump();
 
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    PatchBuffer patchBuffer(code);
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
     // Use the patch information to link the failure cases back to the original slow case routine.
-    void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+    CodeLocationLabel slowCaseBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);
     patchBuffer.link(failureCases1, slowCaseBegin);
     patchBuffer.link(failureCases2, slowCaseBegin);
 
     // On success return back to the hot patch code, at a point it will perform the store to dest for us.
-    intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
-    patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
 
     // Track the stub we have created so that it will be deleted later.
-    stubInfo->stubRoutine = code;
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+    stubInfo->stubRoutine = entryLabel;
 
     // Finally patch the jump to slow case back in the hot path to jump here instead.
-    void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
-    Jump::patch(jumpLocation, code);
-#else
-    // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
-    // referencing the prototype object - let's speculatively load it's table nice and early!)
-    JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
-    PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
-    loadPtr(protoPropertyStorage, X86::edx);
-
-    // Check eax is an object of the right Structure.
-    Jump failureCases1 = emitJumpIfNotJSCell(X86::eax);
-    Jump failureCases2 = checkStructure(X86::eax, structure);
-
-    // Check the prototype object's Structure had not changed.
-    Structure** prototypeStructureAddress = &(protoObject->m_structure);
-    Jump failureCases3 = jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
-
-    // Checks out okay! - getDirectOffset
-    loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
-
-    ret();
-
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    PatchBuffer patchBuffer(code);
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
 
-    patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
-    patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
-    patchBuffer.link(failureCases3, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
-
-    stubInfo->stubRoutine = code;
-
-    Jump::patch(returnAddress, code);
-#endif
+    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
 }
 
-#if USE(CTI_REPATCH_PIC)
 void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset)
 {
-    Jump failureCase = checkStructure(X86::eax, structure);
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
-    loadPtr(Address(X86::eax, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+    Jump failureCase = checkStructure(regT0, structure);
+    compileGetDirectOffset(regT0, regT0, structure, cachedOffset);
     Jump success = jump();
 
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    ASSERT(code);
-    PatchBuffer patchBuffer(code);
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
     // Use the patch information to link the failure cases back to the original slow case routine.
-    void* lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine;
+    CodeLocationLabel lastProtoBegin = polymorphicStructures->list[currentIndex - 1].stubRoutine;
     if (!lastProtoBegin)
-        lastProtoBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
+        lastProtoBegin = stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall);
 
     patchBuffer.link(failureCase, lastProtoBegin);
 
     // On success return back to the hot patch code, at a point it will perform the store to dest for us.
-    intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
-    patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
 
     structure->ref();
-    polymorphicStructures->list[currentIndex].set(code, structure);
+    polymorphicStructures->list[currentIndex].set(entryLabel, structure);
 
     // Finally patch the jump to slow case back in the hot path to jump here instead.
-    void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
-    Jump::patch(jumpLocation, code);
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
 }
 
 void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame)
@@ -482,45 +1594,44 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
     // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is
     // referencing the prototype object - let's speculatively load it's table nice and early!)
     JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
-    PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
-    loadPtr(protoPropertyStorage, X86::edx);
 
     // Check eax is an object of the right Structure.
-    Jump failureCases1 = checkStructure(X86::eax, structure);
+    Jump failureCases1 = checkStructure(regT0, structure);
 
     // Check the prototype object's Structure had not changed.
     Structure** prototypeStructureAddress = &(protoObject->m_structure);
 #if PLATFORM(X86_64)
-    move(ImmPtr(prototypeStructure), X86::ebx);
-    Jump failureCases2 = jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress));
+    move(ImmPtr(prototypeStructure), regT3);
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
 #else
-    Jump failureCases2 = jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
 #endif
 
     // Checks out okay! - getDirectOffset
-    loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+    compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
 
     Jump success = jump();
 
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    PatchBuffer patchBuffer(code);
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
     // Use the patch information to link the failure cases back to the original slow case routine.
-    void* lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
+    CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
     patchBuffer.link(failureCases1, lastProtoBegin);
     patchBuffer.link(failureCases2, lastProtoBegin);
 
     // On success return back to the hot patch code, at a point it will perform the store to dest for us.
-    intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
-    patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
 
     structure->ref();
     prototypeStructure->ref();
-    prototypeStructures->list[currentIndex].set(code, structure, prototypeStructure);
+    prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure);
 
     // Finally patch the jump to slow case back in the hot path to jump here instead.
-    void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
-    Jump::patch(jumpLocation, code);
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
 }
 
 void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame)
@@ -530,7 +1641,7 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
     JumpList bucketsOfFail;
 
     // Check eax is an object of the right Structure.
-    Jump baseObjectCheck = checkStructure(X86::eax, structure);
+    Jump baseObjectCheck = checkStructure(regT0, structure);
     bucketsOfFail.append(baseObjectCheck);
 
     Structure* currStructure = structure;
@@ -543,54 +1654,48 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
         // Check the prototype object's Structure had not changed.
         Structure** prototypeStructureAddress = &(protoObject->m_structure);
 #if PLATFORM(X86_64)
-        move(ImmPtr(currStructure), X86::ebx);
-        bucketsOfFail.append(jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress)));
+        move(ImmPtr(currStructure), regT3);
+        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
 #else
-        bucketsOfFail.append(jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
 #endif
     }
     ASSERT(protoObject);
 
-    PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
-    loadPtr(protoPropertyStorage, X86::edx);
-    loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+    compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     Jump success = jump();
 
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    PatchBuffer patchBuffer(code);
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
     // Use the patch information to link the failure cases back to the original slow case routine.
-    void* lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
+    CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
 
     patchBuffer.link(bucketsOfFail, lastProtoBegin);
 
     // On success return back to the hot patch code, at a point it will perform the store to dest for us.
-    intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
-    patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
+
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
 
     // Track the stub we have created so that it will be deleted later.
     structure->ref();
     chain->ref();
-    prototypeStructures->list[currentIndex].set(code, structure, chain);
+    prototypeStructures->list[currentIndex].set(entryLabel, structure, chain);
 
     // Finally patch the jump to slow case back in the hot path to jump here instead.
-    void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
-    Jump::patch(jumpLocation, code);
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
 }
-#endif
 
-void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, void* returnAddress, CallFrame* callFrame)
+void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
 {
-#if USE(CTI_REPATCH_PIC)
-    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
-    Jump::patch(returnAddress, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_list));
-
     ASSERT(count);
     
     JumpList bucketsOfFail;
 
     // Check eax is an object of the right Structure.
-    bucketsOfFail.append(checkStructure(X86::eax, structure));
+    bucketsOfFail.append(checkStructure(regT0, structure));
 
     Structure* currStructure = structure;
     RefPtr<Structure>* chainEntries = chain->head();
@@ -602,102 +1707,43 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
         // Check the prototype object's Structure had not changed.
         Structure** prototypeStructureAddress = &(protoObject->m_structure);
 #if PLATFORM(X86_64)
-        move(ImmPtr(currStructure), X86::ebx);
-        bucketsOfFail.append(jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress)));
+        move(ImmPtr(currStructure), regT3);
+        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
 #else
-        bucketsOfFail.append(jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
 #endif
     }
     ASSERT(protoObject);
 
-    PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
-    loadPtr(protoPropertyStorage, X86::edx);
-    loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
+    compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     Jump success = jump();
 
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    PatchBuffer patchBuffer(code);
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
     // Use the patch information to link the failure cases back to the original slow case routine.
-    void* slowCaseBegin = reinterpret_cast<char*>(stubInfo->callReturnLocation) - patchOffsetGetByIdSlowCaseCall;
-
-    patchBuffer.link(bucketsOfFail, slowCaseBegin);
+    patchBuffer.link(bucketsOfFail, stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall));
 
     // On success return back to the hot patch code, at a point it will perform the store to dest for us.
-    intptr_t successDest = reinterpret_cast<intptr_t>(stubInfo->hotPathBegin) + patchOffsetGetByIdPutResult;
-    patchBuffer.link(success, reinterpret_cast<void*>(successDest));
+    patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));
 
     // Track the stub we have created so that it will be deleted later.
-    stubInfo->stubRoutine = code;
+    CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
+    stubInfo->stubRoutine = entryLabel;
 
     // Finally patch the jump to slow case back in the hot path to jump here instead.
-    void* jumpLocation = reinterpret_cast<char*>(stubInfo->hotPathBegin) + patchOffsetGetByIdBranchToSlowCase;
-    Jump::patch(jumpLocation, code);
-#else
-    ASSERT(count);
-    
-    JumpList bucketsOfFail;
-
-    // Check eax is an object of the right Structure.
-    bucketsOfFail.append(emitJumpIfNotJSCell(X86::eax));
-    bucketsOfFail.append(checkStructure(X86::eax, structure));
-
-    Structure* currStructure = structure;
-    RefPtr<Structure>* chainEntries = chain->head();
-    JSObject* protoObject = 0;
-    for (unsigned i = 0; i < count; ++i) {
-        protoObject = asObject(currStructure->prototypeForLookup(callFrame));
-        currStructure = chainEntries[i].get();
-
-        // Check the prototype object's Structure had not changed.
-        Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if PLATFORM(X86_64)
-        move(ImmPtr(currStructure), X86::ebx);
-        bucketsOfFail.append(jnePtr(X86::ebx, AbsoluteAddress(prototypeStructureAddress)));
-#else
-        bucketsOfFail.append(jnePtr(AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
-#endif
-    }
-    ASSERT(protoObject);
+    CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);
+    RepatchBuffer repatchBuffer(m_codeBlock);
+    repatchBuffer.relink(jumpLocation, entryLabel);
 
-    PropertyStorage* protoPropertyStorage = &protoObject->m_propertyStorage;
-    loadPtr(protoPropertyStorage, X86::edx);
-    loadPtr(Address(X86::edx, cachedOffset * sizeof(JSValuePtr)), X86::eax);
-    ret();
-
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-
-    patchBuffer.link(bucketsOfFail, reinterpret_cast<void*>(Interpreter::cti_op_get_by_id_proto_fail));
-
-    stubInfo->stubRoutine = code;
-
-    Jump::patch(returnAddress, code);
-#endif
+    // We don't want to patch more than once - in future go to cti_op_put_by_id_generic.
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
 }
 
-void JIT::privateCompilePutByIdReplace(StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, void* returnAddress)
-{
-    // Check eax is an object of the right Structure.
-    Jump failureCases1 = emitJumpIfNotJSCell(X86::eax);
-    Jump failureCases2 = checkStructure(X86::eax, structure);
-
-    // checks out okay! - putDirectOffset
-    loadPtr(Address(X86::eax, FIELD_OFFSET(JSObject, m_propertyStorage)), X86::eax);
-    storePtr(X86::edx, Address(X86::eax, cachedOffset * sizeof(JSValuePtr)));
-    ret();
-
-    void* code = m_assembler.executableCopy(m_codeBlock->executablePool());
-    PatchBuffer patchBuffer(code);
-    
-    patchBuffer.link(failureCases1, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));
-    patchBuffer.link(failureCases2, reinterpret_cast<void*>(Interpreter::cti_op_put_by_id_fail));
+/* ------------------------------ END: !ENABLE / ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) ------------------------------ */
 
-    stubInfo->stubRoutine = code;
-    
-    Jump::patch(returnAddress, code);
-}
+#endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
 
-#endif
+#endif // USE(JSVALUE32_64)
 
 } // namespace JSC
 
diff --git a/jit/JITStubCall.h b/jit/JITStubCall.h
new file mode 100644 (file)
index 0000000..cb5354b
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JITStubCall_h
+#define JITStubCall_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+    class JITStubCall {
+    public:
+        JITStubCall(JIT* jit, JSObject* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
+            : m_jit(jit)
+            , m_stub(reinterpret_cast<void*>(stub))
+            , m_returnType(Cell)
+            , m_stackIndex(stackIndexStart)
+        {
+        }
+
+        JITStubCall(JIT* jit, JSPropertyNameIterator* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
+            : m_jit(jit)
+            , m_stub(reinterpret_cast<void*>(stub))
+            , m_returnType(Cell)
+            , m_stackIndex(stackIndexStart)
+        {
+        }
+
+        JITStubCall(JIT* jit, void* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
+            : m_jit(jit)
+            , m_stub(reinterpret_cast<void*>(stub))
+            , m_returnType(VoidPtr)
+            , m_stackIndex(stackIndexStart)
+        {
+        }
+
+        JITStubCall(JIT* jit, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
+            : m_jit(jit)
+            , m_stub(reinterpret_cast<void*>(stub))
+            , m_returnType(Int)
+            , m_stackIndex(stackIndexStart)
+        {
+        }
+
+        JITStubCall(JIT* jit, bool (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
+            : m_jit(jit)
+            , m_stub(reinterpret_cast<void*>(stub))
+            , m_returnType(Int)
+            , m_stackIndex(stackIndexStart)
+        {
+        }
+
+        JITStubCall(JIT* jit, void (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
+            : m_jit(jit)
+            , m_stub(reinterpret_cast<void*>(stub))
+            , m_returnType(Void)
+            , m_stackIndex(stackIndexStart)
+        {
+        }
+
+#if USE(JSVALUE32_64)
+        JITStubCall(JIT* jit, EncodedJSValue (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
+            : m_jit(jit)
+            , m_stub(reinterpret_cast<void*>(stub))
+            , m_returnType(Value)
+            , m_stackIndex(stackIndexStart)
+        {
+        }
+#endif
+
+        // Arguments are added first to last.
+
+        void skipArgument()
+        {
+            m_stackIndex += stackIndexStep;
+        }
+
+        void addArgument(JIT::Imm32 argument)
+        {
+            m_jit->poke(argument, m_stackIndex);
+            m_stackIndex += stackIndexStep;
+        }
+
+        void addArgument(JIT::ImmPtr argument)
+        {
+            m_jit->poke(argument, m_stackIndex);
+            m_stackIndex += stackIndexStep;
+        }
+
+        void addArgument(JIT::RegisterID argument)
+        {
+            m_jit->poke(argument, m_stackIndex);
+            m_stackIndex += stackIndexStep;
+        }
+
+        void addArgument(const JSValue& value)
+        {
+            m_jit->poke(JIT::Imm32(value.payload()), m_stackIndex);
+            m_jit->poke(JIT::Imm32(value.tag()), m_stackIndex + 1);
+            m_stackIndex += stackIndexStep;
+        }
+
+        void addArgument(JIT::RegisterID tag, JIT::RegisterID payload)
+        {
+            m_jit->poke(payload, m_stackIndex);
+            m_jit->poke(tag, m_stackIndex + 1);
+            m_stackIndex += stackIndexStep;
+        }
+
+#if USE(JSVALUE32_64)
+        void addArgument(unsigned srcVirtualRegister)
+        {
+            if (m_jit->m_codeBlock->isConstantRegisterIndex(srcVirtualRegister)) {
+                addArgument(m_jit->getConstantOperand(srcVirtualRegister));
+                return;
+            }
+
+            m_jit->emitLoad(srcVirtualRegister, JIT::regT1, JIT::regT0);
+            addArgument(JIT::regT1, JIT::regT0);
+        }
+
+        void getArgument(size_t argumentNumber, JIT::RegisterID tag, JIT::RegisterID payload)
+        {
+            size_t stackIndex = stackIndexStart + (argumentNumber * stackIndexStep);
+            m_jit->peek(payload, stackIndex);
+            m_jit->peek(tag, stackIndex + 1);
+        }
+#else
+        void addArgument(unsigned src, JIT::RegisterID scratchRegister) // src is a virtual register.
+        {
+            if (m_jit->m_codeBlock->isConstantRegisterIndex(src))
+                addArgument(JIT::ImmPtr(JSValue::encode(m_jit->m_codeBlock->getConstant(src))));
+            else {
+                m_jit->loadPtr(JIT::Address(JIT::callFrameRegister, src * sizeof(Register)), scratchRegister);
+                addArgument(scratchRegister);
+            }
+            m_jit->killLastResultRegister();
+        }
+#endif
+
+        JIT::Call call()
+        {
+#if ENABLE(OPCODE_SAMPLING)
+            if (m_jit->m_bytecodeIndex != (unsigned)-1)
+                m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeIndex, true);
+#endif
+
+            m_jit->restoreArgumentReference();
+            JIT::Call call = m_jit->call();
+            m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeIndex, m_stub));
+
+#if ENABLE(OPCODE_SAMPLING)
+            if (m_jit->m_bytecodeIndex != (unsigned)-1)
+                m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeIndex, false);
+#endif
+
+#if USE(JSVALUE32_64)
+            m_jit->unmap();
+#else
+            m_jit->killLastResultRegister();
+#endif
+            return call;
+        }
+
+#if USE(JSVALUE32_64)
+        JIT::Call call(unsigned dst) // dst is a virtual register.
+        {
+            ASSERT(m_returnType == Value || m_returnType == Cell);
+            JIT::Call call = this->call();
+            if (m_returnType == Value)
+                m_jit->emitStore(dst, JIT::regT1, JIT::regT0);
+            else
+                m_jit->emitStoreCell(dst, JIT::returnValueRegister);
+            return call;
+        }
+#else
+        JIT::Call call(unsigned dst) // dst is a virtual register.
+        {
+            ASSERT(m_returnType == VoidPtr || m_returnType == Cell);
+            JIT::Call call = this->call();
+            m_jit->emitPutVirtualRegister(dst);
+            return call;
+        }
+#endif
+
+        JIT::Call call(JIT::RegisterID dst) // dst is a machine register.
+        {
+#if USE(JSVALUE32_64)
+            ASSERT(m_returnType == Value || m_returnType == VoidPtr || m_returnType == Int || m_returnType == Cell);
+#else
+            ASSERT(m_returnType == VoidPtr || m_returnType == Int || m_returnType == Cell);
+#endif
+            JIT::Call call = this->call();
+            if (dst != JIT::returnValueRegister)
+                m_jit->move(JIT::returnValueRegister, dst);
+            return call;
+        }
+
+    private:
+        static const size_t stackIndexStep = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 2 : 1;
+        static const size_t stackIndexStart = 1; // Index 0 is reserved for restoreArgumentReference().
+
+        JIT* m_jit;
+        void* m_stub;
+        enum { Void, VoidPtr, Int, Value, Cell } m_returnType;
+        size_t m_stackIndex;
+    };
+}
+
+#endif // ENABLE(JIT)
+
+#endif // JITStubCall_h
diff --git a/jit/JITStubs.cpp b/jit/JITStubs.cpp
new file mode 100644 (file)
index 0000000..a7011e8
--- /dev/null
@@ -0,0 +1,3036 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JITStubs.h"
+
+#if ENABLE(JIT)
+
+#include "Arguments.h"
+#include "CallFrame.h"
+#include "CodeBlock.h"
+#include "Collector.h"
+#include "Debugger.h"
+#include "ExceptionHelpers.h"
+#include "GlobalEvalFunction.h"
+#include "JIT.h"
+#include "JSActivation.h"
+#include "JSArray.h"
+#include "JSByteArray.h"
+#include "JSFunction.h"
+#include "JSNotAnObject.h"
+#include "JSPropertyNameIterator.h"
+#include "JSStaticScopeObject.h"
+#include "JSString.h"
+#include "ObjectPrototype.h"
+#include "Operations.h"
+#include "Parser.h"
+#include "Profiler.h"
+#include "RegExpObject.h"
+#include "RegExpPrototype.h"
+#include "Register.h"
+#include "SamplingTool.h"
+#include <stdarg.h>
+#include <stdio.h>
+
+using namespace std;
+
+namespace JSC {
+
+#if PLATFORM(DARWIN) || PLATFORM(WIN_OS)
+#define SYMBOL_STRING(name) "_" #name
+#else
+#define SYMBOL_STRING(name) #name
+#endif
+
+#if USE(JSVALUE32_64)
+
+#if COMPILER(GCC) && PLATFORM(X86)
+
+// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
+// need to change the assembly trampolines below to match.
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x3c, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_offset_matches_ctiTrampoline);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+    "pushl %ebp" "\n"
+    "movl %esp, %ebp" "\n"
+    "pushl %esi" "\n"
+    "pushl %edi" "\n"
+    "pushl %ebx" "\n"
+    "subl $0x3c, %esp" "\n"
+    "movl $512, %esi" "\n"
+    "movl 0x58(%esp), %edi" "\n"
+    "call *0x50(%esp)" "\n"
+    "addl $0x3c, %esp" "\n"
+    "popl %ebx" "\n"
+    "popl %edi" "\n"
+    "popl %esi" "\n"
+    "popl %ebp" "\n"
+    "ret" "\n"
+);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+#if !USE(JIT_STUB_ARGUMENT_VA_LIST)
+    "movl %esp, %ecx" "\n"
+#endif
+    "call " SYMBOL_STRING(cti_vm_throw) "\n"
+    "addl $0x3c, %esp" "\n"
+    "popl %ebx" "\n"
+    "popl %edi" "\n"
+    "popl %esi" "\n"
+    "popl %ebp" "\n"
+    "ret" "\n"
+);
+    
+asm volatile (
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+    "addl $0x3c, %esp" "\n"
+    "popl %ebx" "\n"
+    "popl %edi" "\n"
+    "popl %esi" "\n"
+    "popl %ebp" "\n"
+    "ret" "\n"
+);
+    
+#elif COMPILER(GCC) && PLATFORM(X86_64)
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#error "JIT_STUB_ARGUMENT_VA_LIST not supported on x86-64."
+#endif
+
+// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
+// need to change the assembly trampolines below to match.
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 32 == 0x0, JITStackFrame_maintains_32byte_stack_alignment);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x48, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x90, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x80, JITStackFrame_code_offset_matches_ctiTrampoline);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+    "pushq %rbp" "\n"
+    "movq %rsp, %rbp" "\n"
+    "pushq %r12" "\n"
+    "pushq %r13" "\n"
+    "pushq %r14" "\n"
+    "pushq %r15" "\n"
+    "pushq %rbx" "\n"
+    "subq $0x48, %rsp" "\n"
+    "movq $512, %r12" "\n"
+    "movq $0xFFFF000000000000, %r14" "\n"
+    "movq $0xFFFF000000000002, %r15" "\n"
+    "movq 0x90(%rsp), %r13" "\n"
+    "call *0x80(%rsp)" "\n"
+    "addq $0x48, %rsp" "\n"
+    "popq %rbx" "\n"
+    "popq %r15" "\n"
+    "popq %r14" "\n"
+    "popq %r13" "\n"
+    "popq %r12" "\n"
+    "popq %rbp" "\n"
+    "ret" "\n"
+);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+    "movq %rsp, %rdi" "\n"
+    "call " SYMBOL_STRING(cti_vm_throw) "\n"
+    "addq $0x48, %rsp" "\n"
+    "popq %rbx" "\n"
+    "popq %r15" "\n"
+    "popq %r14" "\n"
+    "popq %r13" "\n"
+    "popq %r12" "\n"
+    "popq %rbp" "\n"
+    "ret" "\n"
+);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+    "addq $0x48, %rsp" "\n"
+    "popq %rbx" "\n"
+    "popq %r15" "\n"
+    "popq %r14" "\n"
+    "popq %r13" "\n"
+    "popq %r12" "\n"
+    "popq %rbp" "\n"
+    "ret" "\n"
+);
+
+#elif COMPILER(GCC) && PLATFORM_ARM_ARCH(7)
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7."
+#endif
+
+asm volatile (
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+".thumb" "\n"
+".thumb_func " SYMBOL_STRING(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+    "sub sp, sp, #0x3c" "\n"
+    "str lr, [sp, #0x20]" "\n"
+    "str r4, [sp, #0x24]" "\n"
+    "str r5, [sp, #0x28]" "\n"
+    "str r6, [sp, #0x2c]" "\n"
+    "str r1, [sp, #0x30]" "\n"
+    "str r2, [sp, #0x34]" "\n"
+    "str r3, [sp, #0x38]" "\n"
+    "cpy r5, r2" "\n"
+    "mov r6, #512" "\n"
+    "blx r0" "\n"
+    "ldr r6, [sp, #0x2c]" "\n"
+    "ldr r5, [sp, #0x28]" "\n"
+    "ldr r4, [sp, #0x24]" "\n"
+    "ldr lr, [sp, #0x20]" "\n"
+    "add sp, sp, #0x3c" "\n"
+    "bx lr" "\n"
+);
+
+asm volatile (
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+".thumb" "\n"
+".thumb_func " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+    "cpy r0, sp" "\n"
+    "bl " SYMBOL_STRING(cti_vm_throw) "\n"
+    "ldr r6, [sp, #0x2c]" "\n"
+    "ldr r5, [sp, #0x28]" "\n"
+    "ldr r4, [sp, #0x24]" "\n"
+    "ldr lr, [sp, #0x20]" "\n"
+    "add sp, sp, #0x3c" "\n"
+    "bx lr" "\n"
+);
+
+asm volatile (
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+".thumb" "\n"
+".thumb_func " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+    "ldr r6, [sp, #0x2c]" "\n"
+    "ldr r5, [sp, #0x28]" "\n"
+    "ldr r4, [sp, #0x24]" "\n"
+    "ldr lr, [sp, #0x20]" "\n"
+    "add sp, sp, #0x3c" "\n"
+    "bx lr" "\n"
+);
+
+#elif COMPILER(MSVC)
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#error "JIT_STUB_ARGUMENT_VA_LIST configuration not supported on MSVC."
+#endif
+
+// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
+// need to change the assembly trampolines below to match.
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) % 16 == 0x0, JITStackFrame_maintains_16byte_stack_alignment);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x3c, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x58, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x50, JITStackFrame_code_offset_matches_ctiTrampoline);
+
+extern "C" {
+
+    __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*)
+    {
+        __asm {
+            push ebp;
+            mov ebp, esp;
+            push esi;
+            push edi;
+            push ebx;
+            sub esp, 0x3c;
+            mov esi, 512;
+            mov ecx, esp;
+            mov edi, [esp + 0x58];
+            call [esp + 0x50];
+            add esp, 0x3c;
+            pop ebx;
+            pop edi;
+            pop esi;
+            pop ebp;
+            ret;
+        }
+    }
+
+    __declspec(naked) void ctiVMThrowTrampoline()
+    {
+        __asm {
+            mov ecx, esp;
+            call cti_vm_throw;
+            add esp, 0x3c;
+            pop ebx;
+            pop edi;
+            pop esi;
+            pop ebp;
+            ret;
+        }
+    }
+
+    __declspec(naked) void ctiOpThrowNotCaught()
+    {
+        __asm {
+            add esp, 0x3c;
+            pop ebx;
+            pop edi;
+            pop esi;
+            pop ebp;
+            ret;
+        }
+    }
+}
+
+#endif // COMPILER(GCC) && PLATFORM(X86)
+
+#else // USE(JSVALUE32_64)
+
+#if COMPILER(GCC) && PLATFORM(X86)
+
+// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
+// need to change the assembly trampolines below to match.
+COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x38, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x30, JITStackFrame_code_offset_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x1c, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+    "pushl %ebp" "\n"
+    "movl %esp, %ebp" "\n"
+    "pushl %esi" "\n"
+    "pushl %edi" "\n"
+    "pushl %ebx" "\n"
+    "subl $0x1c, %esp" "\n"
+    "movl $512, %esi" "\n"
+    "movl 0x38(%esp), %edi" "\n"
+    "call *0x30(%esp)" "\n"
+    "addl $0x1c, %esp" "\n"
+    "popl %ebx" "\n"
+    "popl %edi" "\n"
+    "popl %esi" "\n"
+    "popl %ebp" "\n"
+    "ret" "\n"
+);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+#if !USE(JIT_STUB_ARGUMENT_VA_LIST)
+    "movl %esp, %ecx" "\n"
+#endif
+    "call " SYMBOL_STRING(cti_vm_throw) "\n"
+    "addl $0x1c, %esp" "\n"
+    "popl %ebx" "\n"
+    "popl %edi" "\n"
+    "popl %esi" "\n"
+    "popl %ebp" "\n"
+    "ret" "\n"
+);
+    
+asm volatile (
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+    "addl $0x1c, %esp" "\n"
+    "popl %ebx" "\n"
+    "popl %edi" "\n"
+    "popl %esi" "\n"
+    "popl %ebp" "\n"
+    "ret" "\n"
+);
+    
+#elif COMPILER(GCC) && PLATFORM(X86_64)
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#error "JIT_STUB_ARGUMENT_VA_LIST not supported on x86-64."
+#endif
+
+// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
+// need to change the assembly trampolines below to match.
+COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x90, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x80, JITStackFrame_code_offset_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, savedRBX) == 0x48, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+    "pushq %rbp" "\n"
+    "movq %rsp, %rbp" "\n"
+    "pushq %r12" "\n"
+    "pushq %r13" "\n"
+    "pushq %r14" "\n"
+    "pushq %r15" "\n"
+    "pushq %rbx" "\n"
+    "subq $0x48, %rsp" "\n"
+    "movq $512, %r12" "\n"
+    "movq $0xFFFF000000000000, %r14" "\n"
+    "movq $0xFFFF000000000002, %r15" "\n"
+    "movq 0x90(%rsp), %r13" "\n"
+    "call *0x80(%rsp)" "\n"
+    "addq $0x48, %rsp" "\n"
+    "popq %rbx" "\n"
+    "popq %r15" "\n"
+    "popq %r14" "\n"
+    "popq %r13" "\n"
+    "popq %r12" "\n"
+    "popq %rbp" "\n"
+    "ret" "\n"
+);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+    "movq %rsp, %rdi" "\n"
+    "call " SYMBOL_STRING(cti_vm_throw) "\n"
+    "addq $0x48, %rsp" "\n"
+    "popq %rbx" "\n"
+    "popq %r15" "\n"
+    "popq %r14" "\n"
+    "popq %r13" "\n"
+    "popq %r12" "\n"
+    "popq %rbp" "\n"
+    "ret" "\n"
+);
+
+asm volatile (
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+    "addq $0x48, %rsp" "\n"
+    "popq %rbx" "\n"
+    "popq %r15" "\n"
+    "popq %r14" "\n"
+    "popq %r13" "\n"
+    "popq %r12" "\n"
+    "popq %rbp" "\n"
+    "ret" "\n"
+);
+
+#elif COMPILER(GCC) && PLATFORM_ARM_ARCH(7)
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7."
+#endif
+
+asm volatile (
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+".thumb" "\n"
+".thumb_func " SYMBOL_STRING(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+    "sub sp, sp, #0x3c" "\n"
+    "str lr, [sp, #0x20]" "\n"
+    "str r4, [sp, #0x24]" "\n"
+    "str r5, [sp, #0x28]" "\n"
+    "str r6, [sp, #0x2c]" "\n"
+    "str r1, [sp, #0x30]" "\n"
+    "str r2, [sp, #0x34]" "\n"
+    "str r3, [sp, #0x38]" "\n"
+    "cpy r5, r2" "\n"
+    "mov r6, #512" "\n"
+    "blx r0" "\n"
+    "ldr r6, [sp, #0x2c]" "\n"
+    "ldr r5, [sp, #0x28]" "\n"
+    "ldr r4, [sp, #0x24]" "\n"
+    "ldr lr, [sp, #0x20]" "\n"
+    "add sp, sp, #0x3c" "\n"
+    "bx lr" "\n"
+);
+
+asm volatile (
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+".thumb" "\n"
+".thumb_func " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+    "cpy r0, sp" "\n"
+    "bl " SYMBOL_STRING(cti_vm_throw) "\n"
+    "ldr r6, [sp, #0x2c]" "\n"
+    "ldr r5, [sp, #0x28]" "\n"
+    "ldr r4, [sp, #0x24]" "\n"
+    "ldr lr, [sp, #0x20]" "\n"
+    "add sp, sp, #0x3c" "\n"
+    "bx lr" "\n"
+);
+
+asm volatile (
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+".thumb" "\n"
+".thumb_func " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+    "ldr r6, [sp, #0x2c]" "\n"
+    "ldr r5, [sp, #0x28]" "\n"
+    "ldr r4, [sp, #0x24]" "\n"
+    "ldr lr, [sp, #0x20]" "\n"
+    "add sp, sp, #0x3c" "\n"
+    "bx lr" "\n"
+);
+
+#elif COMPILER(MSVC)
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#error "JIT_STUB_ARGUMENT_VA_LIST configuration not supported on MSVC."
+#endif
+
+// These ASSERTs remind you that, if you change the layout of JITStackFrame, you
+// need to change the assembly trampolines below to match.
+COMPILE_ASSERT(offsetof(struct JITStackFrame, callFrame) == 0x38, JITStackFrame_callFrame_offset_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, code) == 0x30, JITStackFrame_code_offset_matches_ctiTrampoline);
+COMPILE_ASSERT(offsetof(struct JITStackFrame, savedEBX) == 0x1c, JITStackFrame_stub_argument_space_matches_ctiTrampoline);
+
+extern "C" {
+
+    __declspec(naked) EncodedJSValue ctiTrampoline(void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*)
+    {
+        __asm {
+            push ebp;
+            mov ebp, esp;
+            push esi;
+            push edi;
+            push ebx;
+            sub esp, 0x1c;
+            mov esi, 512;
+            mov ecx, esp;
+            mov edi, [esp + 0x38];
+            call [esp + 0x30];
+            add esp, 0x1c;
+            pop ebx;
+            pop edi;
+            pop esi;
+            pop ebp;
+            ret;
+        }
+    }
+
+    __declspec(naked) void ctiVMThrowTrampoline()
+    {
+        __asm {
+            mov ecx, esp;
+            call cti_vm_throw;
+            add esp, 0x1c;
+            pop ebx;
+            pop edi;
+            pop esi;
+            pop ebp;
+            ret;
+        }
+    }
+     
+     __declspec(naked) void ctiOpThrowNotCaught()
+     {
+         __asm {
+             add esp, 0x1c;
+             pop ebx;
+             pop edi;
+             pop esi;
+             pop ebp;
+             ret;
+         }
+     }
+}
+
+#endif // COMPILER(GCC) && PLATFORM(X86)
+
+#endif // USE(JSVALUE32_64)
+
+#if ENABLE(OPCODE_SAMPLING)
+    #define CTI_SAMPLER stackFrame.globalData->interpreter->sampler()
+#else
+    #define CTI_SAMPLER 0
+#endif
+
+JITThunks::JITThunks(JSGlobalData* globalData)
+{
+    JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallPreLink, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk);
+
+#if PLATFORM_ARM_ARCH(7)
+    // Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types),
+    // and the OBJECT_OFFSETOF macro does not appear constantish enough for it to be happy with its use in COMPILE_ASSERT
+    // macros.
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == 0x20);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR4) == 0x24);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR5) == 0x28);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR6) == 0x2c);
+
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == 0x30);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == 0x34);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == 0x38);
+    // The fifth argument is the first item already on the stack.
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == 0x3c);
+
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == 0x1C);
+#endif
+}
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot)
+{
+    // The interpreter checks for recursion here; I do not believe this can occur in CTI.
+
+    if (!baseValue.isCell())
+        return;
+
+    // Uncacheable: give up.
+    if (!slot.isCacheable()) {
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
+        return;
+    }
+    
+    JSCell* baseCell = asCell(baseValue);
+    Structure* structure = baseCell->structure();
+
+    if (structure->isUncacheableDictionary()) {
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
+        return;
+    }
+
+    // If baseCell != base, then baseCell must be a proxy for another object.
+    if (baseCell != slot.base()) {
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
+        return;
+    }
+
+    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
+
+    // Cache hit: Specialize instruction and ref Structures.
+
+    // Structure transition, cache transition info
+    if (slot.type() == PutPropertySlot::NewProperty) {
+        StructureChain* prototypeChain = structure->prototypeChain(callFrame);
+        if (!prototypeChain->isCacheable() || structure->isDictionary()) {
+            ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
+            return;
+        }
+        stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain);
+        JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress);
+        return;
+    }
+    
+    stubInfo->initPutByIdReplace(structure);
+
+    JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
+}
+
+NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot)
+{
+    // FIXME: Write a test that proves we need to check for recursion here just
+    // like the interpreter does, then add a check for recursion.
+
+    // FIXME: Cache property access for immediates.
+    if (!baseValue.isCell()) {
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
+        return;
+    }
+    
+    JSGlobalData* globalData = &callFrame->globalData();
+
+    if (isJSArray(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
+        JIT::compilePatchGetArrayLength(callFrame->scopeChain()->globalData, codeBlock, returnAddress);
+        return;
+    }
+    
+    if (isJSString(globalData, baseValue) && propertyName == callFrame->propertyNames().length) {
+        // The tradeoff of compiling an patched inline string length access routine does not seem
+        // to pay off, so we currently only do this for arrays.
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, globalData->jitStubs.ctiStringLengthTrampoline());
+        return;
+    }
+
+    // Uncacheable: give up.
+    if (!slot.isCacheable()) {
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
+        return;
+    }
+
+    JSCell* baseCell = asCell(baseValue);
+    Structure* structure = baseCell->structure();
+
+    if (structure->isUncacheableDictionary()) {
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
+        return;
+    }
+
+    // In the interpreter the last structure is trapped here; in CTI we use the
+    // *_second method to achieve a similar (but not quite the same) effect.
+
+    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(returnAddress);
+
+    // Cache hit: Specialize instruction and ref Structures.
+
+    if (slot.slotBase() == baseValue) {
+        // set this up, so derefStructures can do it's job.
+        stubInfo->initGetByIdSelf(structure);
+
+        JIT::patchGetByIdSelf(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
+        return;
+    }
+
+    if (structure->isDictionary()) {
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
+        return;
+    }
+
+    if (slot.slotBase() == structure->prototypeForLookup(callFrame)) {
+        ASSERT(slot.slotBase().isObject());
+
+        JSObject* slotBaseObject = asObject(slot.slotBase());
+        size_t offset = slot.cachedOffset();
+        
+        // Since we're accessing a prototype in a loop, it's a good bet that it
+        // should not be treated as a dictionary.
+        if (slotBaseObject->structure()->isDictionary()) {
+            slotBaseObject->flattenDictionaryObject();
+            offset = slotBaseObject->structure()->get(propertyName);
+        }
+        
+        stubInfo->initGetByIdProto(structure, slotBaseObject->structure());
+
+        JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), offset, returnAddress);
+        return;
+    }
+
+    size_t offset = slot.cachedOffset();
+    size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset);
+    if (!count) {
+        stubInfo->opcodeID = op_get_by_id_generic;
+        return;
+    }
+
+    StructureChain* prototypeChain = structure->prototypeChain(callFrame);
+    if (!prototypeChain->isCacheable()) {
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
+        return;
+    }
+    stubInfo->initGetByIdChain(structure, prototypeChain);
+    JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, offset, returnAddress);
+}
+
+#endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#define SETUP_VA_LISTL_ARGS va_list vl_args; va_start(vl_args, args)
+#else
+#define SETUP_VA_LISTL_ARGS
+#endif
+
+#ifndef NDEBUG
+
+extern "C" {
+
+static void jscGeneratedNativeCode() 
+{
+    // When executing a JIT stub function (which might do an allocation), we hack the return address
+    // to pretend to be executing this function, to keep stack logging tools from blowing out
+    // memory.
+}
+
+}
+
+struct StackHack {
+    ALWAYS_INLINE StackHack(JITStackFrame& stackFrame) 
+        : stackFrame(stackFrame)
+        , savedReturnAddress(*stackFrame.returnAddressSlot())
+    {
+        *stackFrame.returnAddressSlot() = ReturnAddressPtr(FunctionPtr(jscGeneratedNativeCode));
+    }
+
+    ALWAYS_INLINE ~StackHack() 
+    { 
+        *stackFrame.returnAddressSlot() = savedReturnAddress;
+    }
+
+    JITStackFrame& stackFrame;
+    ReturnAddressPtr savedReturnAddress;
+};
+
+#define STUB_INIT_STACK_FRAME(stackFrame) SETUP_VA_LISTL_ARGS; JITStackFrame& stackFrame = *reinterpret_cast<JITStackFrame*>(STUB_ARGS); StackHack stackHack(stackFrame)
+#define STUB_SET_RETURN_ADDRESS(returnAddress) stackHack.savedReturnAddress = ReturnAddressPtr(returnAddress)
+#define STUB_RETURN_ADDRESS stackHack.savedReturnAddress
+
+#else
+
+#define STUB_INIT_STACK_FRAME(stackFrame) SETUP_VA_LISTL_ARGS; JITStackFrame& stackFrame = *reinterpret_cast<JITStackFrame*>(STUB_ARGS)
+#define STUB_SET_RETURN_ADDRESS(returnAddress) *stackFrame.returnAddressSlot() = ReturnAddressPtr(returnAddress)
+#define STUB_RETURN_ADDRESS *stackFrame.returnAddressSlot()
+
+#endif
+
+// The reason this is not inlined is to avoid having to do a PIC branch
+// to get the address of the ctiVMThrowTrampoline function. It's also
+// good to keep the code size down by leaving as much of the exception
+// handling code out of line as possible.
+static NEVER_INLINE void returnToThrowTrampoline(JSGlobalData* globalData, ReturnAddressPtr exceptionLocation, ReturnAddressPtr& returnAddressSlot)
+{
+    ASSERT(globalData->exception);
+    globalData->exceptionLocation = exceptionLocation;
+    returnAddressSlot = ReturnAddressPtr(FunctionPtr(ctiVMThrowTrampoline));
+}
+
+static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalData* globalData, ReturnAddressPtr exceptionLocation, ReturnAddressPtr& returnAddressSlot)
+{
+    globalData->exception = createStackOverflowError(callFrame);
+    returnToThrowTrampoline(globalData, exceptionLocation, returnAddressSlot);
+}
+
+#define VM_THROW_EXCEPTION() \
+    do { \
+        VM_THROW_EXCEPTION_AT_END(); \
+        return 0; \
+    } while (0)
+#define VM_THROW_EXCEPTION_AT_END() \
+    returnToThrowTrampoline(stackFrame.globalData, STUB_RETURN_ADDRESS, STUB_RETURN_ADDRESS)
+
+#define CHECK_FOR_EXCEPTION() \
+    do { \
+        if (UNLIKELY(stackFrame.globalData->exception)) \
+            VM_THROW_EXCEPTION(); \
+    } while (0)
+#define CHECK_FOR_EXCEPTION_AT_END() \
+    do { \
+        if (UNLIKELY(stackFrame.globalData->exception)) \
+            VM_THROW_EXCEPTION_AT_END(); \
+    } while (0)
+#define CHECK_FOR_EXCEPTION_VOID() \
+    do { \
+        if (UNLIKELY(stackFrame.globalData->exception)) { \
+            VM_THROW_EXCEPTION_AT_END(); \
+            return; \
+        } \
+    } while (0)
+
+#if PLATFORM_ARM_ARCH(7)
+
+#define DEFINE_STUB_FUNCTION(rtype, op) \
+    extern "C" { \
+        rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
+    }; \
+    asm volatile ( \
+        ".text" "\n" \
+        ".align 2" "\n" \
+        ".globl " SYMBOL_STRING(cti_##op) "\n" \
+        ".thumb" "\n" \
+        ".thumb_func " SYMBOL_STRING(cti_##op) "\n" \
+        SYMBOL_STRING(cti_##op) ":" "\n" \
+        "str lr, [sp, #0x1c]" "\n" \
+        "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \
+        "ldr lr, [sp, #0x1c]" "\n" \
+        "bx lr" "\n" \
+        ); \
+    rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \
+
+#else
+#define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION)
+#endif
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue v1 = stackFrame.args[0].jsValue();
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    JSObject* result = v1.toThisObject(callFrame);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(void, op_end)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    ScopeChainNode* scopeChain = stackFrame.callFrame->scopeChain();
+    ASSERT(scopeChain->refCount > 1);
+    scopeChain->deref();
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_add)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue v1 = stackFrame.args[0].jsValue();
+    JSValue v2 = stackFrame.args[1].jsValue();
+
+    double left;
+    double right = 0.0;
+
+    bool rightIsNumber = v2.getNumber(right);
+    if (rightIsNumber && v1.getNumber(left))
+        return JSValue::encode(jsNumber(stackFrame.globalData, left + right));
+    
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    bool leftIsString = v1.isString();
+    if (leftIsString && v2.isString()) {
+        RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
+        if (UNLIKELY(!value)) {
+            throwOutOfMemoryError(callFrame);
+            VM_THROW_EXCEPTION();
+        }
+
+        return JSValue::encode(jsString(stackFrame.globalData, value.release()));
+    }
+
+    if (rightIsNumber & leftIsString) {
+        RefPtr<UString::Rep> value = v2.isInt32() ?
+            concatenate(asString(v1)->value().rep(), v2.asInt32()) :
+            concatenate(asString(v1)->value().rep(), right);
+
+        if (UNLIKELY(!value)) {
+            throwOutOfMemoryError(callFrame);
+            VM_THROW_EXCEPTION();
+        }
+        return JSValue::encode(jsString(stackFrame.globalData, value.release()));
+    }
+
+    // All other cases are pretty uncommon
+    JSValue result = jsAddSlowCase(callFrame, v1, v2);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_inc)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue v = stackFrame.args[0].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, v.toNumber(callFrame) + 1);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(int, timeout_check)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    
+    JSGlobalData* globalData = stackFrame.globalData;
+    TimeoutChecker& timeoutChecker = globalData->timeoutChecker;
+
+    if (timeoutChecker.didTimeOut(stackFrame.callFrame)) {
+        globalData->exception = createInterruptedExecutionException(globalData);
+        VM_THROW_EXCEPTION_AT_END();
+    }
+    
+    return timeoutChecker.ticksUntilNextCheck();
+}
+
+DEFINE_STUB_FUNCTION(void, register_file_check)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    if (LIKELY(stackFrame.registerFile->grow(&stackFrame.callFrame->registers()[stackFrame.callFrame->codeBlock()->m_numCalleeRegisters])))
+        return;
+
+    // Rewind to the previous call frame because op_call already optimistically
+    // moved the call frame forward.
+    CallFrame* oldCallFrame = stackFrame.callFrame->callerFrame();
+    stackFrame.callFrame = oldCallFrame;
+    throwStackOverflowError(oldCallFrame, stackFrame.globalData, ReturnAddressPtr(oldCallFrame->returnPC()), STUB_RETURN_ADDRESS);
+}
+
+DEFINE_STUB_FUNCTION(int, op_loop_if_less)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    bool result = jsLess(callFrame, src1, src2);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return result;
+}
+
+DEFINE_STUB_FUNCTION(int, op_loop_if_lesseq)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    bool result = jsLessEq(callFrame, src1, src2);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return result;
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_new_object)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return constructEmptyObject(stackFrame.callFrame);
+}
+
+DEFINE_STUB_FUNCTION(void, op_put_by_id_generic)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    PutPropertySlot slot;
+    stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
+    CHECK_FOR_EXCEPTION_AT_END();
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_generic)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(callFrame, ident, slot);
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+DEFINE_STUB_FUNCTION(void, op_put_by_id)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+
+    PutPropertySlot slot;
+    stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
+
+    ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_id_second));
+
+    CHECK_FOR_EXCEPTION_AT_END();
+}
+
+DEFINE_STUB_FUNCTION(void, op_put_by_id_second)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    PutPropertySlot slot;
+    stackFrame.args[0].jsValue().put(stackFrame.callFrame, stackFrame.args[1].identifier(), stackFrame.args[2].jsValue(), slot);
+    JITThunks::tryCachePutByID(stackFrame.callFrame, stackFrame.callFrame->codeBlock(), STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot);
+    CHECK_FOR_EXCEPTION_AT_END();
+}
+
+DEFINE_STUB_FUNCTION(void, op_put_by_id_fail)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+
+    PutPropertySlot slot;
+    stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
+
+    CHECK_FOR_EXCEPTION_AT_END();
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    int32_t oldSize = stackFrame.args[3].int32();
+    int32_t newSize = stackFrame.args[4].int32();
+
+    ASSERT(baseValue.isObject());
+    JSObject* base = asObject(baseValue);
+    base->allocatePropertyStorage(oldSize, newSize);
+
+    return base;
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(callFrame, ident, slot);
+
+    ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_second));
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(callFrame, ident, slot);
+
+    ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_method_check_second));
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check_second)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(callFrame, ident, slot);
+
+    CHECK_FOR_EXCEPTION();
+
+    // If we successfully got something, then the base from which it is being accessed must
+    // be an object.  (Assertion to ensure asObject() call below is safe, which comes after
+    // an isCacheable() chceck.
+    ASSERT(!slot.isCacheable() || slot.slotBase().isObject());
+
+    // Check that:
+    //   * We're dealing with a JSCell,
+    //   * the property is cachable,
+    //   * it's not a dictionary
+    //   * there is a function cached.
+    Structure* structure;
+    JSCell* specific;
+    JSObject* slotBaseObject;
+    if (baseValue.isCell()
+        && slot.isCacheable()
+        && !(structure = asCell(baseValue)->structure())->isUncacheableDictionary()
+        && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
+        && specific
+        ) {
+
+        JSFunction* callee = (JSFunction*)specific;
+
+        // Since we're accessing a prototype in a loop, it's a good bet that it
+        // should not be treated as a dictionary.
+        if (slotBaseObject->structure()->isDictionary())
+            slotBaseObject->flattenDictionaryObject();
+
+        // The result fetched should always be the callee!
+        ASSERT(result == JSValue(callee));
+        MethodCallLinkInfo& methodCallLinkInfo = callFrame->codeBlock()->getMethodCallLinkInfo(STUB_RETURN_ADDRESS);
+
+        // Check to see if the function is on the object's prototype.  Patch up the code to optimize.
+        if (slot.slotBase() == structure->prototypeForLookup(callFrame))
+            JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, slotBaseObject);
+        // Check to see if the function is on the object itself.
+        // Since we generate the method-check to check both the structure and a prototype-structure (since this
+        // is the common case) we have a problem - we need to patch the prototype structure check to do something
+        // useful.  We could try to nop it out altogether, but that's a little messy, so lets do something simpler
+        // for now.  For now it performs a check on a special object on the global object only used for this
+        // purpose.  The object is in no way exposed, and as such the check will always pass.
+        else if (slot.slotBase() == baseValue)
+            JIT::patchMethodCallProto(callFrame->codeBlock(), methodCallLinkInfo, callee, structure, callFrame->scopeChain()->globalObject()->methodCallDummy());
+
+        // For now let any other case be cached as a normal get_by_id.
+    }
+
+    // Revert the get_by_id op back to being a regular get_by_id - allow it to cache like normal, if it needs to.
+    ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id));
+
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_second)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(callFrame, ident, slot);
+
+    JITThunks::tryCacheGetByID(callFrame, callFrame->codeBlock(), STUB_RETURN_ADDRESS, baseValue, ident, slot);
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(callFrame, ident, slot);
+
+    CHECK_FOR_EXCEPTION();
+
+    if (baseValue.isCell()
+        && slot.isCacheable()
+        && !asCell(baseValue)->structure()->isUncacheableDictionary()
+        && slot.slotBase() == baseValue) {
+
+        CodeBlock* codeBlock = callFrame->codeBlock();
+        StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+
+        ASSERT(slot.slotBase().isObject());
+
+        PolymorphicAccessStructureList* polymorphicStructureList;
+        int listIndex = 1;
+
+        if (stubInfo->opcodeID == op_get_by_id_self) {
+            ASSERT(!stubInfo->stubRoutine);
+            polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure);
+            stubInfo->initGetByIdSelfList(polymorphicStructureList, 2);
+        } else {
+            polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
+            listIndex = stubInfo->u.getByIdSelfList.listSize;
+            stubInfo->u.getByIdSelfList.listSize++;
+        }
+
+        JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), slot.cachedOffset());
+
+        if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+            ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
+    } else
+        ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
+    return JSValue::encode(result);
+}
+
+static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(StructureStubInfo* stubInfo, int& listIndex)
+{
+    PolymorphicAccessStructureList* prototypeStructureList = 0;
+    listIndex = 1;
+
+    switch (stubInfo->opcodeID) {
+    case op_get_by_id_proto:
+        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure);
+        stubInfo->stubRoutine = CodeLocationLabel();
+        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
+        break;
+    case op_get_by_id_chain:
+        prototypeStructureList = new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain);
+        stubInfo->stubRoutine = CodeLocationLabel();
+        stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
+        break;
+    case op_get_by_id_proto_list:
+        prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
+        listIndex = stubInfo->u.getByIdProtoList.listSize;
+        stubInfo->u.getByIdProtoList.listSize++;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    
+    ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE);
+    return prototypeStructureList;
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    const Identifier& propertyName = stackFrame.args[1].identifier();
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(callFrame, propertyName, slot);
+
+    CHECK_FOR_EXCEPTION();
+
+    if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isUncacheableDictionary()) {
+        ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
+        return JSValue::encode(result);
+    }
+
+    Structure* structure = asCell(baseValue)->structure();
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+
+    ASSERT(slot.slotBase().isObject());
+    JSObject* slotBaseObject = asObject(slot.slotBase());
+    
+    size_t offset = slot.cachedOffset();
+
+    if (slot.slotBase() == baseValue)
+        ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
+    else if (slot.slotBase() == asCell(baseValue)->structure()->prototypeForLookup(callFrame)) {
+        // Since we're accessing a prototype in a loop, it's a good bet that it
+        // should not be treated as a dictionary.
+        if (slotBaseObject->structure()->isDictionary()) {
+            slotBaseObject->flattenDictionaryObject();
+            offset = slotBaseObject->structure()->get(propertyName);
+        }
+
+        int listIndex;
+        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+
+        JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), offset);
+
+        if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+            ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
+    } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) {
+        StructureChain* protoChain = structure->prototypeChain(callFrame);
+        if (!protoChain->isCacheable()) {
+            ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
+            return JSValue::encode(result);
+        }
+        
+        int listIndex;
+        PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+        JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, offset);
+
+        if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
+            ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
+    } else
+        ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
+
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list_full)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_fail)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_array_fail)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_string_fail)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    PropertySlot slot(baseValue);
+    JSValue result = baseValue.get(stackFrame.callFrame, stackFrame.args[1].identifier(), slot);
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+#endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue value = stackFrame.args[0].jsValue();
+    JSValue baseVal = stackFrame.args[1].jsValue();
+    JSValue proto = stackFrame.args[2].jsValue();
+
+    // At least one of these checks must have failed to get to the slow case.
+    ASSERT(!value.isCell() || !baseVal.isCell() || !proto.isCell()
+           || !value.isObject() || !baseVal.isObject() || !proto.isObject() 
+           || (asObject(baseVal)->structure()->typeInfo().flags() & (ImplementsHasInstance | OverridesHasInstance)) != ImplementsHasInstance);
+
+
+    // ECMA-262 15.3.5.3:
+    // Throw an exception either if baseVal is not an object, or if it does not implement 'HasInstance' (i.e. is a function).
+    TypeInfo typeInfo(UnspecifiedType, 0);
+    if (!baseVal.isObject() || !(typeInfo = asObject(baseVal)->structure()->typeInfo()).implementsHasInstance()) {
+        CallFrame* callFrame = stackFrame.callFrame;
+        CodeBlock* codeBlock = callFrame->codeBlock();
+        unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+        stackFrame.globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal, vPCIndex, codeBlock);
+        VM_THROW_EXCEPTION();
+    }
+    ASSERT(typeInfo.type() != UnspecifiedType);
+
+    if (!typeInfo.overridesHasInstance()) {
+        if (!value.isObject())
+            return JSValue::encode(jsBoolean(false));
+
+        if (!proto.isObject()) {
+            throwError(callFrame, TypeError, "instanceof called on an object with an invalid prototype property.");
+            VM_THROW_EXCEPTION();
+        }
+    }
+
+    JSValue result = jsBoolean(asObject(baseVal)->hasInstance(callFrame, value, proto));
+    CHECK_FOR_EXCEPTION_AT_END();
+
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_id)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    
+    JSObject* baseObj = stackFrame.args[0].jsValue().toObject(callFrame);
+
+    JSValue result = jsBoolean(baseObj->deleteProperty(callFrame, stackFrame.args[1].identifier()));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_mul)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    double left;
+    double right;
+    if (src1.getNumber(left) && src2.getNumber(right))
+        return JSValue::encode(jsNumber(stackFrame.globalData, left * right));
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, src1.toNumber(callFrame) * src2.toNumber(callFrame));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return stackFrame.args[0].funcDeclNode()->makeFunction(stackFrame.callFrame, stackFrame.callFrame->scopeChain());
+}
+
+DEFINE_STUB_FUNCTION(void*, op_call_JSFunction)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+#ifndef NDEBUG
+    CallData callData;
+    ASSERT(stackFrame.args[0].jsValue().getCallData(callData) == CallTypeJS);
+#endif
+
+    JSFunction* function = asFunction(stackFrame.args[0].jsValue());
+    ASSERT(!function->isHostFunction());
+    FunctionBodyNode* body = function->body();
+    ScopeChainNode* callDataScopeChain = function->scope().node();
+    body->jitCode(callDataScopeChain);
+
+    return &(body->generatedBytecode());
+}
+
+DEFINE_STUB_FUNCTION(VoidPtrPair, op_call_arityCheck)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    CodeBlock* newCodeBlock = stackFrame.args[3].codeBlock();
+    ASSERT(newCodeBlock->codeType() != NativeCode);
+    int argCount = stackFrame.args[2].int32();
+
+    ASSERT(argCount != newCodeBlock->m_numParameters);
+
+    CallFrame* oldCallFrame = callFrame->callerFrame();
+
+    if (argCount > newCodeBlock->m_numParameters) {
+        size_t numParameters = newCodeBlock->m_numParameters;
+        Register* r = callFrame->registers() + numParameters;
+
+        Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
+        for (size_t i = 0; i < numParameters; ++i)
+            argv[i + argCount] = argv[i];
+
+        callFrame = CallFrame::create(r);
+        callFrame->setCallerFrame(oldCallFrame);
+    } else {
+        size_t omittedArgCount = newCodeBlock->m_numParameters - argCount;
+        Register* r = callFrame->registers() + omittedArgCount;
+        Register* newEnd = r + newCodeBlock->m_numCalleeRegisters;
+        if (!stackFrame.registerFile->grow(newEnd)) {
+            // Rewind to the previous call frame because op_call already optimistically
+            // moved the call frame forward.
+            stackFrame.callFrame = oldCallFrame;
+            throwStackOverflowError(oldCallFrame, stackFrame.globalData, stackFrame.args[1].returnAddress(), STUB_RETURN_ADDRESS);
+            RETURN_POINTER_PAIR(0, 0);
+        }
+
+        Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
+        for (size_t i = 0; i < omittedArgCount; ++i)
+            argv[i] = jsUndefined();
+
+        callFrame = CallFrame::create(r);
+        callFrame->setCallerFrame(oldCallFrame);
+    }
+
+    RETURN_POINTER_PAIR(newCodeBlock, callFrame);
+}
+
+#if ENABLE(JIT_OPTIMIZE_CALL)
+DEFINE_STUB_FUNCTION(void*, vm_dontLazyLinkCall)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSGlobalData* globalData = stackFrame.globalData;
+    JSFunction* callee = asFunction(stackFrame.args[0].jsValue());
+
+    ctiPatchNearCallByReturnAddress(stackFrame.callFrame->callerFrame()->codeBlock(), stackFrame.args[1].returnAddress(), globalData->jitStubs.ctiVirtualCallLink());
+
+    return callee->body()->generatedJITCode().addressForCall().executableAddress();
+}
+
+DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSFunction* callee = asFunction(stackFrame.args[0].jsValue());
+    JITCode& jitCode = callee->body()->generatedJITCode();
+    
+    CodeBlock* codeBlock = 0;
+    if (!callee->isHostFunction())
+        codeBlock = &callee->body()->bytecode(callee->scope().node());
+    else
+        codeBlock = &callee->body()->generatedBytecode();
+
+    CallLinkInfo* callLinkInfo = &stackFrame.callFrame->callerFrame()->codeBlock()->getCallLinkInfo(stackFrame.args[1].returnAddress());
+    JIT::linkCall(callee, stackFrame.callFrame->callerFrame()->codeBlock(), codeBlock, jitCode, callLinkInfo, stackFrame.args[2].int32(), stackFrame.globalData);
+
+    return jitCode.addressForCall().executableAddress();
+}
+#endif // !ENABLE(JIT_OPTIMIZE_CALL)
+
+DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSActivation* activation = new (stackFrame.globalData) JSActivation(stackFrame.callFrame, static_cast<FunctionBodyNode*>(stackFrame.callFrame->codeBlock()->ownerNode()));
+    stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->copy()->push(activation));
+    return activation;
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue funcVal = stackFrame.args[0].jsValue();
+
+    CallData callData;
+    CallType callType = funcVal.getCallData(callData);
+
+    ASSERT(callType != CallTypeJS);
+
+    if (callType == CallTypeHost) {
+        int registerOffset = stackFrame.args[1].int32();
+        int argCount = stackFrame.args[2].int32();
+        CallFrame* previousCallFrame = stackFrame.callFrame;
+        CallFrame* callFrame = CallFrame::create(previousCallFrame->registers() + registerOffset);
+
+        callFrame->init(0, static_cast<Instruction*>((STUB_RETURN_ADDRESS).value()), previousCallFrame->scopeChain(), previousCallFrame, 0, argCount, 0);
+        stackFrame.callFrame = callFrame;
+
+        Register* argv = stackFrame.callFrame->registers() - RegisterFile::CallFrameHeaderSize - argCount;
+        ArgList argList(argv + 1, argCount - 1);
+
+        JSValue returnValue;
+        {
+            SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
+
+            // FIXME: All host methods should be calling toThisObject, but this is not presently the case.
+            JSValue thisValue = argv[0].jsValue();
+            if (thisValue == jsNull())
+                thisValue = callFrame->globalThisValue();
+
+            returnValue = callData.native.function(callFrame, asObject(funcVal), thisValue, argList);
+        }
+        stackFrame.callFrame = previousCallFrame;
+        CHECK_FOR_EXCEPTION();
+
+        return JSValue::encode(returnValue);
+    }
+
+    ASSERT(callType == CallTypeNone);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+    stackFrame.globalData->exception = createNotAFunctionError(stackFrame.callFrame, funcVal, vPCIndex, codeBlock);
+    VM_THROW_EXCEPTION();
+}
+
+DEFINE_STUB_FUNCTION(void, op_create_arguments)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    Arguments* arguments = new (stackFrame.globalData) Arguments(stackFrame.callFrame);
+    stackFrame.callFrame->setCalleeArguments(arguments);
+    stackFrame.callFrame[RegisterFile::ArgumentsRegister] = JSValue(arguments);
+}
+
+DEFINE_STUB_FUNCTION(void, op_create_arguments_no_params)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    Arguments* arguments = new (stackFrame.globalData) Arguments(stackFrame.callFrame, Arguments::NoParameters);
+    stackFrame.callFrame->setCalleeArguments(arguments);
+    stackFrame.callFrame[RegisterFile::ArgumentsRegister] = JSValue(arguments);
+}
+
+DEFINE_STUB_FUNCTION(void, op_tear_off_activation)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain());
+    asActivation(stackFrame.args[0].jsValue())->copyRegisters(stackFrame.callFrame->optionalCalleeArguments());
+}
+
+DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    ASSERT(stackFrame.callFrame->codeBlock()->usesArguments() && !stackFrame.callFrame->codeBlock()->needsFullScopeChain());
+    if (stackFrame.callFrame->optionalCalleeArguments())
+        stackFrame.callFrame->optionalCalleeArguments()->copyRegisters();
+}
+
+DEFINE_STUB_FUNCTION(void, op_profile_will_call)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    ASSERT(*stackFrame.enabledProfilerReference);
+    (*stackFrame.enabledProfilerReference)->willExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
+}
+
+DEFINE_STUB_FUNCTION(void, op_profile_did_call)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    ASSERT(*stackFrame.enabledProfilerReference);
+    (*stackFrame.enabledProfilerReference)->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
+}
+
+DEFINE_STUB_FUNCTION(void, op_ret_scopeChain)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    ASSERT(stackFrame.callFrame->codeBlock()->needsFullScopeChain());
+    stackFrame.callFrame->scopeChain()->deref();
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_new_array)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    ArgList argList(&stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32());
+    return constructArray(stackFrame.callFrame, argList);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    ScopeChainNode* scopeChain = callFrame->scopeChain();
+
+    ScopeChainIterator iter = scopeChain->begin();
+    ScopeChainIterator end = scopeChain->end();
+    ASSERT(iter != end);
+
+    Identifier& ident = stackFrame.args[0].identifier();
+    do {
+        JSObject* o = *iter;
+        PropertySlot slot(o);
+        if (o->getPropertySlot(callFrame, ident, slot)) {
+            JSValue result = slot.getValue(callFrame, ident);
+            CHECK_FOR_EXCEPTION_AT_END();
+            return JSValue::encode(result);
+        }
+    } while (++iter != end);
+
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+    stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
+    VM_THROW_EXCEPTION();
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_construct_JSConstruct)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSFunction* constructor = asFunction(stackFrame.args[0].jsValue());
+    if (constructor->isHostFunction()) {
+        CallFrame* callFrame = stackFrame.callFrame;
+        CodeBlock* codeBlock = callFrame->codeBlock();
+        unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+        stackFrame.globalData->exception = createNotAConstructorError(callFrame, constructor, vPCIndex, codeBlock);
+        VM_THROW_EXCEPTION();
+    }
+
+#ifndef NDEBUG
+    ConstructData constructData;
+    ASSERT(constructor->getConstructData(constructData) == ConstructTypeJS);
+#endif
+
+    Structure* structure;
+    if (stackFrame.args[3].jsValue().isObject())
+        structure = asObject(stackFrame.args[3].jsValue())->inheritorID();
+    else
+        structure = constructor->scope().node()->globalObject()->emptyObjectStructure();
+    return new (stackFrame.globalData) JSObject(structure);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    JSValue constrVal = stackFrame.args[0].jsValue();
+    int argCount = stackFrame.args[2].int32();
+    int thisRegister = stackFrame.args[4].int32();
+
+    ConstructData constructData;
+    ConstructType constructType = constrVal.getConstructData(constructData);
+
+    if (constructType == ConstructTypeHost) {
+        ArgList argList(callFrame->registers() + thisRegister + 1, argCount - 1);
+
+        JSValue returnValue;
+        {
+            SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
+            returnValue = constructData.native.function(callFrame, asObject(constrVal), argList);
+        }
+        CHECK_FOR_EXCEPTION();
+
+        return JSValue::encode(returnValue);
+    }
+
+    ASSERT(constructType == ConstructTypeNone);
+
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+    stackFrame.globalData->exception = createNotAConstructorError(callFrame, constrVal, vPCIndex, codeBlock);
+    VM_THROW_EXCEPTION();
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSGlobalData* globalData = stackFrame.globalData;
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    JSValue subscript = stackFrame.args[1].jsValue();
+
+    JSValue result;
+
+    if (LIKELY(subscript.isUInt32())) {
+        uint32_t i = subscript.asUInt32();
+        if (isJSArray(globalData, baseValue)) {
+            JSArray* jsArray = asArray(baseValue);
+            if (jsArray->canGetIndex(i))
+                result = jsArray->getIndex(i);
+            else
+                result = jsArray->JSArray::get(callFrame, i);
+        } else if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) {
+            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+            ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
+            result = asString(baseValue)->getIndex(stackFrame.globalData, i);
+        } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+            ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_byte_array));
+            return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i));
+        } else
+            result = baseValue.get(callFrame, i);
+    } else {
+        Identifier property(callFrame, subscript.toString(callFrame));
+        result = baseValue.get(callFrame, property);
+    }
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+    
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSGlobalData* globalData = stackFrame.globalData;
+    
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    JSValue subscript = stackFrame.args[1].jsValue();
+    
+    JSValue result;
+    
+    if (LIKELY(subscript.isUInt32())) {
+        uint32_t i = subscript.asUInt32();
+        if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i))
+            result = asString(baseValue)->getIndex(stackFrame.globalData, i);
+        else {
+            result = baseValue.get(callFrame, i);
+            if (!isJSString(globalData, baseValue))
+                ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
+        }
+    } else {
+        Identifier property(callFrame, subscript.toString(callFrame));
+        result = baseValue.get(callFrame, property);
+    }
+    
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+    
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_byte_array)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSGlobalData* globalData = stackFrame.globalData;
+    
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    JSValue subscript = stackFrame.args[1].jsValue();
+    
+    JSValue result;
+
+    if (LIKELY(subscript.isUInt32())) {
+        uint32_t i = subscript.asUInt32();
+        if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+            return JSValue::encode(asByteArray(baseValue)->getIndex(callFrame, i));
+        }
+
+        result = baseValue.get(callFrame, i);
+        if (!isJSByteArray(globalData, baseValue))
+            ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
+    } else {
+        Identifier property(callFrame, subscript.toString(callFrame));
+        result = baseValue.get(callFrame, property);
+    }
+    
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_sub)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    double left;
+    double right;
+    if (src1.getNumber(left) && src2.getNumber(right))
+        return JSValue::encode(jsNumber(stackFrame.globalData, left - right));
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, src1.toNumber(callFrame) - src2.toNumber(callFrame));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(void, op_put_by_val)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSGlobalData* globalData = stackFrame.globalData;
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    JSValue subscript = stackFrame.args[1].jsValue();
+    JSValue value = stackFrame.args[2].jsValue();
+
+    if (LIKELY(subscript.isUInt32())) {
+        uint32_t i = subscript.asUInt32();
+        if (isJSArray(globalData, baseValue)) {
+            JSArray* jsArray = asArray(baseValue);
+            if (jsArray->canSetIndex(i))
+                jsArray->setIndex(i, value);
+            else
+                jsArray->JSArray::put(callFrame, i, value);
+        } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+            JSByteArray* jsByteArray = asByteArray(baseValue);
+            ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val_byte_array));
+            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+            if (value.isInt32()) {
+                jsByteArray->setIndex(i, value.asInt32());
+                return;
+            } else {
+                double dValue = 0;
+                if (value.getNumber(dValue)) {
+                    jsByteArray->setIndex(i, dValue);
+                    return;
+                }
+            }
+
+            baseValue.put(callFrame, i, value);
+        } else
+            baseValue.put(callFrame, i, value);
+    } else {
+        Identifier property(callFrame, subscript.toString(callFrame));
+        if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
+            PutPropertySlot slot;
+            baseValue.put(callFrame, property, value, slot);
+        }
+    }
+
+    CHECK_FOR_EXCEPTION_AT_END();
+}
+
+DEFINE_STUB_FUNCTION(void, op_put_by_val_array)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    int i = stackFrame.args[1].int32();
+    JSValue value = stackFrame.args[2].jsValue();
+
+    ASSERT(isJSArray(stackFrame.globalData, baseValue));
+
+    if (LIKELY(i >= 0))
+        asArray(baseValue)->JSArray::put(callFrame, i, value);
+    else {
+        Identifier property(callFrame, UString::from(i));
+        PutPropertySlot slot;
+        baseValue.put(callFrame, property, value, slot);
+    }
+
+    CHECK_FOR_EXCEPTION_AT_END();
+}
+
+DEFINE_STUB_FUNCTION(void, op_put_by_val_byte_array)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSGlobalData* globalData = stackFrame.globalData;
+    
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    JSValue subscript = stackFrame.args[1].jsValue();
+    JSValue value = stackFrame.args[2].jsValue();
+    
+    if (LIKELY(subscript.isUInt32())) {
+        uint32_t i = subscript.asUInt32();
+        if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+            JSByteArray* jsByteArray = asByteArray(baseValue);
+            
+            // All fast byte array accesses are safe from exceptions so return immediately to avoid exception checks.
+            if (value.isInt32()) {
+                jsByteArray->setIndex(i, value.asInt32());
+                return;
+            } else {
+                double dValue = 0;                
+                if (value.getNumber(dValue)) {
+                    jsByteArray->setIndex(i, dValue);
+                    return;
+                }
+            }
+        }
+
+        if (!isJSByteArray(globalData, baseValue))
+            ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_put_by_val));
+        baseValue.put(callFrame, i, value);
+    } else {
+        Identifier property(callFrame, subscript.toString(callFrame));
+        if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
+            PutPropertySlot slot;
+            baseValue.put(callFrame, property, value, slot);
+        }
+    }
+    
+    CHECK_FOR_EXCEPTION_AT_END();
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_lesseq)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsBoolean(jsLessEq(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(int, op_loop_if_true)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    bool result = src1.toBoolean(callFrame);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return result;
+}
+    
+DEFINE_STUB_FUNCTION(int, op_load_varargs)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    RegisterFile* registerFile = stackFrame.registerFile;
+    int argsOffset = stackFrame.args[0].int32();
+    JSValue arguments = callFrame->registers()[argsOffset].jsValue();
+    uint32_t argCount = 0;
+    if (!arguments) {
+        int providedParams = callFrame->registers()[RegisterFile::ArgumentCount].i() - 1;
+        argCount = providedParams;
+        int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
+        Register* newEnd = callFrame->registers() + sizeDelta;
+        if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
+            stackFrame.globalData->exception = createStackOverflowError(callFrame);
+            VM_THROW_EXCEPTION();
+        }
+        int32_t expectedParams = callFrame->callee()->body()->parameterCount();
+        int32_t inplaceArgs = min(providedParams, expectedParams);
+        
+        Register* inplaceArgsDst = callFrame->registers() + argsOffset;
+
+        Register* inplaceArgsEnd = inplaceArgsDst + inplaceArgs;
+        Register* inplaceArgsEnd2 = inplaceArgsDst + providedParams;
+
+        Register* inplaceArgsSrc = callFrame->registers() - RegisterFile::CallFrameHeaderSize - expectedParams;
+        Register* inplaceArgsSrc2 = inplaceArgsSrc - providedParams - 1 + inplaceArgs;
+        // First step is to copy the "expected" parameters from their normal location relative to the callframe
+        while (inplaceArgsDst < inplaceArgsEnd)
+            *inplaceArgsDst++ = *inplaceArgsSrc++;
+
+        // Then we copy any additional arguments that may be further up the stack ('-1' to account for 'this')
+        while (inplaceArgsDst < inplaceArgsEnd2)
+            *inplaceArgsDst++ = *inplaceArgsSrc2++;
+
+    } else if (!arguments.isUndefinedOrNull()) {
+        if (!arguments.isObject()) {
+            CodeBlock* codeBlock = callFrame->codeBlock();
+            unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+            stackFrame.globalData->exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPCIndex, codeBlock);
+            VM_THROW_EXCEPTION();
+        }
+        if (asObject(arguments)->classInfo() == &Arguments::info) {
+            Arguments* argsObject = asArguments(arguments);
+            argCount = argsObject->numProvidedArguments(callFrame);
+            int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
+            Register* newEnd = callFrame->registers() + sizeDelta;
+            if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
+                stackFrame.globalData->exception = createStackOverflowError(callFrame);
+                VM_THROW_EXCEPTION();
+            }
+            argsObject->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount);
+        } else if (isJSArray(&callFrame->globalData(), arguments)) {
+            JSArray* array = asArray(arguments);
+            argCount = array->length();
+            int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
+            Register* newEnd = callFrame->registers() + sizeDelta;
+            if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
+                stackFrame.globalData->exception = createStackOverflowError(callFrame);
+                VM_THROW_EXCEPTION();
+            }
+            array->copyToRegisters(callFrame, callFrame->registers() + argsOffset, argCount);
+        } else if (asObject(arguments)->inherits(&JSArray::info)) {
+            JSObject* argObject = asObject(arguments);
+            argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+            int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize;
+            Register* newEnd = callFrame->registers() + sizeDelta;
+            if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) {
+                stackFrame.globalData->exception = createStackOverflowError(callFrame);
+                VM_THROW_EXCEPTION();
+            }
+            Register* argsBuffer = callFrame->registers() + argsOffset;
+            for (unsigned i = 0; i < argCount; ++i) {
+                argsBuffer[i] = asObject(arguments)->get(callFrame, i);
+                CHECK_FOR_EXCEPTION();
+            }
+        } else {
+            CodeBlock* codeBlock = callFrame->codeBlock();
+            unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+            stackFrame.globalData->exception = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPCIndex, codeBlock);
+            VM_THROW_EXCEPTION();
+        }
+    }
+
+    return argCount + 1;
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_negate)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src = stackFrame.args[0].jsValue();
+
+    double v;
+    if (src.getNumber(v))
+        return JSValue::encode(jsNumber(stackFrame.globalData, -v));
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, -src.toNumber(callFrame));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSValue::encode(JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain()));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    ScopeChainNode* scopeChain = callFrame->scopeChain();
+
+    int skip = stackFrame.args[1].int32();
+
+    ScopeChainIterator iter = scopeChain->begin();
+    ScopeChainIterator end = scopeChain->end();
+    ASSERT(iter != end);
+    while (skip--) {
+        ++iter;
+        ASSERT(iter != end);
+    }
+    Identifier& ident = stackFrame.args[0].identifier();
+    do {
+        JSObject* o = *iter;
+        PropertySlot slot(o);
+        if (o->getPropertySlot(callFrame, ident, slot)) {
+            JSValue result = slot.getValue(callFrame, ident);
+            CHECK_FOR_EXCEPTION_AT_END();
+            return JSValue::encode(result);
+        }
+    } while (++iter != end);
+
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+    stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
+    VM_THROW_EXCEPTION();
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSGlobalObject* globalObject = stackFrame.args[0].globalObject();
+    Identifier& ident = stackFrame.args[1].identifier();
+    unsigned globalResolveInfoIndex = stackFrame.args[2].int32();
+    ASSERT(globalObject->isGlobalObject());
+
+    PropertySlot slot(globalObject);
+    if (globalObject->getPropertySlot(callFrame, ident, slot)) {
+        JSValue result = slot.getValue(callFrame, ident);
+        if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
+            GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex);
+            if (globalResolveInfo.structure)
+                globalResolveInfo.structure->deref();
+            globalObject->structure()->ref();
+            globalResolveInfo.structure = globalObject->structure();
+            globalResolveInfo.offset = slot.cachedOffset();
+            return JSValue::encode(result);
+        }
+
+        CHECK_FOR_EXCEPTION_AT_END();
+        return JSValue::encode(result);
+    }
+
+    unsigned vPCIndex = callFrame->codeBlock()->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+    stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, callFrame->codeBlock());
+    VM_THROW_EXCEPTION();
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_div)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    double left;
+    double right;
+    if (src1.getNumber(left) && src2.getNumber(right))
+        return JSValue::encode(jsNumber(stackFrame.globalData, left / right));
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, src1.toNumber(callFrame) / src2.toNumber(callFrame));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_dec)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue v = stackFrame.args[0].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, v.toNumber(callFrame) - 1);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(int, op_jless)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    bool result = jsLess(callFrame, src1, src2);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return result;
+}
+
+DEFINE_STUB_FUNCTION(int, op_jlesseq)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    bool result = jsLessEq(callFrame, src1, src2);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return result;
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_not)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src = stackFrame.args[0].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    JSValue result = jsBoolean(!src.toBoolean(callFrame));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(int, op_jtrue)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    bool result = src1.toBoolean(callFrame);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return result;
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue v = stackFrame.args[0].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    JSValue number = v.toJSNumber(callFrame);
+    CHECK_FOR_EXCEPTION_AT_END();
+
+    callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(stackFrame.globalData, number.uncheckedGetNumber() + 1);
+    return JSValue::encode(number);
+}
+
+#if USE(JSVALUE32_64)
+
+DEFINE_STUB_FUNCTION(int, op_eq)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    start:
+    if (src2.isUndefined()) {
+        return src1.isNull() || 
+               (src1.isCell() && asCell(src1)->structure()->typeInfo().masqueradesAsUndefined()) ||
+               src1.isUndefined();
+    }
+    
+    if (src2.isNull()) {
+        return src1.isUndefined() || 
+               (src1.isCell() && asCell(src1)->structure()->typeInfo().masqueradesAsUndefined()) ||
+               src1.isNull();
+    }
+
+    if (src1.isInt32()) {
+        if (src2.isDouble())
+            return src1.asInt32() == src2.asDouble();
+        double d = src2.toNumber(stackFrame.callFrame);
+        CHECK_FOR_EXCEPTION();
+        return src1.asInt32() == d;
+    }
+
+    if (src1.isDouble()) {
+        if (src2.isInt32())
+            return src1.asDouble() == src2.asInt32();
+        double d = src2.toNumber(stackFrame.callFrame);
+        CHECK_FOR_EXCEPTION();
+        return src1.asDouble() == d;
+    }
+
+    if (src1.isTrue()) {
+        if (src2.isFalse())
+            return false;
+        double d = src2.toNumber(stackFrame.callFrame);
+        CHECK_FOR_EXCEPTION();
+        return d == 1.0;
+    }
+
+    if (src1.isFalse()) {
+        if (src2.isTrue())
+            return false;
+        double d = src2.toNumber(stackFrame.callFrame);
+        CHECK_FOR_EXCEPTION();
+        return d == 0.0;
+    }
+    
+    if (src1.isUndefined())
+        return src2.isCell() && asCell(src2)->structure()->typeInfo().masqueradesAsUndefined();
+    
+    if (src1.isNull())
+        return src2.isCell() && asCell(src2)->structure()->typeInfo().masqueradesAsUndefined();
+
+    ASSERT(src1.isCell());
+
+    JSCell* cell1 = asCell(src1);
+
+    if (cell1->isString()) {
+        if (src2.isInt32())
+            return static_cast<JSString*>(cell1)->value().toDouble() == src2.asInt32();
+            
+        if (src2.isDouble())
+            return static_cast<JSString*>(cell1)->value().toDouble() == src2.asDouble();
+
+        if (src2.isTrue())
+            return static_cast<JSString*>(cell1)->value().toDouble() == 1.0;
+
+        if (src2.isFalse())
+            return static_cast<JSString*>(cell1)->value().toDouble() == 0.0;
+
+        ASSERT(src2.isCell());
+        JSCell* cell2 = asCell(src2);
+        if (cell2->isString())
+            return static_cast<JSString*>(cell1)->value() == static_cast<JSString*>(cell2)->value();
+
+        ASSERT(cell2->isObject());
+        src2 = static_cast<JSObject*>(cell2)->toPrimitive(stackFrame.callFrame);
+        CHECK_FOR_EXCEPTION();
+        goto start;
+    }
+
+    ASSERT(cell1->isObject());
+    if (src2.isObject())
+        return static_cast<JSObject*>(cell1) == asObject(src2);
+    src1 = static_cast<JSObject*>(cell1)->toPrimitive(stackFrame.callFrame);
+    CHECK_FOR_EXCEPTION();
+    goto start;
+}
+
+DEFINE_STUB_FUNCTION(int, op_eq_strings)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSString* string1 = stackFrame.args[0].jsString();
+    JSString* string2 = stackFrame.args[1].jsString();
+
+    ASSERT(string1->isString());
+    ASSERT(string2->isString());
+    return string1->value() == string2->value();
+}
+
+#else // USE(JSVALUE32_64)
+
+DEFINE_STUB_FUNCTION(int, op_eq)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return result;
+}
+
+#endif // USE(JSVALUE32_64)
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue val = stackFrame.args[0].jsValue();
+    JSValue shift = stackFrame.args[1].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, (val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitand)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    ASSERT(!src1.isInt32() || !src2.isInt32());
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, src1.toInt32(callFrame) & src2.toInt32(callFrame));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_rshift)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue val = stackFrame.args[0].jsValue();
+    JSValue shift = stackFrame.args[1].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, (val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitnot)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src = stackFrame.args[0].jsValue();
+
+    ASSERT(!src.isInt32());
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, ~src.toInt32(callFrame));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_base)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    ScopeChainNode* scopeChain = callFrame->scopeChain();
+
+    ScopeChainIterator iter = scopeChain->begin();
+    ScopeChainIterator end = scopeChain->end();
+
+    // FIXME: add scopeDepthIsZero optimization
+
+    ASSERT(iter != end);
+
+    Identifier& ident = stackFrame.args[0].identifier();
+    JSObject* base;
+    do {
+        base = *iter;
+        PropertySlot slot(base);
+        if (base->getPropertySlot(callFrame, ident, slot)) {
+            JSValue result = slot.getValue(callFrame, ident);
+            CHECK_FOR_EXCEPTION_AT_END();
+
+            callFrame->registers()[stackFrame.args[1].int32()] = JSValue(base);
+            return JSValue::encode(result);
+        }
+        ++iter;
+    } while (iter != end);
+
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+    stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident, vPCIndex, codeBlock);
+    VM_THROW_EXCEPTION_AT_END();
+    return JSValue::encode(JSValue());
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return stackFrame.args[0].funcExprNode()->makeFunction(stackFrame.callFrame, stackFrame.callFrame->scopeChain());
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_mod)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue dividendValue = stackFrame.args[0].jsValue();
+    JSValue divisorValue = stackFrame.args[1].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    double d = dividendValue.toNumber(callFrame);
+    JSValue result = jsNumber(stackFrame.globalData, fmod(d, divisorValue.toNumber(callFrame)));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_less)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsBoolean(jsLess(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_dec)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue v = stackFrame.args[0].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    JSValue number = v.toJSNumber(callFrame);
+    CHECK_FOR_EXCEPTION_AT_END();
+
+    callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(stackFrame.globalData, number.uncheckedGetNumber() - 1);
+    return JSValue::encode(number);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_urshift)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue val = stackFrame.args[0].jsValue();
+    JSValue shift = stackFrame.args[1].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue result = jsNumber(stackFrame.globalData, (val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitxor)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    JSValue result = jsNumber(stackFrame.globalData, src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return new (stackFrame.globalData) RegExpObject(stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), stackFrame.args[0].regExp());
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    JSValue result = jsNumber(stackFrame.globalData, src1.toInt32(callFrame) | src2.toInt32(callFrame));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    RegisterFile* registerFile = stackFrame.registerFile;
+
+    Interpreter* interpreter = stackFrame.globalData->interpreter;
+    
+    JSValue funcVal = stackFrame.args[0].jsValue();
+    int registerOffset = stackFrame.args[1].int32();
+    int argCount = stackFrame.args[2].int32();
+
+    Register* newCallFrame = callFrame->registers() + registerOffset;
+    Register* argv = newCallFrame - RegisterFile::CallFrameHeaderSize - argCount;
+    JSValue thisValue = argv[0].jsValue();
+    JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
+
+    if (thisValue == globalObject && funcVal == globalObject->evalFunction()) {
+        JSValue exceptionValue;
+        JSValue result = interpreter->callEval(callFrame, registerFile, argv, argCount, registerOffset, exceptionValue);
+        if (UNLIKELY(exceptionValue)) {
+            stackFrame.globalData->exception = exceptionValue;
+            VM_THROW_EXCEPTION_AT_END();
+        }
+        return JSValue::encode(result);
+    }
+
+    return JSValue::encode(JSValue());
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_throw)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    CodeBlock* codeBlock = callFrame->codeBlock();
+
+    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+
+    JSValue exceptionValue = stackFrame.args[0].jsValue();
+    ASSERT(exceptionValue);
+
+    HandlerInfo* handler = stackFrame.globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, true);
+
+    if (!handler) {
+        *stackFrame.exception = exceptionValue;
+        STUB_SET_RETURN_ADDRESS(reinterpret_cast<void*>(ctiOpThrowNotCaught));
+        return JSValue::encode(jsNull());
+    }
+
+    stackFrame.callFrame = callFrame;
+    void* catchRoutine = handler->nativeCode.executableAddress();
+    ASSERT(catchRoutine);
+    STUB_SET_RETURN_ADDRESS(catchRoutine);
+    return JSValue::encode(exceptionValue);
+}
+
+DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSPropertyNameIterator::create(stackFrame.callFrame, stackFrame.args[0].jsValue());
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_next_pname)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSPropertyNameIterator* it = stackFrame.args[0].propertyNameIterator();
+    JSValue temp = it->next(stackFrame.callFrame);
+    if (!temp)
+        it->invalidate();
+    return JSValue::encode(temp);
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_push_scope)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSObject* o = stackFrame.args[0].jsValue().toObject(stackFrame.callFrame);
+    CHECK_FOR_EXCEPTION();
+    stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->push(o));
+    return o;
+}
+
+DEFINE_STUB_FUNCTION(void, op_pop_scope)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->pop());
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_typeof)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSValue::encode(jsTypeStringForValue(stackFrame.callFrame, stackFrame.args[0].jsValue()));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_undefined)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue v = stackFrame.args[0].jsValue();
+    return JSValue::encode(jsBoolean(v.isCell() ? v.asCell()->structure()->typeInfo().masqueradesAsUndefined() : v.isUndefined()));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_boolean)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSValue::encode(jsBoolean(stackFrame.args[0].jsValue().isBoolean()));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_number)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSValue::encode(jsBoolean(stackFrame.args[0].jsValue().isNumber()));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_string)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSValue::encode(jsBoolean(isJSString(stackFrame.globalData, stackFrame.args[0].jsValue())));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_object)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSValue::encode(jsBoolean(jsIsObjectType(stackFrame.args[0].jsValue())));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_function)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSValue::encode(jsBoolean(jsIsFunctionType(stackFrame.args[0].jsValue())));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_stricteq)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    return JSValue::encode(jsBoolean(JSValue::strictEqual(src1, src2)));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_primitive)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSValue::encode(stackFrame.args[0].jsValue().toPrimitive(stackFrame.callFrame));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_strcat)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    return JSValue::encode(concatenateStrings(stackFrame.callFrame, &stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32()));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src1 = stackFrame.args[0].jsValue();
+    JSValue src2 = stackFrame.args[1].jsValue();
+
+    return JSValue::encode(jsBoolean(!JSValue::strictEqual(src1, src2)));
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue src = stackFrame.args[0].jsValue();
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    JSValue result = src.toJSNumber(callFrame);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_in)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSValue baseVal = stackFrame.args[1].jsValue();
+
+    if (!baseVal.isObject()) {
+        CallFrame* callFrame = stackFrame.callFrame;
+        CodeBlock* codeBlock = callFrame->codeBlock();
+        unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, STUB_RETURN_ADDRESS);
+        stackFrame.globalData->exception = createInvalidParamError(callFrame, "in", baseVal, vPCIndex, codeBlock);
+        VM_THROW_EXCEPTION();
+    }
+
+    JSValue propName = stackFrame.args[0].jsValue();
+    JSObject* baseObj = asObject(baseVal);
+
+    uint32_t i;
+    if (propName.getUInt32(i))
+        return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, i)));
+
+    Identifier property(callFrame, propName.toString(callFrame));
+    CHECK_FOR_EXCEPTION();
+    return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, property)));
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_push_new_scope)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSObject* scope = new (stackFrame.globalData) JSStaticScopeObject(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), DontDelete);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    callFrame->setScopeChain(callFrame->scopeChain()->push(scope));
+    return scope;
+}
+
+DEFINE_STUB_FUNCTION(void, op_jmp_scopes)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    unsigned count = stackFrame.args[0].int32();
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    ScopeChainNode* tmp = callFrame->scopeChain();
+    while (count--)
+        tmp = tmp->pop();
+    callFrame->setScopeChain(tmp);
+}
+
+DEFINE_STUB_FUNCTION(void, op_put_by_index)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    unsigned property = stackFrame.args[1].int32();
+
+    stackFrame.args[0].jsValue().put(callFrame, property, stackFrame.args[2].jsValue());
+}
+
+DEFINE_STUB_FUNCTION(void*, op_switch_imm)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue scrutinee = stackFrame.args[0].jsValue();
+    unsigned tableIndex = stackFrame.args[1].int32();
+    CallFrame* callFrame = stackFrame.callFrame;
+    CodeBlock* codeBlock = callFrame->codeBlock();
+
+    if (scrutinee.isInt32())
+        return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.asInt32()).executableAddress();
+    else {
+        double value;
+        int32_t intValue;
+        if (scrutinee.getNumber(value) && ((intValue = static_cast<int32_t>(value)) == value))
+            return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(intValue).executableAddress();
+        else
+            return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
+    }
+}
+
+DEFINE_STUB_FUNCTION(void*, op_switch_char)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue scrutinee = stackFrame.args[0].jsValue();
+    unsigned tableIndex = stackFrame.args[1].int32();
+    CallFrame* callFrame = stackFrame.callFrame;
+    CodeBlock* codeBlock = callFrame->codeBlock();
+
+    void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
+
+    if (scrutinee.isString()) {
+        UString::Rep* value = asString(scrutinee)->value().rep();
+        if (value->size() == 1)
+            result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]).executableAddress();
+    }
+
+    return result;
+}
+
+DEFINE_STUB_FUNCTION(void*, op_switch_string)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    JSValue scrutinee = stackFrame.args[0].jsValue();
+    unsigned tableIndex = stackFrame.args[1].int32();
+    CallFrame* callFrame = stackFrame.callFrame;
+    CodeBlock* codeBlock = callFrame->codeBlock();
+
+    void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
+
+    if (scrutinee.isString()) {
+        UString::Rep* value = asString(scrutinee)->value().rep();
+        result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();
+    }
+
+    return result;
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    JSValue baseValue = stackFrame.args[0].jsValue();
+    JSObject* baseObj = baseValue.toObject(callFrame); // may throw
+
+    JSValue subscript = stackFrame.args[1].jsValue();
+    JSValue result;
+    uint32_t i;
+    if (subscript.getUInt32(i))
+        result = jsBoolean(baseObj->deleteProperty(callFrame, i));
+    else {
+        CHECK_FOR_EXCEPTION();
+        Identifier property(callFrame, subscript.toString(callFrame));
+        CHECK_FOR_EXCEPTION();
+        result = jsBoolean(baseObj->deleteProperty(callFrame, property));
+    }
+
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(void, op_put_getter)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    ASSERT(stackFrame.args[0].jsValue().isObject());
+    JSObject* baseObj = asObject(stackFrame.args[0].jsValue());
+    ASSERT(stackFrame.args[2].jsValue().isObject());
+    baseObj->defineGetter(callFrame, stackFrame.args[1].identifier(), asObject(stackFrame.args[2].jsValue()));
+}
+
+DEFINE_STUB_FUNCTION(void, op_put_setter)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    ASSERT(stackFrame.args[0].jsValue().isObject());
+    JSObject* baseObj = asObject(stackFrame.args[0].jsValue());
+    ASSERT(stackFrame.args[2].jsValue().isObject());
+    baseObj->defineSetter(callFrame, stackFrame.args[1].identifier(), asObject(stackFrame.args[2].jsValue()));
+}
+
+DEFINE_STUB_FUNCTION(JSObject*, op_new_error)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    unsigned type = stackFrame.args[0].int32();
+    JSValue message = stackFrame.args[1].jsValue();
+    unsigned bytecodeOffset = stackFrame.args[2].int32();
+
+    unsigned lineNumber = codeBlock->lineNumberForBytecodeOffset(callFrame, bytecodeOffset);
+    return Error::create(callFrame, static_cast<ErrorType>(type), message.toString(callFrame), lineNumber, codeBlock->ownerNode()->sourceID(), codeBlock->ownerNode()->sourceURL());
+}
+
+DEFINE_STUB_FUNCTION(void, op_debug)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+
+    int debugHookID = stackFrame.args[0].int32();
+    int firstLine = stackFrame.args[1].int32();
+    int lastLine = stackFrame.args[2].int32();
+
+    stackFrame.globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, vm_throw)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+
+    CallFrame* callFrame = stackFrame.callFrame;
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    JSGlobalData* globalData = stackFrame.globalData;
+
+    unsigned vPCIndex = codeBlock->getBytecodeIndex(callFrame, globalData->exceptionLocation);
+
+    JSValue exceptionValue = globalData->exception;
+    ASSERT(exceptionValue);
+    globalData->exception = JSValue();
+
+    HandlerInfo* handler = globalData->interpreter->throwException(callFrame, exceptionValue, vPCIndex, false);
+
+    if (!handler) {
+        *stackFrame.exception = exceptionValue;
+        return JSValue::encode(jsNull());
+    }
+
+    stackFrame.callFrame = callFrame;
+    void* catchRoutine = handler->nativeCode.executableAddress();
+    ASSERT(catchRoutine);
+    STUB_SET_RETURN_ADDRESS(catchRoutine);
+    return JSValue::encode(exceptionValue);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
diff --git a/jit/JITStubs.h b/jit/JITStubs.h
new file mode 100644 (file)
index 0000000..317eca9
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JITStubs_h
+#define JITStubs_h
+
+#include <wtf/Platform.h>
+
+#include "MacroAssemblerCodeRef.h"
+#include "Register.h"
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+    class CodeBlock;
+    class ExecutablePool;
+    class Identifier;
+    class JSGlobalData;
+    class JSGlobalData;
+    class JSObject;
+    class JSPropertyNameIterator;
+    class JSValue;
+    class JSValueEncodedAsPointer;
+    class Profiler;
+    class PropertySlot;
+    class PutPropertySlot;
+    class RegisterFile;
+    class FuncDeclNode;
+    class FuncExprNode;
+    class JSGlobalObject;
+    class RegExp;
+
+    union JITStubArg {
+        void* asPointer;
+        EncodedJSValue asEncodedJSValue;
+        int32_t asInt32;
+
+        JSValue jsValue() { return JSValue::decode(asEncodedJSValue); }
+        Identifier& identifier() { return *static_cast<Identifier*>(asPointer); }
+        int32_t int32() { return asInt32; }
+        CodeBlock* codeBlock() { return static_cast<CodeBlock*>(asPointer); }
+        FuncDeclNode* funcDeclNode() { return static_cast<FuncDeclNode*>(asPointer); }
+        FuncExprNode* funcExprNode() { return static_cast<FuncExprNode*>(asPointer); }
+        RegExp* regExp() { return static_cast<RegExp*>(asPointer); }
+        JSPropertyNameIterator* propertyNameIterator() { return static_cast<JSPropertyNameIterator*>(asPointer); }
+        JSGlobalObject* globalObject() { return static_cast<JSGlobalObject*>(asPointer); }
+        JSString* jsString() { return static_cast<JSString*>(asPointer); }
+        ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); }
+    };
+
+#if PLATFORM(X86_64)
+    struct JITStackFrame {
+        void* reserved; // Unused
+        JITStubArg args[6];
+        void* padding[2]; // Maintain 32-byte stack alignment (possibly overkill).
+
+        void* savedRBX;
+        void* savedR15;
+        void* savedR14;
+        void* savedR13;
+        void* savedR12;
+        void* savedRBP;
+        void* savedRIP;
+
+        void* code;
+        RegisterFile* registerFile;
+        CallFrame* callFrame;
+        JSValue* exception;
+        Profiler** enabledProfilerReference;
+        JSGlobalData* globalData;
+
+        // When JIT code makes a call, it pushes its return address just below the rest of the stack.
+        ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
+    };
+#elif PLATFORM(X86)
+#if COMPILER(MSVC)
+#pragma pack(push)
+#pragma pack(4)
+#endif // COMPILER(MSVC)
+    struct JITStackFrame {
+        void* reserved; // Unused
+        JITStubArg args[6];
+#if USE(JSVALUE32_64)
+        void* padding[2]; // Maintain 16-byte stack alignment.
+#endif
+
+        void* savedEBX;
+        void* savedEDI;
+        void* savedESI;
+        void* savedEBP;
+        void* savedEIP;
+
+        void* code;
+        RegisterFile* registerFile;
+        CallFrame* callFrame;
+        JSValue* exception;
+        Profiler** enabledProfilerReference;
+        JSGlobalData* globalData;
+        
+        // When JIT code makes a call, it pushes its return address just below the rest of the stack.
+        ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
+    };
+#if COMPILER(MSVC)
+#pragma pack(pop)
+#endif // COMPILER(MSVC)
+#elif PLATFORM_ARM_ARCH(7)
+    struct JITStackFrame {
+        void* reserved; // Unused
+        JITStubArg args[6];
+#if USE(JSVALUE32_64)
+        void* padding[2]; // Maintain 16-byte stack alignment.
+#endif
+
+        ReturnAddressPtr thunkReturnAddress;
+
+        void* preservedReturnAddress;
+        void* preservedR4;
+        void* preservedR5;
+        void* preservedR6;
+
+        // These arguments passed in r1..r3 (r0 contained the entry code pointed, which is not preserved)
+        RegisterFile* registerFile;
+        CallFrame* callFrame;
+        JSValue* exception;
+
+        // These arguments passed on the stack.
+        Profiler** enabledProfilerReference;
+        JSGlobalData* globalData;
+        
+        ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
+    };
+#else
+#error "JITStackFrame not defined for this platform."
+#endif
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+    #define STUB_ARGS_DECLARATION void* args, ...
+    #define STUB_ARGS (reinterpret_cast<void**>(vl_args) - 1)
+
+    #if COMPILER(MSVC)
+    #define JIT_STUB __cdecl
+    #else
+    #define JIT_STUB
+    #endif
+#else
+    #define STUB_ARGS_DECLARATION void** args
+    #define STUB_ARGS (args)
+
+    #if PLATFORM(X86) && COMPILER(MSVC)
+    #define JIT_STUB __fastcall
+    #elif PLATFORM(X86) && COMPILER(GCC)
+    #define JIT_STUB  __attribute__ ((fastcall))
+    #else
+    #define JIT_STUB
+    #endif
+#endif
+
+#if PLATFORM(X86_64)
+    struct VoidPtrPair {
+        void* first;
+        void* second;
+    };
+    #define RETURN_POINTER_PAIR(a,b) VoidPtrPair pair = { a, b }; return pair
+#else
+    // MSVC doesn't support returning a two-value struct in two registers, so
+    // we cast the struct to int64_t instead.
+    typedef uint64_t VoidPtrPair;
+    union VoidPtrPairUnion {
+        struct { void* first; void* second; } s;
+        VoidPtrPair i;
+    };
+    #define RETURN_POINTER_PAIR(a,b) VoidPtrPairUnion pair = {{ a, b }}; return pair.i
+#endif
+
+    extern "C" void ctiVMThrowTrampoline();
+    extern "C" void ctiOpThrowNotCaught();
+    extern "C" EncodedJSValue ctiTrampoline(
+#if PLATFORM(X86_64)
+            // FIXME: (bug #22910) this will force all arguments onto the stack (regparm(0) does not appear to have any effect).
+            // We can allow register passing here, and move the writes of these values into the trampoline.
+            void*, void*, void*, void*, void*, void*,
+#endif
+            void* code, RegisterFile*, CallFrame*, JSValue* exception, Profiler**, JSGlobalData*);
+
+    class JITThunks {
+    public:
+        JITThunks(JSGlobalData*);
+
+        static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&);
+        static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&);
+        
+        MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_ctiStringLengthTrampoline; }
+        MacroAssemblerCodePtr ctiVirtualCallPreLink() { return m_ctiVirtualCallPreLink; }
+        MacroAssemblerCodePtr ctiVirtualCallLink() { return m_ctiVirtualCallLink; }
+        MacroAssemblerCodePtr ctiVirtualCall() { return m_ctiVirtualCall; }
+        MacroAssemblerCodePtr ctiNativeCallThunk() { return m_ctiNativeCallThunk; }
+
+    private:
+        RefPtr<ExecutablePool> m_executablePool;
+
+        MacroAssemblerCodePtr m_ctiStringLengthTrampoline;
+        MacroAssemblerCodePtr m_ctiVirtualCallPreLink;
+        MacroAssemblerCodePtr m_ctiVirtualCallLink;
+        MacroAssemblerCodePtr m_ctiVirtualCall;
+        MacroAssemblerCodePtr m_ctiNativeCallThunk;
+    };
+
+extern "C" {
+    EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_bitnot(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_bitor(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_bitxor(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_call_eval(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_construct_NotJSConstruct(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_convert_this(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_del_by_id(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_del_by_val(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_div(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_array_fail(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_generic(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_method_check(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_method_check_second(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_proto_fail(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_proto_list_full(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_second(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_self_fail(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_string_fail(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_val(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_val_byte_array(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_val_string(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_in(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_instanceof(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_is_boolean(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_is_function(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_is_number(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_is_object(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_is_string(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_is_undefined(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_less(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_lesseq(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_lshift(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_mod(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_mul(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_negate(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_next_pname(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_not(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_nstricteq(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_post_dec(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_post_inc(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_pre_dec(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_pre_inc(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_resolve(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_resolve_base(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_resolve_global(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_resolve_skip(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_resolve_with_base(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_rshift(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_strcat(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_stricteq(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_sub(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_throw(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_to_jsnumber(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_to_primitive(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_typeof(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_urshift(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_vm_throw(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_construct_JSConstruct(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_new_array(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_new_error(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS_DECLARATION);
+    JSObject* JIT_STUB cti_op_put_by_id_transition_realloc(STUB_ARGS_DECLARATION);
+    JSPropertyNameIterator* JIT_STUB cti_op_get_pnames(STUB_ARGS_DECLARATION);
+    VoidPtrPair JIT_STUB cti_op_call_arityCheck(STUB_ARGS_DECLARATION);
+    int JIT_STUB cti_op_eq(STUB_ARGS_DECLARATION);
+#if USE(JSVALUE32_64)
+    int JIT_STUB cti_op_eq_strings(STUB_ARGS_DECLARATION);
+#endif
+    int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION);
+    int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION);
+    int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION);
+    int JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION);
+    int JIT_STUB cti_op_loop_if_less(STUB_ARGS_DECLARATION);
+    int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS_DECLARATION);
+    int JIT_STUB cti_op_loop_if_true(STUB_ARGS_DECLARATION);
+    int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_create_arguments(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_create_arguments_no_params(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_debug(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_end(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_jmp_scopes(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_pop_scope(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_profile_did_call(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_profile_will_call(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_id(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_id_fail(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_id_generic(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_id_second(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_index(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_val(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_val_array(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_val_byte_array(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_getter(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_setter(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_ret_scopeChain(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_tear_off_activation(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_tear_off_arguments(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_register_file_check(STUB_ARGS_DECLARATION);
+    void* JIT_STUB cti_op_call_JSFunction(STUB_ARGS_DECLARATION);
+    void* JIT_STUB cti_op_switch_char(STUB_ARGS_DECLARATION);
+    void* JIT_STUB cti_op_switch_imm(STUB_ARGS_DECLARATION);
+    void* JIT_STUB cti_op_switch_string(STUB_ARGS_DECLARATION);
+    void* JIT_STUB cti_vm_dontLazyLinkCall(STUB_ARGS_DECLARATION);
+    void* JIT_STUB cti_vm_lazyLinkCall(STUB_ARGS_DECLARATION);
+} // extern "C"
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JITStubs_h
diff --git a/jsc.cpp b/jsc.cpp
index 666bd586c97d30cc96daeb24f6ca07b5ad763c7b..efe3fa5e836d160288b2c4952ae4a15c06d4f1f3 100644 (file)
--- a/jsc.cpp
+++ b/jsc.cpp
@@ -26,6 +26,7 @@
 #include "Completion.h"
 #include "InitializeThreading.h"
 #include "JSArray.h"
+#include "JSFunction.h"
 #include "JSLock.h"
 #include "PrototypeFunction.h"
 #include "SamplingTool.h"
 #include <sys/time.h>
 #endif
 
-#if PLATFORM(UNIX)
+#if HAVE(SIGNAL_H)
 #include <signal.h>
 #endif
 
-#if COMPILER(MSVC) && !PLATFORM(WIN_CE)
+#if COMPILER(MSVC) && !PLATFORM(WINCE)
 #include <crtdbg.h>
 #include <windows.h>
+#include <mmsystem.h>
 #endif
 
 #if PLATFORM(QT)
@@ -67,14 +69,31 @@ using namespace WTF;
 static void cleanupGlobalData(JSGlobalData*);
 static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer);
 
-static JSValuePtr functionPrint(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionDebug(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionGC(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionVersion(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionRun(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionLoad(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionReadline(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static NO_RETURN JSValuePtr functionQuit(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL functionPrint(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionDebug(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionGC(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionVersion(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionRun(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionLoad(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionCheckSyntax(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionReadline(ExecState*, JSObject*, JSValue, const ArgList&);
+static NO_RETURN JSValue JSC_HOST_CALL functionQuit(ExecState*, JSObject*, JSValue, const ArgList&);
+
+#if ENABLE(SAMPLING_FLAGS)
+static JSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*, JSObject*, JSValue, const ArgList&);
+#endif
+
+struct Script {
+    bool isFile;
+    char *argument;
+    
+    Script(bool isFile, char *argument)
+        : isFile(isFile)
+        , argument(argument)
+    {
+    }
+};
 
 struct Options {
     Options()
@@ -85,7 +104,7 @@ struct Options {
 
     bool interactive;
     bool dump;
-    Vector<UString> fileNames;
+    Vector<Script> scripts;
     Vector<UString> arguments;
 };
 
@@ -159,14 +178,20 @@ ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
 GlobalObject::GlobalObject(const Vector<UString>& arguments)
     : JSGlobalObject()
 {
-    putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "debug"), functionDebug));
-    putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "print"), functionPrint));
-    putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "quit"), functionQuit));
-    putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "gc"), functionGC));
-    putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "version"), functionVersion));
-    putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "run"), functionRun));
-    putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "load"), functionLoad));
-    putDirectFunction(globalExec(), new (globalExec()) PrototypeFunction(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "readline"), functionReadline));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "debug"), functionDebug));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "print"), functionPrint));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "quit"), functionQuit));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "gc"), functionGC));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "version"), functionVersion));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "run"), functionRun));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "load"), functionLoad));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "checkSyntax"), functionCheckSyntax));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 0, Identifier(globalExec(), "readline"), functionReadline));
+
+#if ENABLE(SAMPLING_FLAGS)
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "setSamplingFlags"), functionSetSamplingFlags));
+    putDirectFunction(globalExec(), new (globalExec()) NativeFunctionWrapper(globalExec(), prototypeFunctionStructure(), 1, Identifier(globalExec(), "clearSamplingFlags"), functionClearSamplingFlags));
+#endif
 
     JSObject* array = constructEmptyArray(globalExec());
     for (size_t i = 0; i < arguments.size(); ++i)
@@ -174,13 +199,13 @@ GlobalObject::GlobalObject(const Vector<UString>& arguments)
     putDirect(Identifier(globalExec(), "arguments"), array);
 }
 
-JSValuePtr functionPrint(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL functionPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     for (unsigned i = 0; i < args.size(); ++i) {
         if (i != 0)
             putchar(' ');
         
-        printf("%s", args.at(exec, i).toString(exec).UTF8String().c_str());
+        printf("%s", args.at(i).toString(exec).UTF8String().c_str());
     }
     
     putchar('\n');
@@ -188,30 +213,30 @@ JSValuePtr functionPrint(ExecState* exec, JSObject*, JSValuePtr, const ArgList&
     return jsUndefined();
 }
 
-JSValuePtr functionDebug(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL functionDebug(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    fprintf(stderr, "--> %s\n", args.at(exec, 0).toString(exec).UTF8String().c_str());
+    fprintf(stderr, "--> %s\n", args.at(0).toString(exec).UTF8String().c_str());
     return jsUndefined();
 }
 
-JSValuePtr functionGC(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
+JSValue JSC_HOST_CALL functionGC(ExecState* exec, JSObject*, JSValue, const ArgList&)
 {
     JSLock lock(false);
     exec->heap()->collect();
     return jsUndefined();
 }
 
-JSValuePtr functionVersion(ExecState*, JSObject*, JSValuePtr, const ArgList&)
+JSValue JSC_HOST_CALL functionVersion(ExecState*, JSObject*, JSValue, const ArgList&)
 {
     // We need this function for compatibility with the Mozilla JS tests but for now
     // we don't actually do any version-specific handling
     return jsUndefined();
 }
 
-JSValuePtr functionRun(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL functionRun(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     StopWatch stopWatch;
-    UString fileName = args.at(exec, 0).toString(exec);
+    UString fileName = args.at(0).toString(exec);
     Vector<char> script;
     if (!fillBufferWithContentsOfFile(fileName, script))
         return throwError(exec, GeneralError, "Could not open file.");
@@ -225,20 +250,61 @@ JSValuePtr functionRun(ExecState* exec, JSObject*, JSValuePtr, const ArgList& ar
     return jsNumber(globalObject->globalExec(), stopWatch.getElapsedMS());
 }
 
-JSValuePtr functionLoad(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL functionLoad(ExecState* exec, JSObject* o, JSValue v, const ArgList& args)
 {
-    UString fileName = args.at(exec, 0).toString(exec);
+    UNUSED_PARAM(o);
+    UNUSED_PARAM(v);
+    UString fileName = args.at(0).toString(exec);
     Vector<char> script;
     if (!fillBufferWithContentsOfFile(fileName, script))
         return throwError(exec, GeneralError, "Could not open file.");
 
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-    evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
+    Completion result = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
+    if (result.complType() == Throw)
+        exec->setException(result.value());
+    return result.value();
+}
 
-    return jsUndefined();
+JSValue JSC_HOST_CALL functionCheckSyntax(ExecState* exec, JSObject* o, JSValue v, const ArgList& args)
+{
+    UNUSED_PARAM(o);
+    UNUSED_PARAM(v);
+    UString fileName = args.at(0).toString(exec);
+    Vector<char> script;
+    if (!fillBufferWithContentsOfFile(fileName, script))
+        return throwError(exec, GeneralError, "Could not open file.");
+
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    Completion result = checkSyntax(globalObject->globalExec(), makeSource(script.data(), fileName));
+    if (result.complType() == Throw)
+        exec->setException(result.value());
+    return result.value();
 }
 
-JSValuePtr functionReadline(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
+#if ENABLE(SAMPLING_FLAGS)
+JSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+    for (unsigned i = 0; i < args.size(); ++i) {
+        unsigned flag = static_cast<unsigned>(args.at(i).toNumber(exec));
+        if ((flag >= 1) && (flag <= 32))
+            SamplingFlags::setFlag(flag);
+    }
+    return jsNull();
+}
+
+JSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+    for (unsigned i = 0; i < args.size(); ++i) {
+        unsigned flag = static_cast<unsigned>(args.at(i).toNumber(exec));
+        if ((flag >= 1) && (flag <= 32))
+            SamplingFlags::clearFlag(flag);
+    }
+    return jsNull();
+}
+#endif
+
+JSValue JSC_HOST_CALL functionReadline(ExecState* exec, JSObject*, JSValue, const ArgList&)
 {
     Vector<char, 256> line;
     int c;
@@ -252,7 +318,7 @@ JSValuePtr functionReadline(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
     return jsString(exec, line.data());
 }
 
-JSValuePtr functionQuit(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
+JSValue JSC_HOST_CALL functionQuit(ExecState* exec, JSObject*, JSValue, const ArgList&)
 {
     cleanupGlobalData(&exec->globalData());
     exit(EXIT_SUCCESS);
@@ -284,6 +350,10 @@ int main(int argc, char** argv)
     _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
 #endif
 
+#if COMPILER(MSVC) && !PLATFORM(WINCE)
+    timeBeginPeriod(1);
+#endif
+
 #if PLATFORM(QT)
     QCoreApplication app(argc, argv);
 #endif
@@ -310,9 +380,11 @@ static void cleanupGlobalData(JSGlobalData* globalData)
     globalData->deref();
 }
 
-static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fileNames, bool dump)
+static bool runWithScripts(GlobalObject* globalObject, const Vector<Script>& scripts, bool dump)
 {
-    Vector<char> script;
+    UString script;
+    UString fileName;
+    Vector<char> scriptBuffer;
 
     if (dump)
         BytecodeGenerator::setDumpsGeneratedCode(true);
@@ -320,19 +392,29 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fi
 #if ENABLE(OPCODE_SAMPLING)
     Interpreter* interpreter = globalObject->globalData()->interpreter;
     interpreter->setSampler(new SamplingTool(interpreter));
+    interpreter->sampler()->setup();
+#endif
+#if ENABLE(SAMPLING_FLAGS)
+    SamplingFlags::start();
 #endif
 
     bool success = true;
-    for (size_t i = 0; i < fileNames.size(); i++) {
-        UString fileName = fileNames[i];
-
-        if (!fillBufferWithContentsOfFile(fileName, script))
-            return false; // fail early so we can catch missing files
+    for (size_t i = 0; i < scripts.size(); i++) {
+        if (scripts[i].isFile) {
+            fileName = scripts[i].argument;
+            if (!fillBufferWithContentsOfFile(fileName, scriptBuffer))
+                return false; // fail early so we can catch missing files
+            script = scriptBuffer.data();
+        } else {
+            script = scripts[i].argument;
+            fileName = "[Command Line]";
+        }
 
-#if ENABLE(OPCODE_SAMPLING)
-        interpreter->sampler()->start();
+#if ENABLE(SAMPLING_THREAD)
+        SamplingThread::start();
 #endif
-        Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script.data(), fileName));
+
+        Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(script, fileName));
         success = success && completion.complType() != Throw;
         if (dump) {
             if (completion.complType() == Throw)
@@ -341,24 +423,32 @@ static bool runWithScripts(GlobalObject* globalObject, const Vector<UString>& fi
                 printf("End: %s\n", completion.value().toString(globalObject->globalExec()).ascii());
         }
 
-        globalObject->globalExec()->clearException();
-
-#if ENABLE(OPCODE_SAMPLING)
-        interpreter->sampler()->stop();
+#if ENABLE(SAMPLING_THREAD)
+        SamplingThread::stop();
 #endif
+
+        globalObject->globalExec()->clearException();
     }
 
+#if ENABLE(SAMPLING_FLAGS)
+    SamplingFlags::stop();
+#endif
 #if ENABLE(OPCODE_SAMPLING)
     interpreter->sampler()->dump(globalObject->globalExec());
     delete interpreter->sampler();
+#endif
+#if ENABLE(SAMPLING_COUNTERS)
+    AbstractSamplingCounter::dump();
 #endif
     return success;
 }
 
+#define RUNNING_FROM_XCODE 0
+
 static void runInteractive(GlobalObject* globalObject)
 {
     while (true) {
-#if HAVE(READLINE)
+#if HAVE(READLINE) && !RUNNING_FROM_XCODE
         char* line = readline(interactivePrompt);
         if (!line)
             break;
@@ -367,7 +457,7 @@ static void runInteractive(GlobalObject* globalObject)
         Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line, interpreterName));
         free(line);
 #else
-        puts(interactivePrompt);
+        printf("%s", interactivePrompt);
         Vector<char, 256> line;
         int c;
         while ((c = getchar()) != EOF) {
@@ -376,6 +466,8 @@ static void runInteractive(GlobalObject* globalObject)
                 break;
             line.append(c);
         }
+        if (line.isEmpty())
+            break;
         line.append('\0');
         Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), makeSource(line.data(), interpreterName));
 #endif
@@ -389,30 +481,41 @@ static void runInteractive(GlobalObject* globalObject)
     printf("\n");
 }
 
-static NO_RETURN void printUsageStatement()
+static NO_RETURN void printUsageStatement(JSGlobalData* globalData, bool help = false)
 {
     fprintf(stderr, "Usage: jsc [options] [files] [-- arguments]\n");
     fprintf(stderr, "  -d         Dumps bytecode (debug builds only)\n");
+    fprintf(stderr, "  -e         Evaluate argument as script code\n");
     fprintf(stderr, "  -f         Specifies a source file (deprecated)\n");
     fprintf(stderr, "  -h|--help  Prints this help message\n");
     fprintf(stderr, "  -i         Enables interactive mode (default if no files are specified)\n");
+#if HAVE(SIGNAL_H)
     fprintf(stderr, "  -s         Installs signal handlers that exit on a crash (Unix platforms only)\n");
-    exit(EXIT_FAILURE);
+#endif
+
+    cleanupGlobalData(globalData);
+    exit(help ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
-static void parseArguments(int argc, char** argv, Options& options)
+static void parseArguments(int argc, char** argv, Options& options, JSGlobalData* globalData)
 {
     int i = 1;
     for (; i < argc; ++i) {
         const char* arg = argv[i];
         if (strcmp(arg, "-f") == 0) {
             if (++i == argc)
-                printUsageStatement();
-            options.fileNames.append(argv[i]);
+                printUsageStatement(globalData);
+            options.scripts.append(Script(true, argv[i]));
+            continue;
+        }
+        if (strcmp(arg, "-e") == 0) {
+            if (++i == argc)
+                printUsageStatement(globalData);
+            options.scripts.append(Script(false, argv[i]));
             continue;
         }
         if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
-            printUsageStatement();
+            printUsageStatement(globalData, true);
         }
         if (strcmp(arg, "-i") == 0) {
             options.interactive = true;
@@ -423,7 +526,7 @@ static void parseArguments(int argc, char** argv, Options& options)
             continue;
         }
         if (strcmp(arg, "-s") == 0) {
-#if PLATFORM(UNIX)
+#if HAVE(SIGNAL_H)
             signal(SIGILL, _exit);
             signal(SIGFPE, _exit);
             signal(SIGBUS, _exit);
@@ -435,10 +538,10 @@ static void parseArguments(int argc, char** argv, Options& options)
             ++i;
             break;
         }
-        options.fileNames.append(argv[i]);
+        options.scripts.append(Script(true, argv[i]));
     }
     
-    if (options.fileNames.isEmpty())
+    if (options.scripts.isEmpty())
         options.interactive = true;
     
     for (; i < argc; ++i)
@@ -450,10 +553,10 @@ int jscmain(int argc, char** argv, JSGlobalData* globalData)
     JSLock lock(false);
 
     Options options;
-    parseArguments(argc, argv, options);
+    parseArguments(argc, argv, options, globalData);
 
     GlobalObject* globalObject = new (globalData) GlobalObject(options.arguments);
-    bool success = runWithScripts(globalObject, options.fileNames, options.dump);
+    bool success = runWithScripts(globalObject, options.scripts, options.dump);
     if (options.interactive && success)
         runInteractive(globalObject);
 
diff --git a/jsc.pro b/jsc.pro
index 6262e627fe285c1cb1f6484a90638ea2930e9a25..35c9e6365ba80c5fe85f9761549647037b256c39 100644 (file)
--- a/jsc.pro
+++ b/jsc.pro
@@ -3,21 +3,9 @@ TARGET = jsc
 DESTDIR = .
 SOURCES = jsc.cpp
 QT -= gui
-INCLUDEPATH += $$PWD \
-    $$PWD/parser \
-    $$PWD/bindings \
-    $$PWD/bindings/c \
-    $$PWD/wtf \
-    $$PWD/jit \
-    $$PWD/bytecode
 CONFIG -= app_bundle
-DEFINES += BUILDING_QT__
 CONFIG += building-libs
 
-CONFIG(release) {
-    DEFINES += NDEBUG USE_SYSTEM_MALLOC
-}
-
 include($$PWD/../WebKit.pri)
 
 CONFIG += link_pkgconfig
@@ -26,9 +14,12 @@ QMAKE_RPATHDIR += $$OUTPUT_DIR/lib
 
 isEmpty(OUTPUT_DIR):OUTPUT_DIR=$$PWD/..
 include($$OUTPUT_DIR/config.pri)
-OBJECTS_DIR = tmp
-OBJECTS_DIR_WTR = $$OBJECTS_DIR/
-win32-*: OBJECTS_DIR_WTR ~= s|/|\|
+CONFIG(debug, debug|release) {
+    OBJECTS_DIR = obj/debug
+} else { # Release
+    OBJECTS_DIR = obj/release
+}
+OBJECTS_DIR_WTR = $$OBJECTS_DIR$${QMAKE_DIR_SEP}
 include($$PWD/JavaScriptCore.pri)
 
 lessThan(QT_MINOR_VERSION, 4) {
index 262c883c88ff020e498b73ce44ff7a85248a8d3c..25e17d775e4adf02cf41259cdf05c6285adb3390 100644 (file)
@@ -48,6 +48,22 @@ JavaScriptCore Bakefile project file.
             $(JSCORE_VM_SOURCES)
             $(JSCORE_WTF_SOURCES)
         </sources>
+
+        <set var="ASSEMBLER_SOURCES">
+            <if cond="WX_PORT=='gtk2'">
+                $(JSCORE_VM_SOURCES_POSIX)
+            </if>
+            <if cond="PLATFORM_OS=='mac'">
+                $(JSCORE_VM_SOURCES_POSIX)
+            </if>
+            <if cond="WX_PORT=='msw'">
+                $(JSCORE_VM_SOURCES_WIN)
+            </if>
+        </set>
+
+        <sources>
+            $(ASSEMBLER_SOURCES)
+        </sources>
         <install-to>$(WKOUTPUTDIR)</install-to>
         <pic>on</pic>
         <threading>multi</threading>
@@ -55,6 +71,7 @@ JavaScriptCore Bakefile project file.
         <include>$(SRCDIR)</include>
         <include>$(SRCDIR)/..</include>
         <include>$(SRCDIR)/API</include>
+        <include>$(SRCDIR)/assembler</include>
         <include>$(SRCDIR)/bytecompiler</include>
         <include>$(SRCDIR)/DerivedSources/JavaScriptCore</include>
         <include>$(SRCDIR)/ForwardingHeaders</include>
@@ -76,7 +93,7 @@ JavaScriptCore Bakefile project file.
             <!-- FIXME: we need proper configure checks -->
             <define>HAVE_FUNC_ISNAN</define>
             <!-- check for undefined symbols for debugging reasons -->
-            <ldflags>-Wl,--no-undefined</ldflags>
+            <ldflags>-Wl</ldflags>
         </if>
 
         <if cond="PLATFORM_WIN32=='1'">
@@ -95,6 +112,7 @@ JavaScriptCore Bakefile project file.
         <depends>jscore</depends>
         <include>$(SRCDIR)</include>
         <include>$(WK_ROOT)/JavaScriptCore</include>
+        <include>$(WK_ROOT)/JavaScriptCore/assembler</include>
         <include>$(WK_ROOT)/JavaScriptCore/bytecompiler</include>
         <include>$(WK_ROOT)/JavaScriptCore/debugger</include>
         <include>$(WK_ROOT)/JavaScriptCore/parser</include>
@@ -108,16 +126,12 @@ JavaScriptCore Bakefile project file.
         <include>$(WK_ROOT)/JavaScriptCore/wtf</include>
         <dirname>$(WKOUTPUTDIR)</dirname>
         <sources>$(SRCDIR)/jsc.cpp</sources>
-        <if cond="FORMAT=='gnu'">
-            <ldflags>$(WKOUTPUTDIR)/libjscore.a</ldflags>
-        </if>
         <set var="READLINE_LIB">
             <if cond="WX_PORT=='mac'">edit</if>
         </set>
         <sys-lib>$(READLINE_LIB)</sys-lib>
         <if cond="FORMAT in ['msvc','msvs2005prj']">
             <include>$(WK_ROOT)/WebKitLibraries/win/include</include>
-            <sys-lib>jscore</sys-lib>
             <sys-lib>winmm</sys-lib> <!-- for timeGetTime -->
             <lib-path>$(WKOUTPUTDIR)</lib-path>
             <lib-path>$(WK_ROOT)/WebKitLibraries/win/lib</lib-path>
index ae787f68e843d27aae189627faeaf9ce9f73a93f..c5ca4250a4522d61df40b3ad658e4cc330cbb211 100644 (file)
@@ -29,7 +29,7 @@
 #include <stdlib.h>
 #include "JSValue.h"
 #include "JSObject.h"
-#include "Nodes.h"
+#include "NodeConstructors.h"
 #include "Lexer.h"
 #include "JSString.h"
 #include "JSGlobalData.h"
@@ -80,7 +80,7 @@ static ExpressionNode* makeSubNode(void*, ExpressionNode*, ExpressionNode*, bool
 static ExpressionNode* makeLeftShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
 static ExpressionNode* makeRightShiftNode(void*, ExpressionNode*, ExpressionNode*, bool rightHasAssignments);
 static StatementNode* makeVarStatementNode(void*, ExpressionNode*);
-static ExpressionNode* combineVarInitializers(void*, ExpressionNode* list, AssignResolveNode* init);
+static ExpressionNode* combineCommaNodes(void*, ExpressionNode* list, ExpressionNode* init);
 
 #if COMPILER(MSVC)
 
@@ -99,24 +99,24 @@ static ExpressionNode* combineVarInitializers(void*, ExpressionNode* list, Assig
 #define YYPARSE_PARAM globalPtr
 #define YYLEX_PARAM globalPtr
 
-template <typename T> NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, ParserRefCountedData<DeclarationStacks::VarStack>* varDecls, 
-                                                                       ParserRefCountedData<DeclarationStacks::FunctionStack>* funcDecls,
+template <typename T> NodeDeclarationInfo<T> createNodeDeclarationInfo(T node, ParserArenaData<DeclarationStacks::VarStack>* varDecls, 
+                                                                       ParserArenaData<DeclarationStacks::FunctionStack>* funcDecls,
                                                                        CodeFeatures info,
                                                                        int numConstants) 
 {
     ASSERT((info & ~AllFeatures) == 0);
-    NodeDeclarationInfo<T> result = {node, varDecls, funcDecls, info, numConstants};
+    NodeDeclarationInfo<T> result = { node, varDecls, funcDecls, info, numConstants };
     return result;
 }
 
 template <typename T> NodeInfo<T> createNodeInfo(T node, CodeFeatures info, int numConstants)
 {
     ASSERT((info & ~AllFeatures) == 0);
-    NodeInfo<T> result = {node, info, numConstants};
+    NodeInfo<T> result = { node, info, numConstants };
     return result;
 }
 
-template <typename T> T mergeDeclarationLists(T decls1, T decls2) 
+template <typename T> inline T mergeDeclarationLists(T decls1, T decls2) 
 {
     // decls1 or both are null
     if (!decls1)
@@ -128,28 +128,28 @@ template <typename T> T mergeDeclarationLists(T decls1, T decls2)
     // Both are non-null
     decls1->data.append(decls2->data);
     
-    // We manually release the declaration lists to avoid accumulating many many
-    // unused heap allocated vectors
-    decls2->ref();
-    decls2->deref();
+    // Manually release as much as possible from the now-defunct declaration lists
+    // to avoid accumulating so many unused heap allocated vectors.
+    decls2->data.clear();
+
     return decls1;
 }
 
-static void appendToVarDeclarationList(void* globalPtr, ParserRefCountedData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs)
+static void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, const Identifier& ident, unsigned attrs)
 {
     if (!varDecls)
-        varDecls = new ParserRefCountedData<DeclarationStacks::VarStack>(GLOBAL_DATA);
+        varDecls = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
 
     varDecls->data.append(make_pair(ident, attrs));
 
 }
 
-static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl)
+static inline void appendToVarDeclarationList(void* globalPtr, ParserArenaData<DeclarationStacks::VarStack>*& varDecls, ConstDeclNode* decl)
 {
     unsigned attrs = DeclarationStacks::IsConstant;
-    if (decl->m_init)
+    if (decl->hasInitializer())
         attrs |= DeclarationStacks::HasInitializer;        
-    appendToVarDeclarationList(globalPtr, varDecls, decl->m_ident, attrs);
+    appendToVarDeclarationList(globalPtr, varDecls, decl->ident(), attrs);
 }
 
 %}
@@ -218,7 +218,7 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedD
 %token ANDEQUAL MODEQUAL           /* &= and %= */
 %token XOREQUAL OREQUAL            /* ^= and |= */
 %token <intValue> OPENBRACE        /* { (with char offset) */
-%token <intValue> CLOSEBRACE        /* { (with char offset) */
+%token <intValue> CLOSEBRACE       /* } (with char offset) */
 
 /* terminal types */
 %token <doubleValue> NUMBER
@@ -264,7 +264,7 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedD
 %type <expressionNode>  Initializer InitializerNoIn
 %type <statementNode>   FunctionDeclaration
 %type <funcExprNode>    FunctionExpr
-%type <functionBodyNode>  FunctionBody
+%type <functionBodyNode> FunctionBody
 %type <sourceElements>  SourceElements
 %type <parameterList>   FormalParameterList
 %type <op>              AssignmentOperator
@@ -287,16 +287,16 @@ static inline void appendToVarDeclarationList(void* globalPtr, ParserRefCountedD
 // In the mean time, make sure to make any changes to the grammar in both versions.
 
 Literal:
-    NULLTOKEN                           { $$ = createNodeInfo<ExpressionNode*>(new NullNode(GLOBAL_DATA), 0, 1); }
-  | TRUETOKEN                           { $$ = createNodeInfo<ExpressionNode*>(new BooleanNode(GLOBAL_DATA, true), 0, 1); }
-  | FALSETOKEN                          { $$ = createNodeInfo<ExpressionNode*>(new BooleanNode(GLOBAL_DATA, false), 0, 1); }
+    NULLTOKEN                           { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NullNode(GLOBAL_DATA), 0, 1); }
+  | TRUETOKEN                           { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BooleanNode(GLOBAL_DATA, true), 0, 1); }
+  | FALSETOKEN                          { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BooleanNode(GLOBAL_DATA, false), 0, 1); }
   | NUMBER                              { $$ = createNodeInfo<ExpressionNode*>(makeNumberNode(GLOBAL_DATA, $1), 0, 1); }
-  | STRING                              { $$ = createNodeInfo<ExpressionNode*>(new StringNode(GLOBAL_DATA, *$1), 0, 1); }
+  | STRING                              { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StringNode(GLOBAL_DATA, *$1), 0, 1); }
   | '/' /* regexp */                    {
                                             Lexer& l = *LEXER;
                                             if (!l.scanRegExp())
                                                 YYABORT;
-                                            RegExpNode* node = new RegExpNode(GLOBAL_DATA, l.pattern(), l.flags());
+                                            RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, l.pattern(), l.flags());
                                             int size = l.pattern().size() + 2; // + 2 for the two /'s
                                             SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size);
                                             $$ = createNodeInfo<ExpressionNode*>(node, 0, 0);
@@ -305,7 +305,7 @@ Literal:
                                             Lexer& l = *LEXER;
                                             if (!l.scanRegExp())
                                                 YYABORT;
-                                            RegExpNode* node = new RegExpNode(GLOBAL_DATA, "=" + l.pattern(), l.flags());
+                                            RegExpNode* node = new (GLOBAL_DATA) RegExpNode(GLOBAL_DATA, "=" + l.pattern(), l.flags());
                                             int size = l.pattern().size() + 2; // + 2 for the two /'s
                                             SET_EXCEPTION_LOCATION(node, @1.first_column, @1.first_column + size, @1.first_column + size);
                                             $$ = createNodeInfo<ExpressionNode*>(node, 0, 0);
@@ -313,9 +313,9 @@ Literal:
 ;
 
 Property:
-    IDENT ':' AssignmentExpr            { $$ = createNodeInfo<PropertyNode*>(new PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
-  | STRING ':' AssignmentExpr           { $$ = createNodeInfo<PropertyNode*>(new PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
-  | NUMBER ':' AssignmentExpr           { $$ = createNodeInfo<PropertyNode*>(new PropertyNode(GLOBAL_DATA, Identifier(GLOBAL_DATA, UString::from($1)), $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
+    IDENT ':' AssignmentExpr            { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
+  | STRING ':' AssignmentExpr           { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, *$1, $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
+  | NUMBER ':' AssignmentExpr           { $$ = createNodeInfo<PropertyNode*>(new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, Identifier(GLOBAL_DATA, UString::from($1)), $3.m_node, PropertyNode::Constant), $3.m_features, $3.m_numConstants); }
   | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE    { $$ = createNodeInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(globalPtr, *$1, *$2, 0, $6, LEXER->sourceCode($5, $7, @5.first_line)), ClosureFeature, 0); DBG($6, @5, @7); if (!$$.m_node) YYABORT; }
   | IDENT IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
                                                              {
@@ -329,46 +329,46 @@ Property:
 ;
 
 PropertyList:
-    Property                            { $$.m_node.head = new PropertyListNode(GLOBAL_DATA, $1.m_node); 
+    Property                            { $$.m_node.head = new (GLOBAL_DATA) PropertyListNode(GLOBAL_DATA, $1.m_node); 
                                           $$.m_node.tail = $$.m_node.head;
                                           $$.m_features = $1.m_features;
                                           $$.m_numConstants = $1.m_numConstants; }
   | PropertyList ',' Property           { $$.m_node.head = $1.m_node.head;
-                                          $$.m_node.tail = new PropertyListNode(GLOBAL_DATA, $3.m_node, $1.m_node.tail);
+                                          $$.m_node.tail = new (GLOBAL_DATA) PropertyListNode(GLOBAL_DATA, $3.m_node, $1.m_node.tail);
                                           $$.m_features = $1.m_features | $3.m_features;
                                           $$.m_numConstants = $1.m_numConstants + $3.m_numConstants; }
 ;
 
 PrimaryExpr:
     PrimaryExprNoBrace
-  | OPENBRACE CLOSEBRACE                             { $$ = createNodeInfo<ExpressionNode*>(new ObjectLiteralNode(GLOBAL_DATA), 0, 0); }
-  | OPENBRACE PropertyList CLOSEBRACE                { $$ = createNodeInfo<ExpressionNode*>(new ObjectLiteralNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); }
+  | OPENBRACE CLOSEBRACE                             { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA), 0, 0); }
+  | OPENBRACE PropertyList CLOSEBRACE                { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); }
   /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */
-  | OPENBRACE PropertyList ',' CLOSEBRACE            { $$ = createNodeInfo<ExpressionNode*>(new ObjectLiteralNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); }
+  | OPENBRACE PropertyList ',' CLOSEBRACE            { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ObjectLiteralNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); }
 ;
 
 PrimaryExprNoBrace:
-    THISTOKEN                           { $$ = createNodeInfo<ExpressionNode*>(new ThisNode(GLOBAL_DATA), ThisFeature, 0); }
+    THISTOKEN                           { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ThisNode(GLOBAL_DATA), ThisFeature, 0); }
   | Literal
   | ArrayLiteral
-  | IDENT                               { $$ = createNodeInfo<ExpressionNode*>(new ResolveNode(GLOBAL_DATA, *$1, @1.first_column), (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); }
+  | IDENT                               { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ResolveNode(GLOBAL_DATA, *$1, @1.first_column), (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); }
   | '(' Expr ')'                        { $$ = $2; }
 ;
 
 ArrayLiteral:
-    '[' ElisionOpt ']'                  { $$ = createNodeInfo<ExpressionNode*>(new ArrayNode(GLOBAL_DATA, $2), 0, $2 ? 1 : 0); }
-  | '[' ElementList ']'                 { $$ = createNodeInfo<ExpressionNode*>(new ArrayNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); }
-  | '[' ElementList ',' ElisionOpt ']'  { $$ = createNodeInfo<ExpressionNode*>(new ArrayNode(GLOBAL_DATA, $4, $2.m_node.head), $2.m_features, $4 ? $2.m_numConstants + 1 : $2.m_numConstants); }
+    '[' ElisionOpt ']'                  { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, $2), 0, $2 ? 1 : 0); }
+  | '[' ElementList ']'                 { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); }
+  | '[' ElementList ',' ElisionOpt ']'  { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ArrayNode(GLOBAL_DATA, $4, $2.m_node.head), $2.m_features, $4 ? $2.m_numConstants + 1 : $2.m_numConstants); }
 ;
 
 ElementList:
-    ElisionOpt AssignmentExpr           { $$.m_node.head = new ElementNode(GLOBAL_DATA, $1, $2.m_node);
+    ElisionOpt AssignmentExpr           { $$.m_node.head = new (GLOBAL_DATA) ElementNode(GLOBAL_DATA, $1, $2.m_node);
                                           $$.m_node.tail = $$.m_node.head;
                                           $$.m_features = $2.m_features;
                                           $$.m_numConstants = $2.m_numConstants; }
   | ElementList ',' ElisionOpt AssignmentExpr
                                         { $$.m_node.head = $1.m_node.head;
-                                          $$.m_node.tail = new ElementNode(GLOBAL_DATA, $1.m_node.tail, $3, $4.m_node);
+                                          $$.m_node.tail = new (GLOBAL_DATA) ElementNode(GLOBAL_DATA, $1.m_node.tail, $3, $4.m_node);
                                           $$.m_features = $1.m_features | $4.m_features;
                                           $$.m_numConstants = $1.m_numConstants + $4.m_numConstants; }
 ;
@@ -386,15 +386,15 @@ Elision:
 MemberExpr:
     PrimaryExpr
   | FunctionExpr                        { $$ = createNodeInfo<ExpressionNode*>($1.m_node, $1.m_features, $1.m_numConstants); }
-  | MemberExpr '[' Expr ']'             { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
+  | MemberExpr '[' Expr ']'             { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); 
                                         }
-  | MemberExpr '.' IDENT                { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3);
+  | MemberExpr '.' IDENT                { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants);
                                         }
-  | NEW MemberExpr Arguments            { NewExprNode* node = new NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node);
+  | NEW MemberExpr Arguments            { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @3.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features | $3.m_features, $2.m_numConstants + $3.m_numConstants);
                                         }
@@ -402,15 +402,15 @@ MemberExpr:
 
 MemberExprNoBF:
     PrimaryExprNoBrace
-  | MemberExprNoBF '[' Expr ']'         { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
+  | MemberExprNoBF '[' Expr ']'         { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); 
                                         }
-  | MemberExprNoBF '.' IDENT            { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3);
+  | MemberExprNoBF '.' IDENT            { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants);
                                         }
-  | NEW MemberExpr Arguments            { NewExprNode* node = new NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node);
+  | NEW MemberExpr Arguments            { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node, $3.m_node);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @3.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features | $3.m_features, $2.m_numConstants + $3.m_numConstants);
                                         }
@@ -418,7 +418,7 @@ MemberExprNoBF:
 
 NewExpr:
     MemberExpr
-  | NEW NewExpr                         { NewExprNode* node = new NewExprNode(GLOBAL_DATA, $2.m_node);
+  | NEW NewExpr                         { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants); 
                                         }
@@ -426,7 +426,7 @@ NewExpr:
 
 NewExprNoBF:
     MemberExprNoBF
-  | NEW NewExpr                         { NewExprNode* node = new NewExprNode(GLOBAL_DATA, $2.m_node);
+  | NEW NewExpr                         { NewExprNode* node = new (GLOBAL_DATA) NewExprNode(GLOBAL_DATA, $2.m_node);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $2.m_features, $2.m_numConstants);
                                         }
@@ -435,11 +435,11 @@ NewExprNoBF:
 CallExpr:
     MemberExpr Arguments                { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
   | CallExpr Arguments                  { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
-  | CallExpr '[' Expr ']'               { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
+  | CallExpr '[' Expr ']'               { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); 
                                         }
-  | CallExpr '.' IDENT                  { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3);
+  | CallExpr '.' IDENT                  { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); }
 ;
@@ -447,28 +447,28 @@ CallExpr:
 CallExprNoBF:
     MemberExprNoBF Arguments            { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
   | CallExprNoBF Arguments              { $$ = makeFunctionCallNode(globalPtr, $1, $2, @1.first_column, @1.last_column, @2.last_column); }
-  | CallExprNoBF '[' Expr ']'           { BracketAccessorNode* node = new BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
+  | CallExprNoBF '[' Expr ']'           { BracketAccessorNode* node = new (GLOBAL_DATA) BracketAccessorNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @4.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); 
                                         }
-  | CallExprNoBF '.' IDENT              { DotAccessorNode* node = new DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3);
+  | CallExprNoBF '.' IDENT              { DotAccessorNode* node = new (GLOBAL_DATA) DotAccessorNode(GLOBAL_DATA, $1.m_node, *$3);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @3.last_column);
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features, $1.m_numConstants); 
                                         }
 ;
 
 Arguments:
-    '(' ')'                             { $$ = createNodeInfo<ArgumentsNode*>(new ArgumentsNode(GLOBAL_DATA), 0, 0); }
-  | '(' ArgumentList ')'                { $$ = createNodeInfo<ArgumentsNode*>(new ArgumentsNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); }
+    '(' ')'                             { $$ = createNodeInfo<ArgumentsNode*>(new (GLOBAL_DATA) ArgumentsNode(GLOBAL_DATA), 0, 0); }
+  | '(' ArgumentList ')'                { $$ = createNodeInfo<ArgumentsNode*>(new (GLOBAL_DATA) ArgumentsNode(GLOBAL_DATA, $2.m_node.head), $2.m_features, $2.m_numConstants); }
 ;
 
 ArgumentList:
-    AssignmentExpr                      { $$.m_node.head = new ArgumentListNode(GLOBAL_DATA, $1.m_node);
+    AssignmentExpr                      { $$.m_node.head = new (GLOBAL_DATA) ArgumentListNode(GLOBAL_DATA, $1.m_node);
                                           $$.m_node.tail = $$.m_node.head;
                                           $$.m_features = $1.m_features;
                                           $$.m_numConstants = $1.m_numConstants; }
   | ArgumentList ',' AssignmentExpr     { $$.m_node.head = $1.m_node.head;
-                                          $$.m_node.tail = new ArgumentListNode(GLOBAL_DATA, $1.m_node.tail, $3.m_node);
+                                          $$.m_node.tail = new (GLOBAL_DATA) ArgumentListNode(GLOBAL_DATA, $1.m_node.tail, $3.m_node);
                                           $$.m_features = $1.m_features | $3.m_features;
                                           $$.m_numConstants = $1.m_numConstants + $3.m_numConstants; }
 ;
@@ -497,16 +497,16 @@ PostfixExprNoBF:
 
 UnaryExprCommon:
     DELETETOKEN UnaryExpr               { $$ = createNodeInfo<ExpressionNode*>(makeDeleteNode(GLOBAL_DATA, $2.m_node, @1.first_column, @2.last_column, @2.last_column), $2.m_features, $2.m_numConstants); }
-  | VOIDTOKEN UnaryExpr                 { $$ = createNodeInfo<ExpressionNode*>(new VoidNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants + 1); }
+  | VOIDTOKEN UnaryExpr                 { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) VoidNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants + 1); }
   | TYPEOF UnaryExpr                    { $$ = createNodeInfo<ExpressionNode*>(makeTypeOfNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); }
   | PLUSPLUS UnaryExpr                  { $$ = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, $2.m_node, OpPlusPlus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_features | AssignFeature, $2.m_numConstants); }
   | AUTOPLUSPLUS UnaryExpr              { $$ = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, $2.m_node, OpPlusPlus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_features | AssignFeature, $2.m_numConstants); }
   | MINUSMINUS UnaryExpr                { $$ = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, $2.m_node, OpMinusMinus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_features | AssignFeature, $2.m_numConstants); }
   | AUTOMINUSMINUS UnaryExpr            { $$ = createNodeInfo<ExpressionNode*>(makePrefixNode(GLOBAL_DATA, $2.m_node, OpMinusMinus, @1.first_column, @2.first_column + 1, @2.last_column), $2.m_features | AssignFeature, $2.m_numConstants); }
-  | '+' UnaryExpr                       { $$ = createNodeInfo<ExpressionNode*>(new UnaryPlusNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); }
+  | '+' UnaryExpr                       { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); }
   | '-' UnaryExpr                       { $$ = createNodeInfo<ExpressionNode*>(makeNegateNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); }
   | '~' UnaryExpr                       { $$ = createNodeInfo<ExpressionNode*>(makeBitwiseNotNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); }
-  | '!' UnaryExpr                       { $$ = createNodeInfo<ExpressionNode*>(new LogicalNotNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); }
+  | '!' UnaryExpr                       { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalNotNode(GLOBAL_DATA, $2.m_node), $2.m_features, $2.m_numConstants); }
 
 UnaryExpr:
     PostfixExpr
@@ -522,7 +522,7 @@ MultiplicativeExpr:
     UnaryExpr
   | MultiplicativeExpr '*' UnaryExpr    { $$ = createNodeInfo<ExpressionNode*>(makeMultNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | MultiplicativeExpr '/' UnaryExpr    { $$ = createNodeInfo<ExpressionNode*>(makeDivNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | MultiplicativeExpr '%' UnaryExpr    { $$ = createNodeInfo<ExpressionNode*>(new ModNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | MultiplicativeExpr '%' UnaryExpr    { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ModNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 MultiplicativeExprNoBF:
@@ -532,7 +532,7 @@ MultiplicativeExprNoBF:
   | MultiplicativeExprNoBF '/' UnaryExpr
                                         { $$ = createNodeInfo<ExpressionNode*>(makeDivNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | MultiplicativeExprNoBF '%' UnaryExpr
-                                        { $$ = createNodeInfo<ExpressionNode*>(new ModNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ModNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 AdditiveExpr:
@@ -553,188 +553,188 @@ ShiftExpr:
     AdditiveExpr
   | ShiftExpr LSHIFT AdditiveExpr       { $$ = createNodeInfo<ExpressionNode*>(makeLeftShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | ShiftExpr RSHIFT AdditiveExpr       { $$ = createNodeInfo<ExpressionNode*>(makeRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | ShiftExpr URSHIFT AdditiveExpr      { $$ = createNodeInfo<ExpressionNode*>(new UnsignedRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | ShiftExpr URSHIFT AdditiveExpr      { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnsignedRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 ShiftExprNoBF:
     AdditiveExprNoBF
   | ShiftExprNoBF LSHIFT AdditiveExpr   { $$ = createNodeInfo<ExpressionNode*>(makeLeftShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | ShiftExprNoBF RSHIFT AdditiveExpr   { $$ = createNodeInfo<ExpressionNode*>(makeRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | ShiftExprNoBF URSHIFT AdditiveExpr  { $$ = createNodeInfo<ExpressionNode*>(new UnsignedRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | ShiftExprNoBF URSHIFT AdditiveExpr  { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) UnsignedRightShiftNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 RelationalExpr:
     ShiftExpr
-  | RelationalExpr '<' ShiftExpr        { $$ = createNodeInfo<ExpressionNode*>(new LessNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExpr '>' ShiftExpr        { $$ = createNodeInfo<ExpressionNode*>(new GreaterNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExpr LE ShiftExpr         { $$ = createNodeInfo<ExpressionNode*>(new LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExpr GE ShiftExpr         { $$ = createNodeInfo<ExpressionNode*>(new GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExpr INSTANCEOF ShiftExpr { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
+  | RelationalExpr '<' ShiftExpr        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExpr '>' ShiftExpr        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExpr LE ShiftExpr         { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExpr GE ShiftExpr         { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExpr INSTANCEOF ShiftExpr { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column);  
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExpr INTOKEN ShiftExpr    { InNode* node = new InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
+  | RelationalExpr INTOKEN ShiftExpr    { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column);  
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 RelationalExprNoIn:
     ShiftExpr
-  | RelationalExprNoIn '<' ShiftExpr    { $$ = createNodeInfo<ExpressionNode*>(new LessNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExprNoIn '>' ShiftExpr    { $$ = createNodeInfo<ExpressionNode*>(new GreaterNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExprNoIn LE ShiftExpr     { $$ = createNodeInfo<ExpressionNode*>(new LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExprNoIn GE ShiftExpr     { $$ = createNodeInfo<ExpressionNode*>(new GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExprNoIn '<' ShiftExpr    { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExprNoIn '>' ShiftExpr    { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExprNoIn LE ShiftExpr     { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExprNoIn GE ShiftExpr     { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | RelationalExprNoIn INSTANCEOF ShiftExpr
-                                        { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
+                                        { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column);  
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 RelationalExprNoBF:
     ShiftExprNoBF
-  | RelationalExprNoBF '<' ShiftExpr    { $$ = createNodeInfo<ExpressionNode*>(new LessNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExprNoBF '>' ShiftExpr    { $$ = createNodeInfo<ExpressionNode*>(new GreaterNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExprNoBF LE ShiftExpr     { $$ = createNodeInfo<ExpressionNode*>(new LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | RelationalExprNoBF GE ShiftExpr     { $$ = createNodeInfo<ExpressionNode*>(new GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExprNoBF '<' ShiftExpr    { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExprNoBF '>' ShiftExpr    { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExprNoBF LE ShiftExpr     { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LessEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | RelationalExprNoBF GE ShiftExpr     { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) GreaterEqNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | RelationalExprNoBF INSTANCEOF ShiftExpr
-                                        { InstanceOfNode* node = new InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
+                                        { InstanceOfNode* node = new (GLOBAL_DATA) InstanceOfNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column);  
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | RelationalExprNoBF INTOKEN ShiftExpr 
-                                        { InNode* node = new InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
+                                        { InNode* node = new (GLOBAL_DATA) InNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @3.first_column, @3.last_column);  
                                           $$ = createNodeInfo<ExpressionNode*>(node, $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 EqualityExpr:
     RelationalExpr
-  | EqualityExpr EQEQ RelationalExpr    { $$ = createNodeInfo<ExpressionNode*>(new EqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | EqualityExpr NE RelationalExpr      { $$ = createNodeInfo<ExpressionNode*>(new NotEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | EqualityExpr STREQ RelationalExpr   { $$ = createNodeInfo<ExpressionNode*>(new StrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | EqualityExpr STRNEQ RelationalExpr  { $$ = createNodeInfo<ExpressionNode*>(new NotStrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | EqualityExpr EQEQ RelationalExpr    { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | EqualityExpr NE RelationalExpr      { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | EqualityExpr STREQ RelationalExpr   { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | EqualityExpr STRNEQ RelationalExpr  { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 EqualityExprNoIn:
     RelationalExprNoIn
   | EqualityExprNoIn EQEQ RelationalExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new EqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | EqualityExprNoIn NE RelationalExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new NotEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | EqualityExprNoIn STREQ RelationalExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new StrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | EqualityExprNoIn STRNEQ RelationalExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new NotStrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 EqualityExprNoBF:
     RelationalExprNoBF
   | EqualityExprNoBF EQEQ RelationalExpr
-                                        { $$ = createNodeInfo<ExpressionNode*>(new EqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
-  | EqualityExprNoBF NE RelationalExpr  { $$ = createNodeInfo<ExpressionNode*>(new NotEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | EqualityExprNoBF NE RelationalExpr  { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | EqualityExprNoBF STREQ RelationalExpr
-                                        { $$ = createNodeInfo<ExpressionNode*>(new StrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) StrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
   | EqualityExprNoBF STRNEQ RelationalExpr
-                                        { $$ = createNodeInfo<ExpressionNode*>(new NotStrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) NotStrictEqualNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 BitwiseANDExpr:
     EqualityExpr
-  | BitwiseANDExpr '&' EqualityExpr     { $$ = createNodeInfo<ExpressionNode*>(new BitAndNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | BitwiseANDExpr '&' EqualityExpr     { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 BitwiseANDExprNoIn:
     EqualityExprNoIn
   | BitwiseANDExprNoIn '&' EqualityExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new BitAndNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 BitwiseANDExprNoBF:
     EqualityExprNoBF
-  | BitwiseANDExprNoBF '&' EqualityExpr { $$ = createNodeInfo<ExpressionNode*>(new BitAndNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | BitwiseANDExprNoBF '&' EqualityExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitAndNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 BitwiseXORExpr:
     BitwiseANDExpr
-  | BitwiseXORExpr '^' BitwiseANDExpr   { $$ = createNodeInfo<ExpressionNode*>(new BitXOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | BitwiseXORExpr '^' BitwiseANDExpr   { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 BitwiseXORExprNoIn:
     BitwiseANDExprNoIn
   | BitwiseXORExprNoIn '^' BitwiseANDExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new BitXOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 BitwiseXORExprNoBF:
     BitwiseANDExprNoBF
   | BitwiseXORExprNoBF '^' BitwiseANDExpr
-                                        { $$ = createNodeInfo<ExpressionNode*>(new BitXOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitXOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 BitwiseORExpr:
     BitwiseXORExpr
-  | BitwiseORExpr '|' BitwiseXORExpr    { $$ = createNodeInfo<ExpressionNode*>(new BitOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | BitwiseORExpr '|' BitwiseXORExpr    { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 BitwiseORExprNoIn:
     BitwiseXORExprNoIn
   | BitwiseORExprNoIn '|' BitwiseXORExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new BitOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 BitwiseORExprNoBF:
     BitwiseXORExprNoBF
   | BitwiseORExprNoBF '|' BitwiseXORExpr
-                                        { $$ = createNodeInfo<ExpressionNode*>(new BitOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) BitOrNode(GLOBAL_DATA, $1.m_node, $3.m_node, $3.m_features & AssignFeature), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 LogicalANDExpr:
     BitwiseORExpr
-  | LogicalANDExpr AND BitwiseORExpr    { $$ = createNodeInfo<ExpressionNode*>(new LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalAnd), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | LogicalANDExpr AND BitwiseORExpr    { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalAnd), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 LogicalANDExprNoIn:
     BitwiseORExprNoIn
   | LogicalANDExprNoIn AND BitwiseORExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalAnd), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalAnd), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 LogicalANDExprNoBF:
     BitwiseORExprNoBF
   | LogicalANDExprNoBF AND BitwiseORExpr
-                                        { $$ = createNodeInfo<ExpressionNode*>(new LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalAnd), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalAnd), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 LogicalORExpr:
     LogicalANDExpr
-  | LogicalORExpr OR LogicalANDExpr     { $$ = createNodeInfo<ExpressionNode*>(new LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalOr), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | LogicalORExpr OR LogicalANDExpr     { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalOr), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 LogicalORExprNoIn:
     LogicalANDExprNoIn
   | LogicalORExprNoIn OR LogicalANDExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalOr), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalOr), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 LogicalORExprNoBF:
     LogicalANDExprNoBF
-  | LogicalORExprNoBF OR LogicalANDExpr { $$ = createNodeInfo<ExpressionNode*>(new LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalOr), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | LogicalORExprNoBF OR LogicalANDExpr { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) LogicalOpNode(GLOBAL_DATA, $1.m_node, $3.m_node, OpLogicalOr), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 ConditionalExpr:
     LogicalORExpr
   | LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr
-                                        { $$ = createNodeInfo<ExpressionNode*>(new ConditionalNode(GLOBAL_DATA, $1.m_node, $3.m_node, $5.m_node), $1.m_features | $3.m_features | $5.m_features, $1.m_numConstants + $3.m_numConstants + $5.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, $1.m_node, $3.m_node, $5.m_node), $1.m_features | $3.m_features | $5.m_features, $1.m_numConstants + $3.m_numConstants + $5.m_numConstants); }
 ;
 
 ConditionalExprNoIn:
     LogicalORExprNoIn
   | LogicalORExprNoIn '?' AssignmentExprNoIn ':' AssignmentExprNoIn
-                                        { $$ = createNodeInfo<ExpressionNode*>(new ConditionalNode(GLOBAL_DATA, $1.m_node, $3.m_node, $5.m_node), $1.m_features | $3.m_features | $5.m_features, $1.m_numConstants + $3.m_numConstants + $5.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, $1.m_node, $3.m_node, $5.m_node), $1.m_features | $3.m_features | $5.m_features, $1.m_numConstants + $3.m_numConstants + $5.m_numConstants); }
 ;
 
 ConditionalExprNoBF:
     LogicalORExprNoBF
   | LogicalORExprNoBF '?' AssignmentExpr ':' AssignmentExpr
-                                        { $$ = createNodeInfo<ExpressionNode*>(new ConditionalNode(GLOBAL_DATA, $1.m_node, $3.m_node, $5.m_node), $1.m_features | $3.m_features | $5.m_features, $1.m_numConstants + $3.m_numConstants + $5.m_numConstants); }
+                                        { $$ = createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) ConditionalNode(GLOBAL_DATA, $1.m_node, $3.m_node, $5.m_node), $1.m_features | $3.m_features | $5.m_features, $1.m_numConstants + $3.m_numConstants + $5.m_numConstants); }
 ;
 
 AssignmentExpr:
@@ -778,17 +778,17 @@ AssignmentOperator:
 
 Expr:
     AssignmentExpr
-  | Expr ',' AssignmentExpr             { $$ = createNodeInfo<ExpressionNode*>(new CommaNode(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | Expr ',' AssignmentExpr             { $$ = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 ExprNoIn:
     AssignmentExprNoIn
-  | ExprNoIn ',' AssignmentExprNoIn     { $$ = createNodeInfo<ExpressionNode*>(new CommaNode(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | ExprNoIn ',' AssignmentExprNoIn     { $$ = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 ExprNoBF:
     AssignmentExprNoBF
-  | ExprNoBF ',' AssignmentExpr         { $$ = createNodeInfo<ExpressionNode*>(new CommaNode(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
+  | ExprNoBF ',' AssignmentExpr         { $$ = createNodeInfo<ExpressionNode*>(combineCommaNodes(GLOBAL_DATA, $1.m_node, $3.m_node), $1.m_features | $3.m_features, $1.m_numConstants + $3.m_numConstants); }
 ;
 
 Statement:
@@ -812,9 +812,9 @@ Statement:
 ;
 
 Block:
-    OPENBRACE CLOSEBRACE                             { $$ = createNodeDeclarationInfo<StatementNode*>(new BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0);
+    OPENBRACE CLOSEBRACE                             { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, 0), 0, 0, 0, 0);
                                           DBG($$.m_node, @1, @2); }
-  | OPENBRACE SourceElements CLOSEBRACE              { $$ = createNodeDeclarationInfo<StatementNode*>(new BlockNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants);
+  | OPENBRACE SourceElements CLOSEBRACE              { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BlockNode(GLOBAL_DATA, $2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants);
                                           DBG($$.m_node, @1, @3); }
 ;
 
@@ -828,16 +828,16 @@ VariableStatement:
 
 VariableDeclarationList:
     IDENT                               { $$.m_node = 0;
-                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>(GLOBAL_DATA);
+                                          $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
                                           appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, 0);
                                           $$.m_funcDeclarations = 0;
                                           $$.m_features = (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0;
                                           $$.m_numConstants = 0;
                                         }
-  | IDENT Initializer                   { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature);
+  | IDENT Initializer                   { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.first_column + 1, @2.last_column);
                                           $$.m_node = node;
-                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>(GLOBAL_DATA);
+                                          $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
                                           appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer);
                                           $$.m_funcDeclarations = 0;
                                           $$.m_features = ((*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $2.m_features;
@@ -852,9 +852,9 @@ VariableDeclarationList:
                                           $$.m_numConstants = $1.m_numConstants;
                                         }
   | VariableDeclarationList ',' IDENT Initializer
-                                        { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature);
+                                        { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column);
-                                          $$.m_node = combineVarInitializers(GLOBAL_DATA, $1.m_node, node);
+                                          $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node);
                                           $$.m_varDeclarations = $1.m_varDeclarations;
                                           appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer);
                                           $$.m_funcDeclarations = 0;
@@ -865,16 +865,16 @@ VariableDeclarationList:
 
 VariableDeclarationListNoIn:
     IDENT                               { $$.m_node = 0;
-                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>(GLOBAL_DATA);
+                                          $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
                                           appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, 0);
                                           $$.m_funcDeclarations = 0;
                                           $$.m_features = (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0;
                                           $$.m_numConstants = 0;
                                         }
-  | IDENT InitializerNoIn               { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature);
+  | IDENT InitializerNoIn               { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$1, $2.m_node, $2.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.first_column + 1, @2.last_column);
                                           $$.m_node = node;
-                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>(GLOBAL_DATA);
+                                          $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
                                           appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer);
                                           $$.m_funcDeclarations = 0;
                                           $$.m_features = ((*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $2.m_features;
@@ -889,9 +889,9 @@ VariableDeclarationListNoIn:
                                           $$.m_numConstants = $1.m_numConstants;
                                         }
   | VariableDeclarationListNoIn ',' IDENT InitializerNoIn
-                                        { AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature);
+                                        { AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, *$3, $4.m_node, $4.m_features & AssignFeature);
                                           SET_EXCEPTION_LOCATION(node, @3.first_column, @4.first_column + 1, @4.last_column);
-                                          $$.m_node = combineVarInitializers(GLOBAL_DATA, $1.m_node, node);
+                                          $$.m_node = combineCommaNodes(GLOBAL_DATA, $1.m_node, node);
                                           $$.m_varDeclarations = $1.m_varDeclarations;
                                           appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer);
                                           $$.m_funcDeclarations = 0;
@@ -901,24 +901,24 @@ VariableDeclarationListNoIn:
 ;
 
 ConstStatement:
-    CONSTTOKEN ConstDeclarationList ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants);
+    CONSTTOKEN ConstDeclarationList ';' { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants);
                                           DBG($$.m_node, @1, @3); }
   | CONSTTOKEN ConstDeclarationList error
-                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants);
+                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ConstStatementNode(GLOBAL_DATA, $2.m_node.head), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants);
                                           DBG($$.m_node, @1, @2); AUTO_SEMICOLON; }
 ;
 
 ConstDeclarationList:
     ConstDeclaration                    { $$.m_node.head = $1.m_node;
                                           $$.m_node.tail = $$.m_node.head;
-                                          $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>(GLOBAL_DATA);
+                                          $$.m_varDeclarations = new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::VarStack>;
                                           appendToVarDeclarationList(GLOBAL_DATA, $$.m_varDeclarations, $1.m_node);
                                           $$.m_funcDeclarations = 0; 
                                           $$.m_features = $1.m_features;
                                           $$.m_numConstants = $1.m_numConstants;
     }
   | ConstDeclarationList ',' ConstDeclaration
-                                        {  $$.m_node.head = $1.m_node.head;
+                                        { $$.m_node.head = $1.m_node.head;
                                           $1.m_node.tail->m_next = $3.m_node;
                                           $$.m_node.tail = $3.m_node;
                                           $$.m_varDeclarations = $1.m_varDeclarations;
@@ -929,8 +929,8 @@ ConstDeclarationList:
 ;
 
 ConstDeclaration:
-    IDENT                               { $$ = createNodeInfo<ConstDeclNode*>(new ConstDeclNode(GLOBAL_DATA, *$1, 0), (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); }
-  | IDENT Initializer                   { $$ = createNodeInfo<ConstDeclNode*>(new ConstDeclNode(GLOBAL_DATA, *$1, $2.m_node), ((*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $2.m_features, $2.m_numConstants); }
+    IDENT                               { $$ = createNodeInfo<ConstDeclNode*>(new (GLOBAL_DATA) ConstDeclNode(GLOBAL_DATA, *$1, 0), (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0, 0); }
+  | IDENT Initializer                   { $$ = createNodeInfo<ConstDeclNode*>(new (GLOBAL_DATA) ConstDeclNode(GLOBAL_DATA, *$1, $2.m_node), ((*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $2.m_features, $2.m_numConstants); }
 ;
 
 Initializer:
@@ -942,43 +942,44 @@ InitializerNoIn:
 ;
 
 EmptyStatement:
-    ';'                                 { $$ = createNodeDeclarationInfo<StatementNode*>(new EmptyStatementNode(GLOBAL_DATA), 0, 0, 0, 0); }
+    ';'                                 { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA), 0, 0, 0, 0); }
 ;
 
 ExprStatement:
-    ExprNoBF ';'                        { $$ = createNodeDeclarationInfo<StatementNode*>(new ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants);
+    ExprNoBF ';'                        { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants);
                                           DBG($$.m_node, @1, @2); }
-  | ExprNoBF error                      { $$ = createNodeDeclarationInfo<StatementNode*>(new ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants);
+  | ExprNoBF error                      { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ExprStatementNode(GLOBAL_DATA, $1.m_node), 0, 0, $1.m_features, $1.m_numConstants);
                                           DBG($$.m_node, @1, @1); AUTO_SEMICOLON; }
 ;
 
 IfStatement:
     IF '(' Expr ')' Statement %prec IF_WITHOUT_ELSE
-                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new IfNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants);
+                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants);
                                           DBG($$.m_node, @1, @4); }
   | IF '(' Expr ')' Statement ELSE Statement
-                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new IfElseNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node), 
-                                                                                         mergeDeclarationLists($5.m_varDeclarations, $7.m_varDeclarations), mergeDeclarationLists($5.m_funcDeclarations, $7.m_funcDeclarations),
+                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) IfElseNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node), 
+                                                                                         mergeDeclarationLists($5.m_varDeclarations, $7.m_varDeclarations),
+                                                                                         mergeDeclarationLists($5.m_funcDeclarations, $7.m_funcDeclarations),
                                                                                          $3.m_features | $5.m_features | $7.m_features,
                                                                                          $3.m_numConstants + $5.m_numConstants + $7.m_numConstants); 
                                           DBG($$.m_node, @1, @4); }
 ;
 
 IterationStatement:
-    DO Statement WHILE '(' Expr ')' ';'    { $$ = createNodeDeclarationInfo<StatementNode*>(new DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants);
+    DO Statement WHILE '(' Expr ')' ';'    { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants);
                                              DBG($$.m_node, @1, @3); }
-  | DO Statement WHILE '(' Expr ')' error  { $$ = createNodeDeclarationInfo<StatementNode*>(new DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants);
+  | DO Statement WHILE '(' Expr ')' error  { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DoWhileNode(GLOBAL_DATA, $2.m_node, $5.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features | $5.m_features, $2.m_numConstants + $5.m_numConstants);
                                              DBG($$.m_node, @1, @3); } // Always performs automatic semicolon insertion.
-  | WHILE '(' Expr ')' Statement        { $$ = createNodeDeclarationInfo<StatementNode*>(new WhileNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants);
+  | WHILE '(' Expr ')' Statement        { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WhileNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants);
                                           DBG($$.m_node, @1, @4); }
   | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement
-                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new ForNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node, $9.m_node, false), $9.m_varDeclarations, $9.m_funcDeclarations, 
+                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node, $9.m_node, false), $9.m_varDeclarations, $9.m_funcDeclarations, 
                                                                                          $3.m_features | $5.m_features | $7.m_features | $9.m_features,
                                                                                          $3.m_numConstants + $5.m_numConstants + $7.m_numConstants + $9.m_numConstants);
                                           DBG($$.m_node, @1, @8); 
                                         }
   | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement
-                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new ForNode(GLOBAL_DATA, $4.m_node, $6.m_node, $8.m_node, $10.m_node, true),
+                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) ForNode(GLOBAL_DATA, $4.m_node, $6.m_node, $8.m_node, $10.m_node, true),
                                                                                          mergeDeclarationLists($4.m_varDeclarations, $10.m_varDeclarations),
                                                                                          mergeDeclarationLists($4.m_funcDeclarations, $10.m_funcDeclarations),
                                                                                          $4.m_features | $6.m_features | $8.m_features | $10.m_features,
@@ -986,7 +987,7 @@ IterationStatement:
                                           DBG($$.m_node, @1, @9); }
   | FOR '(' LeftHandSideExpr INTOKEN Expr ')' Statement
                                         {
-                                            ForInNode* node = new ForInNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node);
+                                            ForInNode* node = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, $3.m_node, $5.m_node, $7.m_node);
                                             SET_EXCEPTION_LOCATION(node, @3.first_column, @3.last_column, @5.last_column);
                                             $$ = createNodeDeclarationInfo<StatementNode*>(node, $7.m_varDeclarations, $7.m_funcDeclarations,
                                                                                            $3.m_features | $5.m_features | $7.m_features,
@@ -994,13 +995,13 @@ IterationStatement:
                                             DBG($$.m_node, @1, @6);
                                         }
   | FOR '(' VAR IDENT INTOKEN Expr ')' Statement
-                                        { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *$4, 0, $6.m_node, $8.m_node, @5.first_column, @5.first_column - @4.first_column, @6.last_column - @5.first_column);
+                                        { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *$4, 0, $6.m_node, $8.m_node, @5.first_column, @5.first_column - @4.first_column, @6.last_column - @5.first_column);
                                           SET_EXCEPTION_LOCATION(forIn, @4.first_column, @5.first_column + 1, @6.last_column);
                                           appendToVarDeclarationList(GLOBAL_DATA, $8.m_varDeclarations, *$4, DeclarationStacks::HasInitializer);
                                           $$ = createNodeDeclarationInfo<StatementNode*>(forIn, $8.m_varDeclarations, $8.m_funcDeclarations, ((*$4 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $6.m_features | $8.m_features, $6.m_numConstants + $8.m_numConstants);
                                           DBG($$.m_node, @1, @7); }
   | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement
-                                        { ForInNode *forIn = new ForInNode(GLOBAL_DATA, *$4, $5.m_node, $7.m_node, $9.m_node, @5.first_column, @5.first_column - @4.first_column, @5.last_column - @5.first_column);
+                                        { ForInNode *forIn = new (GLOBAL_DATA) ForInNode(GLOBAL_DATA, *$4, $5.m_node, $7.m_node, $9.m_node, @5.first_column, @5.first_column - @4.first_column, @5.last_column - @5.first_column);
                                           SET_EXCEPTION_LOCATION(forIn, @4.first_column, @6.first_column + 1, @7.last_column);
                                           appendToVarDeclarationList(GLOBAL_DATA, $9.m_varDeclarations, *$4, DeclarationStacks::HasInitializer);
                                           $$ = createNodeDeclarationInfo<StatementNode*>(forIn, $9.m_varDeclarations, $9.m_funcDeclarations,
@@ -1020,70 +1021,70 @@ ExprNoInOpt:
 ;
 
 ContinueStatement:
-    CONTINUE ';'                        { ContinueNode* node = new ContinueNode(GLOBAL_DATA);
+    CONTINUE ';'                        { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); 
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0);
                                           DBG($$.m_node, @1, @2); }
-  | CONTINUE error                      { ContinueNode* node = new ContinueNode(GLOBAL_DATA);
+  | CONTINUE error                      { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); 
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0);
                                           DBG($$.m_node, @1, @1); AUTO_SEMICOLON; }
-  | CONTINUE IDENT ';'                  { ContinueNode* node = new ContinueNode(GLOBAL_DATA, *$2);
+  | CONTINUE IDENT ';'                  { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); 
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0);
                                           DBG($$.m_node, @1, @3); }
-  | CONTINUE IDENT error                { ContinueNode* node = new ContinueNode(GLOBAL_DATA, *$2);
+  | CONTINUE IDENT error                { ContinueNode* node = new (GLOBAL_DATA) ContinueNode(GLOBAL_DATA, *$2);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); 
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0);
                                           DBG($$.m_node, @1, @2); AUTO_SEMICOLON; }
 ;
 
 BreakStatement:
-    BREAK ';'                           { BreakNode* node = new BreakNode(GLOBAL_DATA);
+    BREAK ';'                           { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column);
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @2); }
-  | BREAK error                         { BreakNode* node = new BreakNode(GLOBAL_DATA);
+  | BREAK error                         { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column);
-                                          $$ = createNodeDeclarationInfo<StatementNode*>(new BreakNode(GLOBAL_DATA), 0, 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; }
-  | BREAK IDENT ';'                     { BreakNode* node = new BreakNode(GLOBAL_DATA, *$2);
+                                          $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA), 0, 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; }
+  | BREAK IDENT ';'                     { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column);
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @3); }
-  | BREAK IDENT error                   { BreakNode* node = new BreakNode(GLOBAL_DATA, *$2);
+  | BREAK IDENT error                   { BreakNode* node = new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column);
-                                          $$ = createNodeDeclarationInfo<StatementNode*>(new BreakNode(GLOBAL_DATA, *$2), 0, 0, 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; }
+                                          $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) BreakNode(GLOBAL_DATA, *$2), 0, 0, 0, 0); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; }
 ;
 
 ReturnStatement:
-    RETURN ';'                          { ReturnNode* node = new ReturnNode(GLOBAL_DATA, 0); 
+    RETURN ';'                          { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); 
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); 
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @2); }
-  | RETURN error                        { ReturnNode* node = new ReturnNode(GLOBAL_DATA, 0); 
+  | RETURN error                        { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, 0); 
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @1.last_column, @1.last_column); 
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, 0, 0); DBG($$.m_node, @1, @1); AUTO_SEMICOLON; }
-  | RETURN Expr ';'                     { ReturnNode* node = new ReturnNode(GLOBAL_DATA, $2.m_node); 
+  | RETURN Expr ';'                     { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); 
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column);
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @3); }
-  | RETURN Expr error                   { ReturnNode* node = new ReturnNode(GLOBAL_DATA, $2.m_node); 
+  | RETURN Expr error                   { ReturnNode* node = new (GLOBAL_DATA) ReturnNode(GLOBAL_DATA, $2.m_node); 
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column); 
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; }
 ;
 
 WithStatement:
-    WITH '(' Expr ')' Statement         { $$ = createNodeDeclarationInfo<StatementNode*>(new WithNode(GLOBAL_DATA, $3.m_node, $5.m_node, @3.last_column, @3.last_column - @3.first_column),
+    WITH '(' Expr ')' Statement         { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) WithNode(GLOBAL_DATA, $3.m_node, $5.m_node, @3.last_column, @3.last_column - @3.first_column),
                                                                                          $5.m_varDeclarations, $5.m_funcDeclarations, $3.m_features | $5.m_features | WithFeature, $3.m_numConstants + $5.m_numConstants);
                                           DBG($$.m_node, @1, @4); }
 ;
 
 SwitchStatement:
-    SWITCH '(' Expr ')' CaseBlock       { $$ = createNodeDeclarationInfo<StatementNode*>(new SwitchNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations,
+    SWITCH '(' Expr ')' CaseBlock       { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) SwitchNode(GLOBAL_DATA, $3.m_node, $5.m_node), $5.m_varDeclarations, $5.m_funcDeclarations,
                                                                                          $3.m_features | $5.m_features, $3.m_numConstants + $5.m_numConstants);
                                           DBG($$.m_node, @1, @4); }
 ;
 
 CaseBlock:
-    OPENBRACE CaseClausesOpt CLOSEBRACE              { $$ = createNodeDeclarationInfo<CaseBlockNode*>(new CaseBlockNode(GLOBAL_DATA, $2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); }
+    OPENBRACE CaseClausesOpt CLOSEBRACE              { $$ = createNodeDeclarationInfo<CaseBlockNode*>(new (GLOBAL_DATA) CaseBlockNode(GLOBAL_DATA, $2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_features, $2.m_numConstants); }
   | OPENBRACE CaseClausesOpt DefaultClause CaseClausesOpt CLOSEBRACE
-                                        { $$ = createNodeDeclarationInfo<CaseBlockNode*>(new CaseBlockNode(GLOBAL_DATA, $2.m_node.head, $3.m_node, $4.m_node.head),
+                                        { $$ = createNodeDeclarationInfo<CaseBlockNode*>(new (GLOBAL_DATA) CaseBlockNode(GLOBAL_DATA, $2.m_node.head, $3.m_node, $4.m_node.head),
                                                                                          mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $3.m_varDeclarations), $4.m_varDeclarations),
                                                                                          mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $3.m_funcDeclarations), $4.m_funcDeclarations),
                                                                                          $2.m_features | $3.m_features | $4.m_features,
@@ -1096,14 +1097,14 @@ CaseClausesOpt:
 ;
 
 CaseClauses:
-    CaseClause                          { $$.m_node.head = new ClauseListNode(GLOBAL_DATA, $1.m_node);
+    CaseClause                          { $$.m_node.head = new (GLOBAL_DATA) ClauseListNode(GLOBAL_DATA, $1.m_node);
                                           $$.m_node.tail = $$.m_node.head;
                                           $$.m_varDeclarations = $1.m_varDeclarations;
                                           $$.m_funcDeclarations = $1.m_funcDeclarations; 
                                           $$.m_features = $1.m_features;
                                           $$.m_numConstants = $1.m_numConstants; }
   | CaseClauses CaseClause              { $$.m_node.head = $1.m_node.head;
-                                          $$.m_node.tail = new ClauseListNode(GLOBAL_DATA, $1.m_node.tail, $2.m_node);
+                                          $$.m_node.tail = new (GLOBAL_DATA) ClauseListNode(GLOBAL_DATA, $1.m_node.tail, $2.m_node);
                                           $$.m_varDeclarations = mergeDeclarationLists($1.m_varDeclarations, $2.m_varDeclarations);
                                           $$.m_funcDeclarations = mergeDeclarationLists($1.m_funcDeclarations, $2.m_funcDeclarations);
                                           $$.m_features = $1.m_features | $2.m_features;
@@ -1112,47 +1113,47 @@ CaseClauses:
 ;
 
 CaseClause:
-    CASE Expr ':'                       { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new CaseClauseNode(GLOBAL_DATA, $2.m_node), 0, 0, $2.m_features, $2.m_numConstants); }
-  | CASE Expr ':' SourceElements        { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new CaseClauseNode(GLOBAL_DATA, $2.m_node, $4.m_node), $4.m_varDeclarations, $4.m_funcDeclarations, $2.m_features | $4.m_features, $2.m_numConstants + $4.m_numConstants); }
+    CASE Expr ':'                       { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, $2.m_node), 0, 0, $2.m_features, $2.m_numConstants); }
+  | CASE Expr ':' SourceElements        { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, $2.m_node, $4.m_node), $4.m_varDeclarations, $4.m_funcDeclarations, $2.m_features | $4.m_features, $2.m_numConstants + $4.m_numConstants); }
 ;
 
 DefaultClause:
-    DEFAULT ':'                         { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new CaseClauseNode(GLOBAL_DATA, 0), 0, 0, 0, 0); }
-  | DEFAULT ':' SourceElements          { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new CaseClauseNode(GLOBAL_DATA, 0, $3.m_node), $3.m_varDeclarations, $3.m_funcDeclarations, $3.m_features, $3.m_numConstants); }
+    DEFAULT ':'                         { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, 0), 0, 0, 0, 0); }
+  | DEFAULT ':' SourceElements          { $$ = createNodeDeclarationInfo<CaseClauseNode*>(new (GLOBAL_DATA) CaseClauseNode(GLOBAL_DATA, 0, $3.m_node), $3.m_varDeclarations, $3.m_funcDeclarations, $3.m_features, $3.m_numConstants); }
 ;
 
 LabelledStatement:
-    IDENT ':' Statement                 { LabelNode* node = new LabelNode(GLOBAL_DATA, *$1, $3.m_node);
+    IDENT ':' Statement                 { LabelNode* node = new (GLOBAL_DATA) LabelNode(GLOBAL_DATA, *$1, $3.m_node);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column);
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, $3.m_varDeclarations, $3.m_funcDeclarations, $3.m_features, $3.m_numConstants); }
 ;
 
 ThrowStatement:
-    THROW Expr ';'                      { ThrowNode* node = new ThrowNode(GLOBAL_DATA, $2.m_node);
+    THROW Expr ';'                      { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, $2.m_node);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column);
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @2);
                                         }
-  | THROW Expr error                    { ThrowNode* node = new ThrowNode(GLOBAL_DATA, $2.m_node);
+  | THROW Expr error                    { ThrowNode* node = new (GLOBAL_DATA) ThrowNode(GLOBAL_DATA, $2.m_node);
                                           SET_EXCEPTION_LOCATION(node, @1.first_column, @2.last_column, @2.last_column);
                                           $$ = createNodeDeclarationInfo<StatementNode*>(node, 0, 0, $2.m_features, $2.m_numConstants); DBG($$.m_node, @1, @2); AUTO_SEMICOLON; 
                                         }
 ;
 
 TryStatement:
-    TRY Block FINALLY Block             { $$ = createNodeDeclarationInfo<StatementNode*>(new TryNode(GLOBAL_DATA, $2.m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, $4.m_node),
+    TRY Block FINALLY Block             { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, $4.m_node),
                                                                                          mergeDeclarationLists($2.m_varDeclarations, $4.m_varDeclarations),
                                                                                          mergeDeclarationLists($2.m_funcDeclarations, $4.m_funcDeclarations),
                                                                                          $2.m_features | $4.m_features,
                                                                                          $2.m_numConstants + $4.m_numConstants);
                                           DBG($$.m_node, @1, @2); }
-  | TRY Block CATCH '(' IDENT ')' Block { $$ = createNodeDeclarationInfo<StatementNode*>(new TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, 0),
+  | TRY Block CATCH '(' IDENT ')' Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, 0),
                                                                                          mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations),
                                                                                          mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations),
                                                                                          $2.m_features | $7.m_features | CatchFeature,
                                                                                          $2.m_numConstants + $7.m_numConstants);
                                           DBG($$.m_node, @1, @2); }
   | TRY Block CATCH '(' IDENT ')' Block FINALLY Block
-                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, $9.m_node),
+                                        { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, *$5, ($7.m_features & EvalFeature) != 0, $7.m_node, $9.m_node),
                                                                                          mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $7.m_varDeclarations), $9.m_varDeclarations),
                                                                                          mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $7.m_funcDeclarations), $9.m_funcDeclarations),
                                                                                          $2.m_features | $7.m_features | $9.m_features | CatchFeature,
@@ -1161,17 +1162,17 @@ TryStatement:
 ;
 
 DebuggerStatement:
-    DEBUGGER ';'                        { $$ = createNodeDeclarationInfo<StatementNode*>(new DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0);
+    DEBUGGER ';'                        { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0);
                                           DBG($$.m_node, @1, @2); }
-  | DEBUGGER error                      { $$ = createNodeDeclarationInfo<StatementNode*>(new DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0);
+  | DEBUGGER error                      { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) DebuggerStatementNode(GLOBAL_DATA), 0, 0, 0, 0);
                                           DBG($$.m_node, @1, @1); AUTO_SEMICOLON; }
 ;
 
 FunctionDeclaration:
-    FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $6, LEXER->sourceCode($5, $7, @5.first_line)), 0, new ParserRefCountedData<DeclarationStacks::FunctionStack>(GLOBAL_DATA), ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); DBG($6, @5, @7); $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)); }
+    FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $6, LEXER->sourceCode($5, $7, @5.first_line)), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | ClosureFeature, 0); DBG($6, @5, @7); $$.m_funcDeclarations->data.append(static_cast<FuncDeclNode*>($$.m_node)); }
   | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
       { 
-          $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $7, LEXER->sourceCode($6, $8, @6.first_line), $4.m_node.head), 0, new ParserRefCountedData<DeclarationStacks::FunctionStack>(GLOBAL_DATA), ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features | ClosureFeature, 0); 
+          $$ = createNodeDeclarationInfo<StatementNode*>(new FuncDeclNode(GLOBAL_DATA, *$2, $7, LEXER->sourceCode($6, $8, @6.first_line), $4.m_node.head), 0, new (GLOBAL_DATA) ParserArenaData<DeclarationStacks::FunctionStack>, ((*$2 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0) | $4.m_features | ClosureFeature, 0); 
           if ($4.m_features & ArgumentsFeature)
               $7->setUsesArguments(); 
           DBG($7, @6, @8);
@@ -1199,12 +1200,12 @@ FunctionExpr:
 ;
 
 FormalParameterList:
-    IDENT                               { $$.m_node.head = new ParameterNode(GLOBAL_DATA, *$1);
+    IDENT                               { $$.m_node.head = new (GLOBAL_DATA) ParameterNode(GLOBAL_DATA, *$1);
                                           $$.m_features = (*$1 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0;
                                           $$.m_node.tail = $$.m_node.head; }
   | FormalParameterList ',' IDENT       { $$.m_node.head = $1.m_node.head;
                                           $$.m_features = $1.m_features | ((*$3 == GLOBAL_DATA->propertyNames->arguments) ? ArgumentsFeature : 0);
-                                          $$.m_node.tail = new ParameterNode(GLOBAL_DATA, $1.m_node.tail, *$3);  }
+                                          $$.m_node.tail = new (GLOBAL_DATA) ParameterNode(GLOBAL_DATA, $1.m_node.tail, *$3);  }
 ;
 
 FunctionBody:
@@ -1213,13 +1214,13 @@ FunctionBody:
 ;
 
 Program:
-    /* not in spec */                   { GLOBAL_DATA->parser->didFinishParsing(new SourceElements(GLOBAL_DATA), 0, 0, NoFeatures, @0.last_line, 0); }
+    /* not in spec */                   { GLOBAL_DATA->parser->didFinishParsing(new (GLOBAL_DATA) SourceElements(GLOBAL_DATA), 0, 0, NoFeatures, @0.last_line, 0); }
     | SourceElements                    { GLOBAL_DATA->parser->didFinishParsing($1.m_node, $1.m_varDeclarations, $1.m_funcDeclarations, $1.m_features, 
                                                                                 @1.last_line, $1.m_numConstants); }
 ;
 
 SourceElements:
-    Statement                           { $$.m_node = new SourceElements(GLOBAL_DATA);
+    Statement                           { $$.m_node = new (GLOBAL_DATA) SourceElements(GLOBAL_DATA);
                                           $$.m_node->append($1.m_node);
                                           $$.m_varDeclarations = $1.m_varDeclarations;
                                           $$.m_funcDeclarations = $1.m_funcDeclarations;
@@ -1828,23 +1829,23 @@ SourceElements_NoNode:
 static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, int start, int divot, int end)
 {
     if (!loc->isLocation())
-        return new AssignErrorNode(GLOBAL_DATA, loc, op, expr, divot, divot - start, end - divot);
+        return new (GLOBAL_DATA) AssignErrorNode(GLOBAL_DATA, loc, op, expr, divot, divot - start, end - divot);
 
     if (loc->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(loc);
         if (op == OpEqual) {
-            AssignResolveNode* node = new AssignResolveNode(GLOBAL_DATA, resolve->identifier(), expr, exprHasAssignments);
+            AssignResolveNode* node = new (GLOBAL_DATA) AssignResolveNode(GLOBAL_DATA, resolve->identifier(), expr, exprHasAssignments);
             SET_EXCEPTION_LOCATION(node, start, divot, end);
             return node;
         } else
-            return new ReadModifyResolveNode(GLOBAL_DATA, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
+            return new (GLOBAL_DATA) ReadModifyResolveNode(GLOBAL_DATA, resolve->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
     }
     if (loc->isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
         if (op == OpEqual)
-            return new AssignBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
+            return new (GLOBAL_DATA) AssignBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), bracket->divot() - start, end - bracket->divot());
         else {
-            ReadModifyBracketNode* node = new ReadModifyBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
+            ReadModifyBracketNode* node = new (GLOBAL_DATA) ReadModifyBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, divot - start, end - divot);
             node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
             return node;
         }
@@ -1852,9 +1853,9 @@ static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Oper
     ASSERT(loc->isDotAccessorNode());
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc);
     if (op == OpEqual)
-        return new AssignDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
+        return new (GLOBAL_DATA) AssignDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), expr, exprHasAssignments, dot->divot(), dot->divot() - start, end - dot->divot());
 
-    ReadModifyDotNode* node = new ReadModifyDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
+    ReadModifyDotNode* node = new (GLOBAL_DATA) ReadModifyDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, expr, exprHasAssignments, divot, divot - start, end - divot);
     node->setSubexpressionInfo(dot->divot(), dot->endOffset());
     return node;
 }
@@ -1862,21 +1863,21 @@ static ExpressionNode* makeAssignNode(void* globalPtr, ExpressionNode* loc, Oper
 static ExpressionNode* makePrefixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end)
 {
     if (!expr->isLocation())
-        return new PrefixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot);
+        return new (GLOBAL_DATA) PrefixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot);
     
     if (expr->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
-        return new PrefixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot);
+        return new (GLOBAL_DATA) PrefixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot);
     }
     if (expr->isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
-        PrefixBracketNode* node = new PrefixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
+        PrefixBracketNode* node = new (GLOBAL_DATA) PrefixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
         node->setSubexpressionInfo(bracket->divot(), bracket->startOffset());
         return node;
     }
     ASSERT(expr->isDotAccessorNode());
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
-    PrefixDotNode* node = new PrefixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
+    PrefixDotNode* node = new (GLOBAL_DATA) PrefixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
     node->setSubexpressionInfo(dot->divot(), dot->startOffset());
     return node;
 }
@@ -1884,22 +1885,22 @@ static ExpressionNode* makePrefixNode(void* globalPtr, ExpressionNode* expr, Ope
 static ExpressionNode* makePostfixNode(void* globalPtr, ExpressionNode* expr, Operator op, int start, int divot, int end)
 { 
     if (!expr->isLocation())
-        return new PostfixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot);
+        return new (GLOBAL_DATA) PostfixErrorNode(GLOBAL_DATA, expr, op, divot, divot - start, end - divot);
     
     if (expr->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
-        return new PostfixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot);
+        return new (GLOBAL_DATA) PostfixResolveNode(GLOBAL_DATA, resolve->identifier(), op, divot, divot - start, end - divot);
     }
     if (expr->isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
-        PostfixBracketNode* node = new PostfixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
+        PostfixBracketNode* node = new (GLOBAL_DATA) PostfixBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), op, divot, divot - start, end - divot);
         node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
         return node;
         
     }
     ASSERT(expr->isDotAccessorNode());
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
-    PostfixDotNode* node = new PostfixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
+    PostfixDotNode* node = new (GLOBAL_DATA) PostfixDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), op, divot, divot - start, end - divot);
     node->setSubexpressionInfo(dot->divot(), dot->endOffset());
     return node;
 }
@@ -1909,23 +1910,29 @@ static ExpressionNodeInfo makeFunctionCallNode(void* globalPtr, ExpressionNodeIn
     CodeFeatures features = func.m_features | args.m_features;
     int numConstants = func.m_numConstants + args.m_numConstants;
     if (!func.m_node->isLocation())
-        return createNodeInfo<ExpressionNode*>(new FunctionCallValueNode(GLOBAL_DATA, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants);
+        return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallValueNode(GLOBAL_DATA, func.m_node, args.m_node, divot, divot - start, end - divot), features, numConstants);
     if (func.m_node->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(func.m_node);
         const Identifier& identifier = resolve->identifier();
         if (identifier == GLOBAL_DATA->propertyNames->eval)
-            return createNodeInfo<ExpressionNode*>(new EvalFunctionCallNode(GLOBAL_DATA, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants);
-        return createNodeInfo<ExpressionNode*>(new FunctionCallResolveNode(GLOBAL_DATA, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants);
+            return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) EvalFunctionCallNode(GLOBAL_DATA, args.m_node, divot, divot - start, end - divot), EvalFeature | features, numConstants);
+        return createNodeInfo<ExpressionNode*>(new (GLOBAL_DATA) FunctionCallResolveNode(GLOBAL_DATA, identifier, args.m_node, divot, divot - start, end - divot), features, numConstants);
     }
     if (func.m_node->isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func.m_node);
-        FunctionCallBracketNode* node = new FunctionCallBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot);
+        FunctionCallBracketNode* node = new (GLOBAL_DATA) FunctionCallBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), args.m_node, divot, divot - start, end - divot);
         node->setSubexpressionInfo(bracket->divot(), bracket->endOffset());
         return createNodeInfo<ExpressionNode*>(node, features, numConstants);
     }
     ASSERT(func.m_node->isDotAccessorNode());
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(func.m_node);
-    FunctionCallDotNode* node = new FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
+    FunctionCallDotNode* node;
+    if (dot->identifier() == GLOBAL_DATA->propertyNames->call)
+        node = new (GLOBAL_DATA) CallFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
+    else if (dot->identifier() == GLOBAL_DATA->propertyNames->apply)
+        node = new (GLOBAL_DATA) ApplyFunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
+    else
+        node = new (GLOBAL_DATA) FunctionCallDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), args.m_node, divot, divot - start, end - divot);
     node->setSubexpressionInfo(dot->divot(), dot->endOffset());
     return createNodeInfo<ExpressionNode*>(node, features, numConstants);
 }
@@ -1934,26 +1941,26 @@ static ExpressionNode* makeTypeOfNode(void* globalPtr, ExpressionNode* expr)
 {
     if (expr->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
-        return new TypeOfResolveNode(GLOBAL_DATA, resolve->identifier());
+        return new (GLOBAL_DATA) TypeOfResolveNode(GLOBAL_DATA, resolve->identifier());
     }
-    return new TypeOfValueNode(GLOBAL_DATA, expr);
+    return new (GLOBAL_DATA) TypeOfValueNode(GLOBAL_DATA, expr);
 }
 
 static ExpressionNode* makeDeleteNode(void* globalPtr, ExpressionNode* expr, int start, int divot, int end)
 {
     if (!expr->isLocation())
-        return new DeleteValueNode(GLOBAL_DATA, expr);
+        return new (GLOBAL_DATA) DeleteValueNode(GLOBAL_DATA, expr);
     if (expr->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(expr);
-        return new DeleteResolveNode(GLOBAL_DATA, resolve->identifier(), divot, divot - start, end - divot);
+        return new (GLOBAL_DATA) DeleteResolveNode(GLOBAL_DATA, resolve->identifier(), divot, divot - start, end - divot);
     }
     if (expr->isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
-        return new DeleteBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
+        return new (GLOBAL_DATA) DeleteBracketNode(GLOBAL_DATA, bracket->base(), bracket->subscript(), divot, divot - start, end - divot);
     }
     ASSERT(expr->isDotAccessorNode());
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
-    return new DeleteDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), divot, divot - start, end - divot);
+    return new (GLOBAL_DATA) DeleteDotNode(GLOBAL_DATA, dot->base(), dot->identifier(), divot, divot - start, end - divot);
 }
 
 static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceCode& source)
@@ -1965,7 +1972,7 @@ static PropertyNode* makeGetterOrSetterPropertyNode(void* globalPtr, const Ident
         type = PropertyNode::Setter;
     else
         return 0;
-    return new PropertyNode(GLOBAL_DATA, name, new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, body, source, params), type);
+    return new (GLOBAL_DATA) PropertyNode(GLOBAL_DATA, name, new FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, body, source, params), type);
 }
 
 static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n)
@@ -1979,19 +1986,19 @@ static ExpressionNode* makeNegateNode(void* globalPtr, ExpressionNode* n)
         }
     }
 
-    return new NegateNode(GLOBAL_DATA, n);
+    return new (GLOBAL_DATA) NegateNode(GLOBAL_DATA, n);
 }
 
 static NumberNode* makeNumberNode(void* globalPtr, double d)
 {
-    return new NumberNode(GLOBAL_DATA, d);
+    return new (GLOBAL_DATA) NumberNode(GLOBAL_DATA, d);
 }
 
 static ExpressionNode* makeBitwiseNotNode(void* globalPtr, ExpressionNode* expr)
 {
     if (expr->isNumber())
         return makeNumberNode(globalPtr, ~toInt32(static_cast<NumberNode*>(expr)->value()));
-    return new BitwiseNotNode(GLOBAL_DATA, expr);
+    return new (GLOBAL_DATA) BitwiseNotNode(GLOBAL_DATA, expr);
 }
 
 static ExpressionNode* makeMultNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -2003,12 +2010,12 @@ static ExpressionNode* makeMultNode(void* globalPtr, ExpressionNode* expr1, Expr
         return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() * static_cast<NumberNode*>(expr2)->value());
 
     if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
-        return new UnaryPlusNode(GLOBAL_DATA, expr2);
+        return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr2);
 
     if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
-        return new UnaryPlusNode(GLOBAL_DATA, expr1);
+        return new (GLOBAL_DATA) UnaryPlusNode(GLOBAL_DATA, expr1);
 
-    return new MultNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
+    return new (GLOBAL_DATA) MultNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
 }
 
 static ExpressionNode* makeDivNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -2018,14 +2025,14 @@ static ExpressionNode* makeDivNode(void* globalPtr, ExpressionNode* expr1, Expre
 
     if (expr1->isNumber() && expr2->isNumber())
         return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() / static_cast<NumberNode*>(expr2)->value());
-    return new DivNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
+    return new (GLOBAL_DATA) DivNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
 }
 
 static ExpressionNode* makeAddNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
     if (expr1->isNumber() && expr2->isNumber())
         return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() + static_cast<NumberNode*>(expr2)->value());
-    return new AddNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
+    return new (GLOBAL_DATA) AddNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
 }
 
 static ExpressionNode* makeSubNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
@@ -2035,21 +2042,21 @@ static ExpressionNode* makeSubNode(void* globalPtr, ExpressionNode* expr1, Expre
 
     if (expr1->isNumber() && expr2->isNumber())
         return makeNumberNode(globalPtr, static_cast<NumberNode*>(expr1)->value() - static_cast<NumberNode*>(expr2)->value());
-    return new SubNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
+    return new (GLOBAL_DATA) SubNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
 }
 
 static ExpressionNode* makeLeftShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
     if (expr1->isNumber() && expr2->isNumber())
         return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) << (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
-    return new LeftShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
+    return new (GLOBAL_DATA) LeftShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
 }
 
 static ExpressionNode* makeRightShiftNode(void* globalPtr, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
 {
     if (expr1->isNumber() && expr2->isNumber())
         return makeNumberNode(globalPtr, toInt32(static_cast<NumberNode*>(expr1)->value()) >> (toUInt32(static_cast<NumberNode*>(expr2)->value()) & 0x1f));
-    return new RightShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
+    return new (GLOBAL_DATA) RightShiftNode(GLOBAL_DATA, expr1, expr2, rightHasAssignments);
 }
 
 /* called by yyparse on error */
@@ -2064,11 +2071,15 @@ static bool allowAutomaticSemicolon(Lexer& lexer, int yychar)
     return yychar == CLOSEBRACE || yychar == 0 || lexer.prevTerminator();
 }
 
-static ExpressionNode* combineVarInitializers(void* globalPtr, ExpressionNode* list, AssignResolveNode* init)
+static ExpressionNode* combineCommaNodes(void* globalPtr, ExpressionNode* list, ExpressionNode* init)
 {
     if (!list)
         return init;
-    return new VarDeclCommaNode(GLOBAL_DATA, list, init);
+    if (list->isCommaNode()) {
+        static_cast<CommaNode*>(list)->append(init);
+        return list;
+    }
+    return new (GLOBAL_DATA) CommaNode(GLOBAL_DATA, list, init);
 }
 
 // We turn variable declarations into either assignments or empty
@@ -2077,8 +2088,8 @@ static ExpressionNode* combineVarInitializers(void* globalPtr, ExpressionNode* l
 static StatementNode* makeVarStatementNode(void* globalPtr, ExpressionNode* expr)
 {
     if (!expr)
-        return new EmptyStatementNode(GLOBAL_DATA);
-    return new VarStatementNode(GLOBAL_DATA, expr);
+        return new (GLOBAL_DATA) EmptyStatementNode(GLOBAL_DATA);
+    return new (GLOBAL_DATA) VarStatementNode(GLOBAL_DATA, expr);
 }
 
 #undef GLOBAL_DATA
index c2880dc681780bdc9123c7205e3d876fa5e07a1f..8e89c18a9ee9ff0f7ef90279ad0f4db5885aa73b 100644 (file)
 #include <ctype.h>
 #include <limits.h>
 #include <string.h>
-#include <wtf/ASCIICType.h>
 #include <wtf/Assertions.h>
-#include <wtf/unicode/Unicode.h>
 
 using namespace WTF;
 using namespace Unicode;
 
-// we can't specify the namespace in yacc's C output, so do it here
+// We can't specify the namespace in yacc's C output, so do it here instead.
 using namespace JSC;
 
 #ifndef KDE_USE_FINAL
@@ -48,7 +46,7 @@ using namespace JSC;
 #include "Lookup.h"
 #include "Lexer.lut.h"
 
-// a bridge for yacc from the C world to C++
+// A bridge for yacc from the C world to the C++ world.
 int jscyylex(void* lvalp, void* llocp, void* globalData)
 {
     return static_cast<JSGlobalData*>(globalData)->lexer->lex(lvalp, llocp);
@@ -56,29 +54,12 @@ int jscyylex(void* lvalp, void* llocp, void* globalData)
 
 namespace JSC {
 
-static bool isDecimalDigit(int);
+static const UChar byteOrderMark = 0xFEFF;
 
 Lexer::Lexer(JSGlobalData* globalData)
-    : yylineno(1)
-    , m_restrKeyword(false)
-    , m_eatNextIdentifier(false)
-    , m_stackToken(-1)
-    , m_lastToken(-1)
-    , m_position(0)
-    , m_code(0)
-    , m_length(0)
-    , m_isReparsing(false)
-    , m_atLineStart(true)
-    , m_current(0)
-    , m_next1(0)
-    , m_next2(0)
-    , m_next3(0)
-    , m_currentOffset(0)
-    , m_nextOffset1(0)
-    , m_nextOffset2(0)
-    , m_nextOffset3(0)
+    : m_isReparsing(false)
     , m_globalData(globalData)
-    , m_mainTable(JSC::mainTable)
+    , m_keywordTable(JSC::mainTable)
 {
     m_buffer8.reserveInitialCapacity(initialReadBufferCapacity);
     m_buffer16.reserveInitialCapacity(initialReadBufferCapacity);
@@ -86,795 +67,882 @@ Lexer::Lexer(JSGlobalData* globalData)
 
 Lexer::~Lexer()
 {
-    m_mainTable.deleteTable();
+    m_keywordTable.deleteTable();
+}
+
+inline const UChar* Lexer::currentCharacter() const
+{
+    return m_code - 4;
+}
+
+inline int Lexer::currentOffset() const
+{
+    return currentCharacter() - m_codeStart;
+}
+
+ALWAYS_INLINE void Lexer::shift1()
+{
+    m_current = m_next1;
+    m_next1 = m_next2;
+    m_next2 = m_next3;
+    if (LIKELY(m_code < m_codeEnd))
+        m_next3 = m_code[0];
+    else
+        m_next3 = -1;
+
+    ++m_code;
+}
+
+ALWAYS_INLINE void Lexer::shift2()
+{
+    m_current = m_next2;
+    m_next1 = m_next3;
+    if (LIKELY(m_code + 1 < m_codeEnd)) {
+        m_next2 = m_code[0];
+        m_next3 = m_code[1];
+    } else {
+        m_next2 = m_code < m_codeEnd ? m_code[0] : -1;
+        m_next3 = -1;
+    }
+
+    m_code += 2;
+}
+
+ALWAYS_INLINE void Lexer::shift3()
+{
+    m_current = m_next3;
+    if (LIKELY(m_code + 2 < m_codeEnd)) {
+        m_next1 = m_code[0];
+        m_next2 = m_code[1];
+        m_next3 = m_code[2];
+    } else {
+        m_next1 = m_code < m_codeEnd ? m_code[0] : -1;
+        m_next2 = m_code + 1 < m_codeEnd ? m_code[1] : -1;
+        m_next3 = -1;
+    }
+
+    m_code += 3;
+}
+
+ALWAYS_INLINE void Lexer::shift4()
+{
+    if (LIKELY(m_code + 3 < m_codeEnd)) {
+        m_current = m_code[0];
+        m_next1 = m_code[1];
+        m_next2 = m_code[2];
+        m_next3 = m_code[3];
+    } else {
+        m_current = m_code < m_codeEnd ? m_code[0] : -1;
+        m_next1 = m_code + 1 < m_codeEnd ? m_code[1] : -1;
+        m_next2 = m_code + 2 < m_codeEnd ? m_code[2] : -1;
+        m_next3 = -1;
+    }
+
+    m_code += 4;
 }
 
 void Lexer::setCode(const SourceCode& source)
 {
-    yylineno = source.firstLine();
-    m_restrKeyword = false;
+    m_lineNumber = source.firstLine();
     m_delimited = false;
-    m_eatNextIdentifier = false;
-    m_stackToken = -1;
     m_lastToken = -1;
 
-    m_position = source.startOffset();
+    const UChar* data = source.provider()->data();
+
     m_source = &source;
-    m_code = source.provider()->data();
-    m_length = source.endOffset();
-    m_skipLF = false;
-    m_skipCR = false;
+    m_codeStart = data;
+    m_code = data + source.startOffset();
+    m_codeEnd = data + source.endOffset();
     m_error = false;
     m_atLineStart = true;
 
-    // read first characters
-    shift(4);
+    // ECMA-262 calls for stripping all Cf characters, but we only strip BOM characters.
+    // See <https://bugs.webkit.org/show_bug.cgi?id=4931> for details.
+    if (source.provider()->hasBOMs()) {
+        for (const UChar* p = m_codeStart; p < m_codeEnd; ++p) {
+            if (UNLIKELY(*p == byteOrderMark)) {
+                copyCodeWithoutBOMs();
+                break;
+            }
+        }
+    }
+
+    // Read the first characters into the 4-character buffer.
+    shift4();
+    ASSERT(currentOffset() == source.startOffset());
 }
 
-void Lexer::shift(unsigned p)
+void Lexer::copyCodeWithoutBOMs()
 {
-    // ECMA-262 calls for stripping Cf characters here, but we only do this for BOM,
-    // see <https://bugs.webkit.org/show_bug.cgi?id=4931>.
-
-    while (p--) {
-        m_current = m_next1;
-        m_next1 = m_next2;
-        m_next2 = m_next3;
-        m_currentOffset = m_nextOffset1;
-        m_nextOffset1 = m_nextOffset2;
-        m_nextOffset2 = m_nextOffset3;
-        do {
-            if (m_position >= m_length) {
-                m_nextOffset3 = m_position;
-                m_position++;
-                m_next3 = -1;
-                break;
-            }
-            m_nextOffset3 = m_position;
-            m_next3 = m_code[m_position++];
-        } while (m_next3 == 0xFEFF);
+    // Note: In this case, the character offset data for debugging will be incorrect.
+    // If it's important to correctly debug code with extraneous BOMs, then the caller
+    // should strip the BOMs when creating the SourceProvider object and do its own
+    // mapping of offsets within the stripped text to original text offset.
+
+    m_codeWithoutBOMs.reserveCapacity(m_codeEnd - m_code);
+    for (const UChar* p = m_code; p < m_codeEnd; ++p) {
+        UChar c = *p;
+        if (c != byteOrderMark)
+            m_codeWithoutBOMs.append(c);
+    }
+    ptrdiff_t startDelta = m_codeStart - m_code;
+    m_code = m_codeWithoutBOMs.data();
+    m_codeStart = m_code + startDelta;
+    m_codeEnd = m_codeWithoutBOMs.data() + m_codeWithoutBOMs.size();
+}
+
+void Lexer::shiftLineTerminator()
+{
+    ASSERT(isLineTerminator(m_current));
+
+    // Allow both CRLF and LFCR.
+    if (m_current + m_next1 == '\n' + '\r')
+        shift2();
+    else
+        shift1();
+
+    ++m_lineNumber;
+}
+
+ALWAYS_INLINE Identifier* Lexer::makeIdentifier(const UChar* characters, size_t length)
+{
+    m_identifiers.append(Identifier(m_globalData, characters, length));
+    return &m_identifiers.last();
+}
+
+inline bool Lexer::lastTokenWasRestrKeyword() const
+{
+    return m_lastToken == CONTINUE || m_lastToken == BREAK || m_lastToken == RETURN || m_lastToken == THROW;
+}
+
+static NEVER_INLINE bool isNonASCIIIdentStart(int c)
+{
+    return category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other);
+}
+
+static inline bool isIdentStart(int c)
+{
+    return isASCII(c) ? isASCIIAlpha(c) || c == '$' || c == '_' : isNonASCIIIdentStart(c);
+}
+
+static NEVER_INLINE bool isNonASCIIIdentPart(int c)
+{
+    return category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other
+        | Mark_NonSpacing | Mark_SpacingCombining | Number_DecimalDigit | Punctuation_Connector);
+}
+
+static inline bool isIdentPart(int c)
+{
+    return isASCII(c) ? isASCIIAlphanumeric(c) || c == '$' || c == '_' : isNonASCIIIdentPart(c);
+}
+
+static inline int singleEscape(int c)
+{
+    switch (c) {
+        case 'b':
+            return 0x08;
+        case 't':
+            return 0x09;
+        case 'n':
+            return 0x0A;
+        case 'v':
+            return 0x0B;
+        case 'f':
+            return 0x0C;
+        case 'r':
+            return 0x0D;
+        default:
+            return c;
     }
 }
 
-// called on each new line
-void Lexer::nextLine()
+inline void Lexer::record8(int c)
 {
-    yylineno++;
-    m_atLineStart = true;
+    ASSERT(c >= 0);
+    ASSERT(c <= 0xFF);
+    m_buffer8.append(static_cast<char>(c));
 }
 
-void Lexer::setDone(State s)
+inline void Lexer::record16(UChar c)
 {
-    m_state = s;
-    m_done = true;
+    m_buffer16.append(c);
+}
+
+inline void Lexer::record16(int c)
+{
+    ASSERT(c >= 0);
+    ASSERT(c <= USHRT_MAX);
+    record16(UChar(static_cast<unsigned short>(c)));
 }
 
 int Lexer::lex(void* p1, void* p2)
 {
+    ASSERT(!m_error);
+    ASSERT(m_buffer8.isEmpty());
+    ASSERT(m_buffer16.isEmpty());
+
     YYSTYPE* lvalp = static_cast<YYSTYPE*>(p1);
     YYLTYPE* llocp = static_cast<YYLTYPE*>(p2);
     int token = 0;
-    m_state = Start;
-    unsigned short stringType = 0; // either single or double quotes
-    m_buffer8.clear();
-    m_buffer16.clear();
-    m_done = false;
     m_terminator = false;
-    m_skipLF = false;
-    m_skipCR = false;
-
-    // did we push a token on the stack previously ?
-    // (after an automatic semicolon insertion)
-    if (m_stackToken >= 0) {
-        setDone(Other);
-        token = m_stackToken;
-        m_stackToken = 0;
-    }
-    int startOffset = m_currentOffset;
-    while (!m_done) {
-        if (m_skipLF && m_current != '\n') // found \r but not \n afterwards
-            m_skipLF = false;
-        if (m_skipCR && m_current != '\r') // found \n but not \r afterwards
-            m_skipCR = false;
-        if (m_skipLF || m_skipCR) { // found \r\n or \n\r -> eat the second one
-            m_skipLF = false;
-            m_skipCR = false;
-            shift(1);
+
+start:
+    while (isWhiteSpace(m_current))
+        shift1();
+
+    int startOffset = currentOffset();
+
+    if (m_current == -1) {
+        if (!m_terminator && !m_delimited && !m_isReparsing) {
+            // automatic semicolon insertion if program incomplete
+            token = ';';
+            goto doneSemicolon;
         }
-        switch (m_state) {
-            case Start:
-                startOffset = m_currentOffset;
-                if (isWhiteSpace()) {
-                    // do nothing
-                } else if (m_current == '/' && m_next1 == '/') {
-                    shift(1);
-                    m_state = InSingleLineComment;
-                } else if (m_current == '/' && m_next1 == '*') {
-                    shift(1);
-                    m_state = InMultiLineComment;
-                } else if (m_current == -1) {
-                    if (!m_terminator && !m_delimited && !m_isReparsing) {
-                        // automatic semicolon insertion if program incomplete
-                        token = ';';
-                        m_stackToken = 0;
-                        setDone(Other);
-                    } else
-                        setDone(Eof);
-                } else if (isLineTerminator()) {
-                    nextLine();
-                    m_terminator = true;
-                    if (m_restrKeyword) {
-                        token = ';';
-                        setDone(Other);
-                    }
-                } else if (m_current == '"' || m_current == '\'') {
-                    m_state = InString;
-                    stringType = static_cast<unsigned short>(m_current);
-                } else if (isIdentStart(m_current)) {
-                    record16(m_current);
-                    m_state = InIdentifierOrKeyword;
-                } else if (m_current == '\\')
-                    m_state = InIdentifierStartUnicodeEscapeStart;
-                else if (m_current == '0') {
-                    record8(m_current);
-                    m_state = InNum0;
-                } else if (isDecimalDigit(m_current)) {
-                    record8(m_current);
-                    m_state = InNum;
-                } else if (m_current == '.' && isDecimalDigit(m_next1)) {
-                    record8(m_current);
-                    m_state = InDecimal;
-                    // <!-- marks the beginning of a line comment (for www usage)
-                } else if (m_current == '<' && m_next1 == '!' && m_next2 == '-' && m_next3 == '-') {
-                    shift(3);
-                    m_state = InSingleLineComment;
-                    // same for -->
-                } else if (m_atLineStart && m_current == '-' && m_next1 == '-' &&  m_next2 == '>') {
-                    shift(2);
-                    m_state = InSingleLineComment;
-                } else {
-                    token = matchPunctuator(lvalp->intValue, m_current, m_next1, m_next2, m_next3);
-                    if (token != -1)
-                        setDone(Other);
-                    else
-                        setDone(Bad);
+        return 0;
+    }
+
+    m_delimited = false;
+    switch (m_current) {
+        case '>':
+            if (m_next1 == '>' && m_next2 == '>') {
+                if (m_next3 == '=') {
+                    shift4();
+                    token = URSHIFTEQUAL;
+                    break;
                 }
+                shift3();
+                token = URSHIFT;
                 break;
-            case InString:
-                if (m_current == stringType) {
-                    shift(1);
-                    setDone(String);
-                } else if (isLineTerminator() || m_current == -1)
-                    setDone(Bad);
-                else if (m_current == '\\')
-                    m_state = InEscapeSequence;
-                else
-                    record16(m_current);
+            }
+            if (m_next1 == '>') {
+                if (m_next2 == '=') {
+                    shift3();
+                    token = RSHIFTEQUAL;
+                    break;
+                }
+                shift2();
+                token = RSHIFT;
                 break;
-            // Escape Sequences inside of strings
-            case InEscapeSequence:
-                if (isOctalDigit(m_current)) {
-                    if (m_current >= '0' && m_current <= '3' &&
-                        isOctalDigit(m_next1) && isOctalDigit(m_next2)) {
-                        record16(convertOctal(m_current, m_next1, m_next2));
-                        shift(2);
-                        m_state = InString;
-                    } else if (isOctalDigit(m_current) && isOctalDigit(m_next1)) {
-                        record16(convertOctal('0', m_current, m_next1));
-                        shift(1);
-                        m_state = InString;
-                    } else if (isOctalDigit(m_current)) {
-                        record16(convertOctal('0', '0', m_current));
-                        m_state = InString;
-                    } else
-                        setDone(Bad);
-                } else if (m_current == 'x')
-                    m_state = InHexEscape;
-                else if (m_current == 'u')
-                    m_state = InUnicodeEscape;
-                else if (isLineTerminator()) {
-                    nextLine();
-                    m_state = InString;
-                } else {
-                    record16(singleEscape(static_cast<unsigned short>(m_current)));
-                    m_state = InString;
+            }
+            if (m_next1 == '=') {
+                shift2();
+                token = GE;
+                break;
+            }
+            shift1();
+            token = '>';
+            break;
+        case '=':
+            if (m_next1 == '=') {
+                if (m_next2 == '=') {
+                    shift3();
+                    token = STREQ;
+                    break;
                 }
+                shift2();
+                token = EQEQ;
                 break;
-            case InHexEscape:
-                if (isHexDigit(m_current) && isHexDigit(m_next1)) {
-                    m_state = InString;
-                    record16(convertHex(m_current, m_next1));
-                    shift(1);
-                } else if (m_current == stringType) {
-                    record16('x');
-                    shift(1);
-                    setDone(String);
-                } else {
-                    record16('x');
-                    record16(m_current);
-                    m_state = InString;
+            }
+            shift1();
+            token = '=';
+            break;
+        case '!':
+            if (m_next1 == '=') {
+                if (m_next2 == '=') {
+                    shift3();
+                    token = STRNEQ;
+                    break;
                 }
+                shift2();
+                token = NE;
                 break;
-            case InUnicodeEscape:
-                if (isHexDigit(m_current) && isHexDigit(m_next1) && isHexDigit(m_next2) && isHexDigit(m_next3)) {
-                    record16(convertUnicode(m_current, m_next1, m_next2, m_next3));
-                    shift(3);
-                    m_state = InString;
-                } else if (m_current == stringType) {
-                    record16('u');
-                    shift(1);
-                    setDone(String);
-                } else
-                    setDone(Bad);
+            }
+            shift1();
+            token = '!';
+            break;
+        case '<':
+            if (m_next1 == '!' && m_next2 == '-' && m_next3 == '-') {
+                // <!-- marks the beginning of a line comment (for www usage)
+                shift4();
+                goto inSingleLineComment;
+            }
+            if (m_next1 == '<') {
+                if (m_next2 == '=') {
+                    shift3();
+                    token = LSHIFTEQUAL;
+                    break;
+                }
+                shift2();
+                token = LSHIFT;
                 break;
-            case InSingleLineComment:
-                if (isLineTerminator()) {
-                    nextLine();
-                    m_terminator = true;
-                    if (m_restrKeyword) {
-                        token = ';';
-                        setDone(Other);
-                    } else
-                        m_state = Start;
-                } else if (m_current == -1)
-                    setDone(Eof);
+            }
+            if (m_next1 == '=') {
+                shift2();
+                token = LE;
                 break;
-            case InMultiLineComment:
-                if (m_current == -1)
-                    setDone(Bad);
-                else if (isLineTerminator())
-                    nextLine();
-                else if (m_current == '*' && m_next1 == '/') {
-                    m_state = Start;
-                    shift(1);
+            }
+            shift1();
+            token = '<';
+            break;
+        case '+':
+            if (m_next1 == '+') {
+                shift2();
+                if (m_terminator) {
+                    token = AUTOPLUSPLUS;
+                    break;
                 }
+                token = PLUSPLUS;
                 break;
-            case InIdentifierOrKeyword:
-            case InIdentifier:
-                if (isIdentPart(m_current))
-                    record16(m_current);
-                else if (m_current == '\\')
-                    m_state = InIdentifierPartUnicodeEscapeStart;
-                else
-                    setDone(m_state == InIdentifierOrKeyword ? IdentifierOrKeyword : Identifier);
+            }
+            if (m_next1 == '=') {
+                shift2();
+                token = PLUSEQUAL;
                 break;
-            case InNum0:
-                if (m_current == 'x' || m_current == 'X') {
-                    record8(m_current);
-                    m_state = InHex;
-                } else if (m_current == '.') {
-                    record8(m_current);
-                    m_state = InDecimal;
-                } else if (m_current == 'e' || m_current == 'E') {
-                    record8(m_current);
-                    m_state = InExponentIndicator;
-                } else if (isOctalDigit(m_current)) {
-                    record8(m_current);
-                    m_state = InOctal;
-                } else if (isDecimalDigit(m_current)) {
-                    record8(m_current);
-                    m_state = InDecimal;
-                } else
-                    setDone(Number);
+            }
+            shift1();
+            token = '+';
+            break;
+        case '-':
+            if (m_next1 == '-') {
+                if (m_atLineStart && m_next2 == '>') {
+                    shift3();
+                    goto inSingleLineComment;
+                }
+                shift2();
+                if (m_terminator) {
+                    token = AUTOMINUSMINUS;
+                    break;
+                }
+                token = MINUSMINUS;
                 break;
-            case InHex:
-                if (isHexDigit(m_current))
-                    record8(m_current);
-                else
-                    setDone(Hex);
+            }
+            if (m_next1 == '=') {
+                shift2();
+                token = MINUSEQUAL;
                 break;
-            case InOctal:
-                if (isOctalDigit(m_current))
-                    record8(m_current);
-                else if (isDecimalDigit(m_current)) {
-                    record8(m_current);
-                    m_state = InDecimal;
-                } else
-                    setDone(Octal);
+            }
+            shift1();
+            token = '-';
+            break;
+        case '*':
+            if (m_next1 == '=') {
+                shift2();
+                token = MULTEQUAL;
                 break;
-            case InNum:
-                if (isDecimalDigit(m_current))
-                    record8(m_current);
-                else if (m_current == '.') {
-                    record8(m_current);
-                    m_state = InDecimal;
-                } else if (m_current == 'e' || m_current == 'E') {
-                    record8(m_current);
-                    m_state = InExponentIndicator;
-                } else
-                    setDone(Number);
+            }
+            shift1();
+            token = '*';
+            break;
+        case '/':
+            if (m_next1 == '/') {
+                shift2();
+                goto inSingleLineComment;
+            }
+            if (m_next1 == '*')
+                goto inMultiLineComment;
+            if (m_next1 == '=') {
+                shift2();
+                token = DIVEQUAL;
                 break;
-            case InDecimal:
-                if (isDecimalDigit(m_current))
-                    record8(m_current);
-                else if (m_current == 'e' || m_current == 'E') {
-                    record8(m_current);
-                    m_state = InExponentIndicator;
-                } else
-                    setDone(Number);
+            }
+            shift1();
+            token = '/';
+            break;
+        case '&':
+            if (m_next1 == '&') {
+                shift2();
+                token = AND;
                 break;
-            case InExponentIndicator:
-                if (m_current == '+' || m_current == '-')
-                    record8(m_current);
-                else if (isDecimalDigit(m_current)) {
-                    record8(m_current);
-                    m_state = InExponent;
-                } else
-                    setDone(Bad);
+            }
+            if (m_next1 == '=') {
+                shift2();
+                token = ANDEQUAL;
                 break;
-            case InExponent:
-                if (isDecimalDigit(m_current))
-                    record8(m_current);
-                else
-                    setDone(Number);
+            }
+            shift1();
+            token = '&';
+            break;
+        case '^':
+            if (m_next1 == '=') {
+                shift2();
+                token = XOREQUAL;
                 break;
-            case InIdentifierStartUnicodeEscapeStart:
-                if (m_current == 'u')
-                    m_state = InIdentifierStartUnicodeEscape;
-                else
-                    setDone(Bad);
+            }
+            shift1();
+            token = '^';
+            break;
+        case '%':
+            if (m_next1 == '=') {
+                shift2();
+                token = MODEQUAL;
                 break;
-            case InIdentifierPartUnicodeEscapeStart:
-                if (m_current == 'u')
-                    m_state = InIdentifierPartUnicodeEscape;
-                else
-                    setDone(Bad);
+            }
+            shift1();
+            token = '%';
+            break;
+        case '|':
+            if (m_next1 == '=') {
+                shift2();
+                token = OREQUAL;
                 break;
-            case InIdentifierStartUnicodeEscape:
-                if (!isHexDigit(m_current) || !isHexDigit(m_next1) || !isHexDigit(m_next2) || !isHexDigit(m_next3)) {
-                    setDone(Bad);
-                    break;
-                }
-                token = convertUnicode(m_current, m_next1, m_next2, m_next3);
-                shift(3);
-                if (!isIdentStart(token)) {
-                    setDone(Bad);
-                    break;
-                }
-                record16(token);
-                m_state = InIdentifier;
+            }
+            if (m_next1 == '|') {
+                shift2();
+                token = OR;
                 break;
-            case InIdentifierPartUnicodeEscape:
-                if (!isHexDigit(m_current) || !isHexDigit(m_next1) || !isHexDigit(m_next2) || !isHexDigit(m_next3)) {
-                    setDone(Bad);
-                    break;
-                }
-                token = convertUnicode(m_current, m_next1, m_next2, m_next3);
-                shift(3);
-                if (!isIdentPart(token)) {
-                    setDone(Bad);
-                    break;
+            }
+            shift1();
+            token = '|';
+            break;
+        case '.':
+            if (isASCIIDigit(m_next1)) {
+                record8('.');
+                shift1();
+                goto inNumberAfterDecimalPoint;
+            }
+            token = '.';
+            shift1();
+            break;
+        case ',':
+        case '~':
+        case '?':
+        case ':':
+        case '(':
+        case ')':
+        case '[':
+        case ']':
+            token = m_current;
+            shift1();
+            break;
+        case ';':
+            shift1();
+            m_delimited = true;
+            token = ';';
+            break;
+        case '{':
+            lvalp->intValue = currentOffset();
+            shift1();
+            token = OPENBRACE;
+            break;
+        case '}':
+            lvalp->intValue = currentOffset();
+            shift1();
+            m_delimited = true;
+            token = CLOSEBRACE;
+            break;
+        case '\\':
+            goto startIdentifierWithBackslash;
+        case '0':
+            goto startNumberWithZeroDigit;
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+            goto startNumber;
+        case '"':
+        case '\'':
+            goto startString;
+        default:
+            if (isIdentStart(m_current))
+                goto startIdentifierOrKeyword;
+            if (isLineTerminator(m_current)) {
+                shiftLineTerminator();
+                m_atLineStart = true;
+                m_terminator = true;
+                if (lastTokenWasRestrKeyword()) {
+                    token = ';';
+                    goto doneSemicolon;
                 }
-                record16(token);
-                m_state = InIdentifier;
-                break;
-            default:
-                ASSERT(!"Unhandled state in switch statement");
-        }
-
-        // move on to the next character
-        if (!m_done)
-            shift(1);
-        if (m_state != Start && m_state != InSingleLineComment)
-            m_atLineStart = false;
+                goto start;
+            }
+            goto returnError;
     }
 
-    // no identifiers allowed directly after numeric literal, e.g. "3in" is bad
-    if ((m_state == Number || m_state == Octal || m_state == Hex) && isIdentStart(m_current))
-        m_state = Bad;
+    m_atLineStart = false;
+    goto returnToken;
 
-    // terminate string
-    m_buffer8.append('\0');
-
-#ifdef JSC_DEBUG_LEX
-    fprintf(stderr, "line: %d ", lineNo());
-    fprintf(stderr, "yytext (%x): ", m_buffer8[0]);
-    fprintf(stderr, "%s ", m_buffer8.data());
-#endif
+startString: {
+    int stringQuoteCharacter = m_current;
+    shift1();
 
-    double dval = 0;
-    if (m_state == Number)
-        dval = WTF::strtod(m_buffer8.data(), 0L);
-    else if (m_state == Hex) { // scan hex numbers
-        const char* p = m_buffer8.data() + 2;
-        while (char c = *p++) {
-            dval *= 16;
-            dval += convertHex(c);
+    const UChar* stringStart = currentCharacter();
+    while (m_current != stringQuoteCharacter) {
+        // Fast check for characters that require special handling.
+        // Catches -1, \n, \r, \, 0x2028, and 0x2029 as efficiently
+        // as possible, and lets through all common ASCII characters.
+        if (UNLIKELY(m_current == '\\') || UNLIKELY(((static_cast<unsigned>(m_current) - 0xE) & 0x2000))) {
+            m_buffer16.append(stringStart, currentCharacter() - stringStart);
+            goto inString;
+        }
+        shift1();
+    }
+    lvalp->ident = makeIdentifier(stringStart, currentCharacter() - stringStart);
+    shift1();
+    m_atLineStart = false;
+    m_delimited = false;
+    token = STRING;
+    goto returnToken;
+
+inString:
+    while (m_current != stringQuoteCharacter) {
+        if (m_current == '\\')
+            goto inStringEscapeSequence;
+        if (UNLIKELY(isLineTerminator(m_current)))
+            goto returnError;
+        if (UNLIKELY(m_current == -1))
+            goto returnError;
+        record16(m_current);
+        shift1();
+    }
+    goto doneString;
+
+inStringEscapeSequence:
+    shift1();
+    if (m_current == 'x') {
+        shift1();
+        if (isASCIIHexDigit(m_current) && isASCIIHexDigit(m_next1)) {
+            record16(convertHex(m_current, m_next1));
+            shift2();
+            goto inString;
         }
+        record16('x');
+        if (m_current == stringQuoteCharacter)
+            goto doneString;
+        goto inString;
+    }
+    if (m_current == 'u') {
+        shift1();
+        if (isASCIIHexDigit(m_current) && isASCIIHexDigit(m_next1) && isASCIIHexDigit(m_next2) && isASCIIHexDigit(m_next3)) {
+            record16(convertUnicode(m_current, m_next1, m_next2, m_next3));
+            shift4();
+            goto inString;
+        }
+        if (m_current == stringQuoteCharacter) {
+            record16('u');
+            goto doneString;
+        }
+        goto returnError;
+    }
+    if (isASCIIOctalDigit(m_current)) {
+        if (m_current >= '0' && m_current <= '3' && isASCIIOctalDigit(m_next1) && isASCIIOctalDigit(m_next2)) {
+            record16((m_current - '0') * 64 + (m_next1 - '0') * 8 + m_next2 - '0');
+            shift3();
+            goto inString;
+        }
+        if (isASCIIOctalDigit(m_next1)) {
+            record16((m_current - '0') * 8 + m_next1 - '0');
+            shift2();
+            goto inString;
+        }
+        record16(m_current - '0');
+        shift1();
+        goto inString;
+    }
+    if (isLineTerminator(m_current)) {
+        shiftLineTerminator();
+        goto inString;
+    }
+    record16(singleEscape(m_current));
+    shift1();
+    goto inString;
+}
 
-        if (dval >= mantissaOverflowLowerBound)
-            dval = parseIntOverflow(m_buffer8.data() + 2, p - (m_buffer8.data() + 3), 16);
+startIdentifierWithBackslash:
+    shift1();
+    if (UNLIKELY(m_current != 'u'))
+        goto returnError;
+    shift1();
+    if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(m_next1) || !isASCIIHexDigit(m_next2) || !isASCIIHexDigit(m_next3)))
+        goto returnError;
+    token = convertUnicode(m_current, m_next1, m_next2, m_next3);
+    if (UNLIKELY(!isIdentStart(token)))
+        goto returnError;
+    goto inIdentifierAfterCharacterCheck;
+
+startIdentifierOrKeyword: {
+    const UChar* identifierStart = currentCharacter();
+    shift1();
+    while (isIdentPart(m_current))
+        shift1();
+    if (LIKELY(m_current != '\\')) {
+        lvalp->ident = makeIdentifier(identifierStart, currentCharacter() - identifierStart);
+        goto doneIdentifierOrKeyword;
+    }
+    m_buffer16.append(identifierStart, currentCharacter() - identifierStart);
+}
 
-        m_state = Number;
-    } else if (m_state == Octal) {   // scan octal number
-        const char* p = m_buffer8.data() + 1;
-        while (char c = *p++) {
-            dval *= 8;
-            dval += c - '0';
+    do {
+        shift1();
+        if (UNLIKELY(m_current != 'u'))
+            goto returnError;
+        shift1();
+        if (UNLIKELY(!isASCIIHexDigit(m_current) || !isASCIIHexDigit(m_next1) || !isASCIIHexDigit(m_next2) || !isASCIIHexDigit(m_next3)))
+            goto returnError;
+        token = convertUnicode(m_current, m_next1, m_next2, m_next3);
+        if (UNLIKELY(!isIdentPart(token)))
+            goto returnError;
+inIdentifierAfterCharacterCheck:
+        record16(token);
+        shift4();
+
+        while (isIdentPart(m_current)) {
+            record16(m_current);
+            shift1();
         }
+    } while (UNLIKELY(m_current == '\\'));
+    goto doneIdentifier;
 
-        if (dval >= mantissaOverflowLowerBound)
-            dval = parseIntOverflow(m_buffer8.data() + 1, p - (m_buffer8.data() + 2), 8);
-
-        m_state = Number;
+inSingleLineComment:
+    while (!isLineTerminator(m_current)) {
+        if (UNLIKELY(m_current == -1))
+            return 0;
+        shift1();
     }
-
-#ifdef JSC_DEBUG_LEX
-    switch (m_state) {
-        case Eof:
-            printf("(EOF)\n");
-            break;
-        case Other:
-            printf("(Other)\n");
-            break;
-        case Identifier:
-            printf("(Identifier)/(Keyword)\n");
-            break;
-        case String:
-            printf("(String)\n");
-            break;
-        case Number:
-            printf("(Number)\n");
-            break;
-        default:
-            printf("(unknown)");
+    shiftLineTerminator();
+    m_atLineStart = true;
+    m_terminator = true;
+    if (lastTokenWasRestrKeyword())
+        goto doneSemicolon;
+    goto start;
+
+inMultiLineComment:
+    shift2();
+    while (m_current != '*' || m_next1 != '/') {
+        if (isLineTerminator(m_current))
+            shiftLineTerminator();
+        else {
+            shift1();
+            if (UNLIKELY(m_current == -1))
+                goto returnError;
+        }
     }
-#endif
+    shift2();
+    m_atLineStart = false;
+    goto start;
+
+startNumberWithZeroDigit:
+    shift1();
+    if ((m_current | 0x20) == 'x' && isASCIIHexDigit(m_next1)) {
+        shift1();
+        goto inHex;
+    }
+    if (m_current == '.') {
+        record8('0');
+        record8('.');
+        shift1();
+        goto inNumberAfterDecimalPoint;
+    }
+    if ((m_current | 0x20) == 'e') {
+        record8('0');
+        record8('e');
+        shift1();
+        goto inExponentIndicator;
+    }
+    if (isASCIIOctalDigit(m_current))
+        goto inOctal;
+    if (isASCIIDigit(m_current))
+        goto startNumber;
+    lvalp->doubleValue = 0;
+    goto doneNumeric;
+
+inNumberAfterDecimalPoint:
+    while (isASCIIDigit(m_current)) {
+        record8(m_current);
+        shift1();
+    }
+    if ((m_current | 0x20) == 'e') {
+        record8('e');
+        shift1();
+        goto inExponentIndicator;
+    }
+    goto doneNumber;
+
+inExponentIndicator:
+    if (m_current == '+' || m_current == '-') {
+        record8(m_current);
+        shift1();
+    }
+    if (!isASCIIDigit(m_current))
+        goto returnError;
+    do {
+        record8(m_current);
+        shift1();
+    } while (isASCIIDigit(m_current));
+    goto doneNumber;
+
+inOctal: {
+    do {
+        record8(m_current);
+        shift1();
+    } while (isASCIIOctalDigit(m_current));
+    if (isASCIIDigit(m_current))
+        goto startNumber;
 
-    if (m_state != Identifier)
-        m_eatNextIdentifier = false;
+    double dval = 0;
 
-    m_restrKeyword = false;
-    m_delimited = false;
-    llocp->first_line = yylineno;
-    llocp->last_line = yylineno;
-    llocp->first_column = startOffset;
-    llocp->last_column = m_currentOffset;
-    switch (m_state) {
-        case Eof:
-            token = 0;
-            break;
-        case Other:
-            if (token == '}' || token == ';')
-                m_delimited = true;
-            break;
-        case Identifier:
-            // Apply anonymous-function hack below (eat the identifier).
-            if (m_eatNextIdentifier) {
-                m_eatNextIdentifier = false;
-                token = lex(lvalp, llocp);
-                break;
-            }
-            lvalp->ident = makeIdentifier(m_buffer16);
-            token = IDENT;
-            break;
-        case IdentifierOrKeyword: {
-            lvalp->ident = makeIdentifier(m_buffer16);
-            const HashEntry* entry = m_mainTable.entry(m_globalData, *lvalp->ident);
-            if (!entry) {
-                // Lookup for keyword failed, means this is an identifier.
-                token = IDENT;
-                break;
-            }
-            token = entry->lexerValue();
-            // Hack for "f = function somename() { ... }"; too hard to get into the grammar.
-            m_eatNextIdentifier = token == FUNCTION && m_lastToken == '=';
-            if (token == CONTINUE || token == BREAK || token == RETURN || token == THROW)
-                m_restrKeyword = true;
-            break;
-        }
-        case String:
-            // Atomize constant strings in case they're later used in property lookup.
-            lvalp->ident = makeIdentifier(m_buffer16);
-            token = STRING;
-            break;
-        case Number:
-            lvalp->doubleValue = dval;
-            token = NUMBER;
-            break;
-        case Bad:
-#ifdef JSC_DEBUG_LEX
-            fprintf(stderr, "yylex: ERROR.\n");
-#endif
-            m_error = true;
-            return -1;
-        default:
-            ASSERT(!"unhandled numeration value in switch");
-            m_error = true;
-            return -1;
+    const char* end = m_buffer8.end();
+    for (const char* p = m_buffer8.data(); p < end; ++p) {
+        dval *= 8;
+        dval += *p - '0';
     }
-    m_lastToken = token;
-    return token;
-}
+    if (dval >= mantissaOverflowLowerBound)
+        dval = parseIntOverflow(m_buffer8.data(), end - m_buffer8.data(), 8);
 
-bool Lexer::isWhiteSpace() const
-{
-    return m_current == '\t' || m_current == 0x0b || m_current == 0x0c || isSeparatorSpace(m_current);
-}
+    m_buffer8.resize(0);
 
-bool Lexer::isLineTerminator()
-{
-    bool cr = (m_current == '\r');
-    bool lf = (m_current == '\n');
-    if (cr)
-        m_skipLF = true;
-    else if (lf)
-        m_skipCR = true;
-    return cr || lf || m_current == 0x2028 || m_current == 0x2029;
+    lvalp->doubleValue = dval;
+    goto doneNumeric;
 }
 
-bool Lexer::isIdentStart(int c)
-{
-    return isASCIIAlpha(c) || c == '$' || c == '_' || (!isASCII(c) && (category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other)));
-}
+inHex: {
+    do {
+        record8(m_current);
+        shift1();
+    } while (isASCIIHexDigit(m_current));
 
-bool Lexer::isIdentPart(int c)
-{
-    return isASCIIAlphanumeric(c) || c == '$' || c == '_' || (!isASCII(c) && (category(c) & (Letter_Uppercase | Letter_Lowercase | Letter_Titlecase | Letter_Modifier | Letter_Other
-                            | Mark_NonSpacing | Mark_SpacingCombining | Number_DecimalDigit | Punctuation_Connector)));
-}
+    double dval = 0;
 
-static bool isDecimalDigit(int c)
-{
-    return isASCIIDigit(c);
-}
+    const char* end = m_buffer8.end();
+    for (const char* p = m_buffer8.data(); p < end; ++p) {
+        dval *= 16;
+        dval += toASCIIHexValue(*p);
+    }
+    if (dval >= mantissaOverflowLowerBound)
+        dval = parseIntOverflow(m_buffer8.data(), end - m_buffer8.data(), 16);
 
-bool Lexer::isHexDigit(int c)
-{
-    return isASCIIHexDigit(c); 
-}
+    m_buffer8.resize(0);
 
-bool Lexer::isOctalDigit(int c)
-{
-    return isASCIIOctalDigit(c);
+    lvalp->doubleValue = dval;
+    goto doneNumeric;
 }
 
-int Lexer::matchPunctuator(int& charPos, int c1, int c2, int c3, int c4)
-{
-    if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
-        shift(4);
-        return URSHIFTEQUAL;
-    }
-    if (c1 == '=' && c2 == '=' && c3 == '=') {
-        shift(3);
-        return STREQ;
-    }
-    if (c1 == '!' && c2 == '=' && c3 == '=') {
-        shift(3);
-        return STRNEQ;
-    }
-    if (c1 == '>' && c2 == '>' && c3 == '>') {
-        shift(3);
-        return URSHIFT;
-    }
-    if (c1 == '<' && c2 == '<' && c3 == '=') {
-        shift(3);
-        return LSHIFTEQUAL;
-    }
-    if (c1 == '>' && c2 == '>' && c3 == '=') {
-        shift(3);
-        return RSHIFTEQUAL;
-    }
-    if (c1 == '<' && c2 == '=') {
-        shift(2);
-        return LE;
-    }
-    if (c1 == '>' && c2 == '=') {
-        shift(2);
-        return GE;
-    }
-    if (c1 == '!' && c2 == '=') {
-        shift(2);
-        return NE;
-    }
-    if (c1 == '+' && c2 == '+') {
-        shift(2);
-        if (m_terminator)
-            return AUTOPLUSPLUS;
-        return PLUSPLUS;
-    }
-    if (c1 == '-' && c2 == '-') {
-        shift(2);
-        if (m_terminator)
-            return AUTOMINUSMINUS;
-        return MINUSMINUS;
-    }
-    if (c1 == '=' && c2 == '=') {
-        shift(2);
-        return EQEQ;
-    }
-    if (c1 == '+' && c2 == '=') {
-        shift(2);
-        return PLUSEQUAL;
-    }
-    if (c1 == '-' && c2 == '=') {
-        shift(2);
-        return MINUSEQUAL;
-    }
-    if (c1 == '*' && c2 == '=') {
-        shift(2);
-        return MULTEQUAL;
-    }
-    if (c1 == '/' && c2 == '=') {
-        shift(2);
-        return DIVEQUAL;
-    }
-    if (c1 == '&' && c2 == '=') {
-        shift(2);
-        return ANDEQUAL;
-    }
-    if (c1 == '^' && c2 == '=') {
-        shift(2);
-        return XOREQUAL;
-    }
-    if (c1 == '%' && c2 == '=') {
-        shift(2);
-        return MODEQUAL;
-    }
-    if (c1 == '|' && c2 == '=') {
-        shift(2);
-        return OREQUAL;
-    }
-    if (c1 == '<' && c2 == '<') {
-        shift(2);
-        return LSHIFT;
-    }
-    if (c1 == '>' && c2 == '>') {
-        shift(2);
-        return RSHIFT;
+startNumber:
+    record8(m_current);
+    shift1();
+    while (isASCIIDigit(m_current)) {
+        record8(m_current);
+        shift1();
     }
-    if (c1 == '&' && c2 == '&') {
-        shift(2);
-        return AND;
+    if (m_current == '.') {
+        record8('.');
+        shift1();
+        goto inNumberAfterDecimalPoint;
     }
-    if (c1 == '|' && c2 == '|') {
-        shift(2);
-        return OR;
+    if ((m_current | 0x20) == 'e') {
+        record8('e');
+        shift1();
+        goto inExponentIndicator;
     }
 
-    switch (c1) {
-        case '=':
-        case '>':
-        case '<':
-        case ',':
-        case '!':
-        case '~':
-        case '?':
-        case ':':
-        case '.':
-        case '+':
-        case '-':
-        case '*':
-        case '/':
-        case '&':
-        case '|':
-        case '^':
-        case '%':
-        case '(':
-        case ')':
-        case '[':
-        case ']':
-        case ';':
-            shift(1);
-            return static_cast<int>(c1);
-        case '{':
-            charPos = m_currentOffset;
-            shift(1);
-            return OPENBRACE;
-        case '}':
-            charPos = m_currentOffset;
-            shift(1);
-            return CLOSEBRACE;
-        default:
-            return -1;
-    }
-}
+    // Fall through into doneNumber.
 
-unsigned short Lexer::singleEscape(unsigned short c)
-{
-    switch (c) {
-        case 'b':
-            return 0x08;
-        case 't':
-            return 0x09;
-        case 'n':
-            return 0x0A;
-        case 'v':
-            return 0x0B;
-        case 'f':
-            return 0x0C;
-        case 'r':
-            return 0x0D;
-        case '"':
-            return 0x22;
-        case '\'':
-            return 0x27;
-        case '\\':
-            return 0x5C;
-        default:
-            return c;
-    }
-}
+doneNumber:
+    // Null-terminate string for strtod.
+    m_buffer8.append('\0');
+    lvalp->doubleValue = WTF::strtod(m_buffer8.data(), 0);
+    m_buffer8.resize(0);
 
-unsigned short Lexer::convertOctal(int c1, int c2, int c3)
-{
-    return static_cast<unsigned short>((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0');
-}
+    // Fall through into doneNumeric.
 
-unsigned char Lexer::convertHex(int c)
-{
-    if (c >= '0' && c <= '9')
-        return static_cast<unsigned char>(c - '0');
-    if (c >= 'a' && c <= 'f')
-        return static_cast<unsigned char>(c - 'a' + 10);
-    return static_cast<unsigned char>(c - 'A' + 10);
-}
+doneNumeric:
+    // No identifiers allowed directly after numeric literal, e.g. "3in" is bad.
+    if (UNLIKELY(isIdentStart(m_current)))
+        goto returnError;
 
-unsigned char Lexer::convertHex(int c1, int c2)
-{
-    return ((convertHex(c1) << 4) + convertHex(c2));
-}
+    m_atLineStart = false;
+    m_delimited = false;
+    token = NUMBER;
+    goto returnToken;
 
-UChar Lexer::convertUnicode(int c1, int c2, int c3, int c4)
-{
-    unsigned char highByte = (convertHex(c1) << 4) + convertHex(c2);
-    unsigned char lowByte = (convertHex(c3) << 4) + convertHex(c4);
-    return (highByte << 8 | lowByte);
-}
+doneSemicolon:
+    token = ';';
+    m_delimited = true;
+    goto returnToken;
 
-void Lexer::record8(int c)
-{
-    ASSERT(c >= 0);
-    ASSERT(c <= 0xff);
-    m_buffer8.append(static_cast<char>(c));
+doneIdentifier:
+    m_atLineStart = false;
+    m_delimited = false;
+    lvalp->ident = makeIdentifier(m_buffer16.data(), m_buffer16.size());
+    m_buffer16.resize(0);
+    token = IDENT;
+    goto returnToken;
+
+doneIdentifierOrKeyword: {
+    m_atLineStart = false;
+    m_delimited = false;
+    m_buffer16.resize(0);
+    const HashEntry* entry = m_keywordTable.entry(m_globalData, *lvalp->ident);
+    token = entry ? entry->lexerValue() : IDENT;
+    goto returnToken;
 }
 
-void Lexer::record16(int c)
-{
-    ASSERT(c >= 0);
-    ASSERT(c <= USHRT_MAX);
-    record16(UChar(static_cast<unsigned short>(c)));
+doneString:
+    // Atomize constant strings in case they're later used in property lookup.
+    shift1();
+    m_atLineStart = false;
+    m_delimited = false;
+    lvalp->ident = makeIdentifier(m_buffer16.data(), m_buffer16.size());
+    m_buffer16.resize(0);
+    token = STRING;
+
+    // Fall through into returnToken.
+
+returnToken: {
+    int lineNumber = m_lineNumber;
+    llocp->first_line = lineNumber;
+    llocp->last_line = lineNumber;
+    llocp->first_column = startOffset;
+    llocp->last_column = currentOffset();
+
+    m_lastToken = token;
+    return token;
 }
 
-void Lexer::record16(UChar c)
-{
-    m_buffer16.append(c);
+returnError:
+    m_error = true;
+    return -1;
 }
 
 bool Lexer::scanRegExp()
 {
-    m_buffer16.clear();
+    ASSERT(m_buffer16.isEmpty());
+
     bool lastWasEscape = false;
     bool inBrackets = false;
 
-    while (1) {
-        if (isLineTerminator() || m_current == -1)
+    while (true) {
+        if (isLineTerminator(m_current) || m_current == -1)
             return false;
-        else if (m_current != '/' || lastWasEscape == true || inBrackets == true) {
+        if (m_current != '/' || lastWasEscape || inBrackets) {
             // keep track of '[' and ']'
             if (!lastWasEscape) {
-                if ( m_current == '[' && !inBrackets )
+                if (m_current == '[' && !inBrackets)
                     inBrackets = true;
-                if ( m_current == ']' && inBrackets )
+                if (m_current == ']' && inBrackets)
                     inBrackets = false;
             }
             record16(m_current);
-            lastWasEscape =
-            !lastWasEscape && (m_current == '\\');
+            lastWasEscape = !lastWasEscape && m_current == '\\';
         } else { // end of regexp
             m_pattern = UString(m_buffer16);
-            m_buffer16.clear();
-            shift(1);
+            m_buffer16.resize(0);
+            shift1();
             break;
         }
-        shift(1);
+        shift1();
     }
 
     while (isIdentPart(m_current)) {
         record16(m_current);
-        shift(1);
+        shift1();
     }
     m_flags = UString(m_buffer16);
+    m_buffer16.resize(0);
 
     return true;
 }
@@ -882,6 +950,7 @@ bool Lexer::scanRegExp()
 void Lexer::clear()
 {
     m_identifiers.clear();
+    m_codeWithoutBOMs.clear();
 
     Vector<char> newBuffer8;
     newBuffer8.reserveInitialCapacity(initialReadBufferCapacity);
@@ -893,8 +962,30 @@ void Lexer::clear()
 
     m_isReparsing = false;
 
-    m_pattern = 0;
-    m_flags = 0;
+    m_pattern = UString();
+    m_flags = UString();
+}
+
+SourceCode Lexer::sourceCode(int openBrace, int closeBrace, int firstLine)
+{
+    if (m_codeWithoutBOMs.isEmpty())
+        return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine);
+
+    const UChar* data = m_source->provider()->data();
+
+    ASSERT(openBrace < closeBrace);
+
+    int numBOMsBeforeOpenBrace = 0;
+    int numBOMsBetweenBraces = 0;
+
+    int i;
+    for (i = m_source->startOffset(); i < openBrace; ++i)
+        numBOMsBeforeOpenBrace += data[i] == byteOrderMark;
+    for (; i < closeBrace; ++i)
+        numBOMsBetweenBraces += data[i] == byteOrderMark;
+
+    return SourceCode(m_source->provider(), openBrace + numBOMsBeforeOpenBrace,
+        closeBrace + numBOMsBeforeOpenBrace + numBOMsBetweenBraces + 1, firstLine);
 }
 
 } // namespace JSC
index 63d38927e0a93a27a319aa795bea017963d3b79e..0e1b6188e0f28b19b572affb97ebcc1a631f1c34 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 #ifndef Lexer_h
 #define Lexer_h
 
-#include "Identifier.h"
 #include "Lookup.h"
-#include "SegmentedVector.h"
 #include "SourceCode.h"
+#include <wtf/ASCIICType.h>
+#include <wtf/SegmentedVector.h>
 #include <wtf/Vector.h>
+#include <wtf/unicode/Unicode.h>
 
 namespace JSC {
 
@@ -34,115 +35,71 @@ namespace JSC {
 
     class Lexer : Noncopyable {
     public:
+        // Character manipulation functions.
+        static bool isWhiteSpace(int character);
+        static bool isLineTerminator(int character);
+        static unsigned char convertHex(int c1, int c2);
+        static UChar convertUnicode(int c1, int c2, int c3, int c4);
+
+        // Functions to set up parsing.
         void setCode(const SourceCode&);
         void setIsReparsing() { m_isReparsing = true; }
-        int lex(void* lvalp, void* llocp);
-
-        int lineNo() const { return yylineno; }
 
+        // Functions for the parser itself.
+        int lex(void* lvalp, void* llocp);
+        int lineNumber() const { return m_lineNumber; }
         bool prevTerminator() const { return m_terminator; }
-
-        enum State {
-            Start,
-            IdentifierOrKeyword,
-            Identifier,
-            InIdentifierOrKeyword,
-            InIdentifier,
-            InIdentifierStartUnicodeEscapeStart,
-            InIdentifierStartUnicodeEscape,
-            InIdentifierPartUnicodeEscapeStart,
-            InIdentifierPartUnicodeEscape,
-            InSingleLineComment,
-            InMultiLineComment,
-            InNum,
-            InNum0,
-            InHex,
-            InOctal,
-            InDecimal,
-            InExponentIndicator,
-            InExponent,
-            Hex,
-            Octal,
-            Number,
-            String,
-            Eof,
-            InString,
-            InEscapeSequence,
-            InHexEscape,
-            InUnicodeEscape,
-            Other,
-            Bad
-        };
-
+        SourceCode sourceCode(int openBrace, int closeBrace, int firstLine);
         bool scanRegExp();
         const UString& pattern() const { return m_pattern; }
         const UString& flags() const { return m_flags; }
 
-        static unsigned char convertHex(int);
-        static unsigned char convertHex(int c1, int c2);
-        static UChar convertUnicode(int c1, int c2, int c3, int c4);
-        static bool isIdentStart(int);
-        static bool isIdentPart(int);
-        static bool isHexDigit(int);
-
+        // Functions for use after parsing.
         bool sawError() const { return m_error; }
-
         void clear();
-        SourceCode sourceCode(int openBrace, int closeBrace, int firstLine) { return SourceCode(m_source->provider(), openBrace, closeBrace + 1, firstLine); }
 
     private:
         friend class JSGlobalData;
+
         Lexer(JSGlobalData*);
         ~Lexer();
 
-        void setDone(State);
-        void shift(unsigned int p);
-        void nextLine();
-        int lookupKeyword(const char *);
-
-        bool isWhiteSpace() const;
-        bool isLineTerminator();
-        static bool isOctalDigit(int);
-
-        ALWAYS_INLINE int matchPunctuator(int& charPos, int c1, int c2, int c3, int c4);
-        static unsigned short singleEscape(unsigned short);
-        static unsigned short convertOctal(int c1, int c2, int c3);
+        void shift1();
+        void shift2();
+        void shift3();
+        void shift4();
+        void shiftLineTerminator();
 
         void record8(int);
         void record16(int);
         void record16(UChar);
 
-        JSC::Identifier* makeIdentifier(const Vector<UChar>& buffer)
-        {
-            m_identifiers.append(JSC::Identifier(m_globalData, buffer.data(), buffer.size()));
-            return &m_identifiers.last();
-        }
+        void copyCodeWithoutBOMs();
+
+        int currentOffset() const;
+        const UChar* currentCharacter() const;
+
+        JSC::Identifier* makeIdentifier(const UChar* buffer, size_t length);
+
+        bool lastTokenWasRestrKeyword() const;
 
         static const size_t initialReadBufferCapacity = 32;
         static const size_t initialIdentifierTableCapacity = 64;
 
-        int yylineno;
-        int yycolumn;
+        int m_lineNumber;
 
-        bool m_done;
         Vector<char> m_buffer8;
         Vector<UChar> m_buffer16;
         bool m_terminator;
-        bool m_restrKeyword;
         bool m_delimited; // encountered delimiter like "'" and "}" on last run
-        bool m_skipLF;
-        bool m_skipCR;
-        bool m_eatNextIdentifier;
-        int m_stackToken;
         int m_lastToken;
 
-        State m_state;
-        unsigned int m_position;
         const SourceCode* m_source;
         const UChar* m_code;
-        unsigned int m_length;
+        const UChar* m_codeStart;
+        const UChar* m_codeEnd;
         bool m_isReparsing;
-        int m_atLineStart;
+        bool m_atLineStart;
         bool m_error;
 
         // current and following unicode characters (int to allow for -1 for end-of-file marker)
@@ -151,21 +108,38 @@ namespace JSC {
         int m_next2;
         int m_next3;
         
-        int m_currentOffset;
-        int m_nextOffset1;
-        int m_nextOffset2;
-        int m_nextOffset3;
-        
-        SegmentedVector<JSC::Identifier, initialIdentifierTableCapacity> m_identifiers;
+        WTF::SegmentedVector<JSC::Identifier, initialIdentifierTableCapacity> m_identifiers;
 
         JSGlobalData* m_globalData;
 
         UString m_pattern;
         UString m_flags;
 
-        const HashTable m_mainTable;
+        const HashTable m_keywordTable;
+
+        Vector<UChar> m_codeWithoutBOMs;
     };
 
+    inline bool Lexer::isWhiteSpace(int ch)
+    {
+        return isASCII(ch) ? (ch == ' ' || ch == '\t' || ch == 0xB || ch == 0xC) : WTF::Unicode::isSeparatorSpace(ch);
+    }
+
+    inline bool Lexer::isLineTerminator(int ch)
+    {
+        return ch == '\r' || ch == '\n' || (ch & ~1) == 0x2028;
+    }
+
+    inline unsigned char Lexer::convertHex(int c1, int c2)
+    {
+        return (toASCIIHexValue(c1) << 4) | toASCIIHexValue(c2);
+    }
+
+    inline UChar Lexer::convertUnicode(int c1, int c2, int c3, int c4)
+    {
+        return (convertHex(c1, c2) << 8) | convertHex(c3, c4);
+    }
+
 } // namespace JSC
 
 #endif // Lexer_h
diff --git a/parser/NodeConstructors.h b/parser/NodeConstructors.h
new file mode 100644 (file)
index 0000000..d17da69
--- /dev/null
@@ -0,0 +1,911 @@
+/*
+ *  Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NodeConstructors_h
+#define NodeConstructors_h
+
+#include "Nodes.h"
+#include "Lexer.h"
+#include "Parser.h"
+
+namespace JSC {
+
+    inline void* ParserArenaDeletable::operator new(size_t size, JSGlobalData* globalData)
+    {
+        ParserArenaDeletable* deletable = static_cast<ParserArenaDeletable*>(fastMalloc(size));
+        globalData->parser->arena().deleteWithArena(deletable);
+        return deletable;
+    }
+
+    inline void* ParserArenaDeletable::operator new(size_t size)
+    {
+        return fastMalloc(size);
+    }
+
+    inline ParserArenaRefCounted::ParserArenaRefCounted(JSGlobalData* globalData)
+    {
+        globalData->parser->arena().derefWithArena(adoptRef(this));
+    }
+
+    inline Node::Node(JSGlobalData* globalData)
+        : m_line(globalData->lexer->lineNumber())
+    {
+    }
+
+    inline ExpressionNode::ExpressionNode(JSGlobalData* globalData, ResultType resultType)
+        : Node(globalData)
+        , m_resultType(resultType)
+    {
+    }
+
+    inline StatementNode::StatementNode(JSGlobalData* globalData)
+        : Node(globalData)
+        , m_lastLine(-1)
+    {
+    }
+
+    inline NullNode::NullNode(JSGlobalData* globalData)
+        : ExpressionNode(globalData, ResultType::nullType())
+    {
+    }
+
+    inline BooleanNode::BooleanNode(JSGlobalData* globalData, bool value)
+        : ExpressionNode(globalData, ResultType::booleanType())
+        , m_value(value)
+    {
+    }
+
+    inline NumberNode::NumberNode(JSGlobalData* globalData, double v)
+        : ExpressionNode(globalData, ResultType::numberType())
+        , m_double(v)
+    {
+    }
+
+    inline StringNode::StringNode(JSGlobalData* globalData, const Identifier& v)
+        : ExpressionNode(globalData, ResultType::stringType())
+        , m_value(v)
+    {
+    }
+
+    inline RegExpNode::RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags)
+        : ExpressionNode(globalData)
+        , m_pattern(pattern)
+        , m_flags(flags)
+    {
+    }
+
+    inline ThisNode::ThisNode(JSGlobalData* globalData)
+        : ExpressionNode(globalData)
+    {
+    }
+
+    inline ResolveNode::ResolveNode(JSGlobalData* globalData, const Identifier& ident, int startOffset)
+        : ExpressionNode(globalData)
+        , m_ident(ident)
+        , m_startOffset(startOffset)
+    {
+    }
+
+    inline ElementNode::ElementNode(JSGlobalData*, int elision, ExpressionNode* node)
+        : m_next(0)
+        , m_elision(elision)
+        , m_node(node)
+    {
+    }
+
+    inline ElementNode::ElementNode(JSGlobalData*, ElementNode* l, int elision, ExpressionNode* node)
+        : m_next(0)
+        , m_elision(elision)
+        , m_node(node)
+    {
+        l->m_next = this;
+    }
+
+    inline ArrayNode::ArrayNode(JSGlobalData* globalData, int elision)
+        : ExpressionNode(globalData)
+        , m_element(0)
+        , m_elision(elision)
+        , m_optional(true)
+    {
+    }
+
+    inline ArrayNode::ArrayNode(JSGlobalData* globalData, ElementNode* element)
+        : ExpressionNode(globalData)
+        , m_element(element)
+        , m_elision(0)
+        , m_optional(false)
+    {
+    }
+
+    inline ArrayNode::ArrayNode(JSGlobalData* globalData, int elision, ElementNode* element)
+        : ExpressionNode(globalData)
+        , m_element(element)
+        , m_elision(elision)
+        , m_optional(true)
+    {
+    }
+
+    inline PropertyNode::PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* assign, Type type)
+        : m_name(name)
+        , m_assign(assign)
+        , m_type(type)
+    {
+    }
+
+    inline PropertyListNode::PropertyListNode(JSGlobalData* globalData, PropertyNode* node)
+        : Node(globalData)
+        , m_node(node)
+        , m_next(0)
+    {
+    }
+
+    inline PropertyListNode::PropertyListNode(JSGlobalData* globalData, PropertyNode* node, PropertyListNode* list)
+        : Node(globalData)
+        , m_node(node)
+        , m_next(0)
+    {
+        list->m_next = this;
+    }
+
+    inline ObjectLiteralNode::ObjectLiteralNode(JSGlobalData* globalData)
+        : ExpressionNode(globalData)
+        , m_list(0)
+    {
+    }
+
+    inline ObjectLiteralNode::ObjectLiteralNode(JSGlobalData* globalData, PropertyListNode* list)
+        : ExpressionNode(globalData)
+        , m_list(list)
+    {
+    }
+
+    inline BracketAccessorNode::BracketAccessorNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments)
+        : ExpressionNode(globalData)
+        , m_base(base)
+        , m_subscript(subscript)
+        , m_subscriptHasAssignments(subscriptHasAssignments)
+    {
+    }
+
+    inline DotAccessorNode::DotAccessorNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident)
+        : ExpressionNode(globalData)
+        , m_base(base)
+        , m_ident(ident)
+    {
+    }
+
+    inline ArgumentListNode::ArgumentListNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : Node(globalData)
+        , m_next(0)
+        , m_expr(expr)
+    {
+    }
+
+    inline ArgumentListNode::ArgumentListNode(JSGlobalData* globalData, ArgumentListNode* listNode, ExpressionNode* expr)
+        : Node(globalData)
+        , m_next(0)
+        , m_expr(expr)
+    {
+        listNode->m_next = this;
+    }
+
+    inline ArgumentsNode::ArgumentsNode(JSGlobalData*)
+        : m_listNode(0)
+    {
+    }
+
+    inline ArgumentsNode::ArgumentsNode(JSGlobalData*, ArgumentListNode* listNode)
+        : m_listNode(listNode)
+    {
+    }
+
+    inline NewExprNode::NewExprNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : ExpressionNode(globalData)
+        , m_expr(expr)
+        , m_args(0)
+    {
+    }
+
+    inline NewExprNode::NewExprNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args)
+        : ExpressionNode(globalData)
+        , m_expr(expr)
+        , m_args(args)
+    {
+    }
+
+    inline EvalFunctionCallNode::EvalFunctionCallNode(JSGlobalData* globalData, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_args(args)
+    {
+    }
+
+    inline FunctionCallValueNode::FunctionCallValueNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_expr(expr)
+        , m_args(args)
+    {
+    }
+
+    inline FunctionCallResolveNode::FunctionCallResolveNode(JSGlobalData* globalData, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_ident(ident)
+        , m_args(args)
+    {
+    }
+
+    inline FunctionCallBracketNode::FunctionCallBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableSubExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_subscript(subscript)
+        , m_args(args)
+    {
+    }
+
+    inline FunctionCallDotNode::FunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableSubExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_ident(ident)
+        , m_args(args)
+    {
+    }
+
+    inline CallFunctionCallDotNode::CallFunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : FunctionCallDotNode(globalData, base, ident, args, divot, startOffset, endOffset)
+    {
+    }
+
+    inline ApplyFunctionCallDotNode::ApplyFunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : FunctionCallDotNode(globalData, base, ident, args, divot, startOffset, endOffset)
+    {
+    }
+
+    inline PrePostResolveNode::PrePostResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData, ResultType::numberType()) // could be reusable for pre?
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_ident(ident)
+    {
+    }
+
+    inline PostfixResolveNode::PostfixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
+        , m_operator(oper)
+    {
+    }
+
+    inline PostfixBracketNode::PostfixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableSubExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_subscript(subscript)
+        , m_operator(oper)
+    {
+    }
+
+    inline PostfixDotNode::PostfixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableSubExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_ident(ident)
+        , m_operator(oper)
+    {
+    }
+
+    inline PostfixErrorNode::PostfixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableSubExpressionData(divot, startOffset, endOffset)
+        , m_expr(expr)
+        , m_operator(oper)
+    {
+    }
+
+    inline DeleteResolveNode::DeleteResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_ident(ident)
+    {
+    }
+
+    inline DeleteBracketNode::DeleteBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_subscript(subscript)
+    {
+    }
+
+    inline DeleteDotNode::DeleteDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_ident(ident)
+    {
+    }
+
+    inline DeleteValueNode::DeleteValueNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : ExpressionNode(globalData)
+        , m_expr(expr)
+    {
+    }
+
+    inline VoidNode::VoidNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : ExpressionNode(globalData)
+        , m_expr(expr)
+    {
+    }
+
+    inline TypeOfResolveNode::TypeOfResolveNode(JSGlobalData* globalData, const Identifier& ident)
+        : ExpressionNode(globalData, ResultType::stringType())
+        , m_ident(ident)
+    {
+    }
+
+    inline TypeOfValueNode::TypeOfValueNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : ExpressionNode(globalData, ResultType::stringType())
+        , m_expr(expr)
+    {
+    }
+
+    inline PrefixResolveNode::PrefixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
+        , m_operator(oper)
+    {
+    }
+
+    inline PrefixBracketNode::PrefixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_subscript(subscript)
+        , m_operator(oper)
+    {
+    }
+
+    inline PrefixDotNode::PrefixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_ident(ident)
+        , m_operator(oper)
+    {
+    }
+
+    inline PrefixErrorNode::PrefixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_expr(expr)
+        , m_operator(oper)
+    {
+    }
+
+    inline UnaryOpNode::UnaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr, OpcodeID opcodeID)
+        : ExpressionNode(globalData, type)
+        , m_expr(expr)
+        , m_opcodeID(opcodeID)
+    {
+    }
+
+    inline UnaryPlusNode::UnaryPlusNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : UnaryOpNode(globalData, ResultType::numberType(), expr, op_to_jsnumber)
+    {
+    }
+
+    inline NegateNode::NegateNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : UnaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr, op_negate)
+    {
+    }
+
+    inline BitwiseNotNode::BitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : UnaryOpNode(globalData, ResultType::forBitOp(), expr, op_bitnot)
+    {
+    }
+
+    inline LogicalNotNode::LogicalNotNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : UnaryOpNode(globalData, ResultType::booleanType(), expr, op_not)
+    {
+    }
+
+    inline BinaryOpNode::BinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+        : ExpressionNode(globalData)
+        , m_expr1(expr1)
+        , m_expr2(expr2)
+        , m_opcodeID(opcodeID)
+        , m_rightHasAssignments(rightHasAssignments)
+    {
+    }
+
+    inline BinaryOpNode::BinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+        : ExpressionNode(globalData, type)
+        , m_expr1(expr1)
+        , m_expr2(expr2)
+        , m_opcodeID(opcodeID)
+        , m_rightHasAssignments(rightHasAssignments)
+    {
+    }
+
+    inline ReverseBinaryOpNode::ReverseBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+        : BinaryOpNode(globalData, expr1, expr2, opcodeID, rightHasAssignments)
+    {
+    }
+
+    inline ReverseBinaryOpNode::ReverseBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+        : BinaryOpNode(globalData, type, expr1, expr2, opcodeID, rightHasAssignments)
+    {
+    }
+
+    inline MultNode::MultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, op_mul, rightHasAssignments)
+    {
+    }
+
+    inline DivNode::DivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, op_div, rightHasAssignments)
+    {
+    }
+
+
+    inline ModNode::ModNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, op_mod, rightHasAssignments)
+    {
+    }
+
+    inline AddNode::AddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::forAdd(expr1->resultDescriptor(), expr2->resultDescriptor()), expr1, expr2, op_add, rightHasAssignments)
+    {
+    }
+
+    inline SubNode::SubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, op_sub, rightHasAssignments)
+    {
+    }
+
+    inline LeftShiftNode::LeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, op_lshift, rightHasAssignments)
+    {
+    }
+
+    inline RightShiftNode::RightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, op_rshift, rightHasAssignments)
+    {
+    }
+
+    inline UnsignedRightShiftNode::UnsignedRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, op_urshift, rightHasAssignments)
+    {
+    }
+
+    inline LessNode::LessNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_less, rightHasAssignments)
+    {
+    }
+
+    inline GreaterNode::GreaterNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_less, rightHasAssignments)
+    {
+    }
+
+    inline LessEqNode::LessEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_lesseq, rightHasAssignments)
+    {
+    }
+
+    inline GreaterEqNode::GreaterEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_lesseq, rightHasAssignments)
+    {
+    }
+
+    inline ThrowableBinaryOpNode::ThrowableBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+        : BinaryOpNode(globalData, type, expr1, expr2, opcodeID, rightHasAssignments)
+    {
+    }
+
+    inline ThrowableBinaryOpNode::ThrowableBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID opcodeID, bool rightHasAssignments)
+        : BinaryOpNode(globalData, expr1, expr2, opcodeID, rightHasAssignments)
+    {
+    }
+
+    inline InstanceOfNode::InstanceOfNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : ThrowableBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_instanceof, rightHasAssignments)
+    {
+    }
+
+    inline InNode::InNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : ThrowableBinaryOpNode(globalData, expr1, expr2, op_in, rightHasAssignments)
+    {
+    }
+
+    inline EqualNode::EqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_eq, rightHasAssignments)
+    {
+    }
+
+    inline NotEqualNode::NotEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_neq, rightHasAssignments)
+    {
+    }
+
+    inline StrictEqualNode::StrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_stricteq, rightHasAssignments)
+    {
+    }
+
+    inline NotStrictEqualNode::NotStrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, op_nstricteq, rightHasAssignments)
+    {
+    }
+
+    inline BitAndNode::BitAndNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, op_bitand, rightHasAssignments)
+    {
+    }
+
+    inline BitOrNode::BitOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, op_bitor, rightHasAssignments)
+    {
+    }
+
+    inline BitXOrNode::BitXOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
+        : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, op_bitxor, rightHasAssignments)
+    {
+    }
+
+    inline LogicalOpNode::LogicalOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator oper)
+        : ExpressionNode(globalData, ResultType::booleanType())
+        , m_expr1(expr1)
+        , m_expr2(expr2)
+        , m_operator(oper)
+    {
+    }
+
+    inline ConditionalNode::ConditionalNode(JSGlobalData* globalData, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2)
+        : ExpressionNode(globalData)
+        , m_logical(logical)
+        , m_expr1(expr1)
+        , m_expr2(expr2)
+    {
+    }
+
+    inline ReadModifyResolveNode::ReadModifyResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, ExpressionNode*  right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_ident(ident)
+        , m_right(right)
+        , m_operator(oper)
+        , m_rightHasAssignments(rightHasAssignments)
+    {
+    }
+
+    inline AssignResolveNode::AssignResolveNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments)
+        : ExpressionNode(globalData)
+        , m_ident(ident)
+        , m_right(right)
+        , m_rightHasAssignments(rightHasAssignments)
+    {
+    }
+
+    inline ReadModifyBracketNode::ReadModifyBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableSubExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_subscript(subscript)
+        , m_right(right)
+        , m_operator(oper)
+        , m_subscriptHasAssignments(subscriptHasAssignments)
+        , m_rightHasAssignments(rightHasAssignments)
+    {
+    }
+
+    inline AssignBracketNode::AssignBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_subscript(subscript)
+        , m_right(right)
+        , m_subscriptHasAssignments(subscriptHasAssignments)
+        , m_rightHasAssignments(rightHasAssignments)
+    {
+    }
+
+    inline AssignDotNode::AssignDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_ident(ident)
+        , m_right(right)
+        , m_rightHasAssignments(rightHasAssignments)
+    {
+    }
+
+    inline ReadModifyDotNode::ReadModifyDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableSubExpressionData(divot, startOffset, endOffset)
+        , m_base(base)
+        , m_ident(ident)
+        , m_right(right)
+        , m_operator(oper)
+        , m_rightHasAssignments(rightHasAssignments)
+    {
+    }
+
+    inline AssignErrorNode::AssignErrorNode(JSGlobalData* globalData, ExpressionNode* left, Operator oper, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset)
+        : ExpressionNode(globalData)
+        , ThrowableExpressionData(divot, startOffset, endOffset)
+        , m_left(left)
+        , m_operator(oper)
+        , m_right(right)
+    {
+    }
+
+    inline CommaNode::CommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2)
+        : ExpressionNode(globalData)
+    {
+        m_expressions.append(expr1);
+        m_expressions.append(expr2);
+    }
+
+    inline ConstStatementNode::ConstStatementNode(JSGlobalData* globalData, ConstDeclNode* next)
+        : StatementNode(globalData)
+        , m_next(next)
+    {
+    }
+
+    inline SourceElements::SourceElements(JSGlobalData*)
+    {
+    }
+
+    inline EmptyStatementNode::EmptyStatementNode(JSGlobalData* globalData)
+        : StatementNode(globalData)
+    {
+    }
+
+    inline DebuggerStatementNode::DebuggerStatementNode(JSGlobalData* globalData)
+        : StatementNode(globalData)
+    {
+    }
+    
+    inline ExprStatementNode::ExprStatementNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : StatementNode(globalData)
+        , m_expr(expr)
+    {
+    }
+
+    inline VarStatementNode::VarStatementNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : StatementNode(globalData)
+        , m_expr(expr)
+    {
+    }
+    
+    inline IfNode::IfNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock)
+        : StatementNode(globalData)
+        , m_condition(condition)
+        , m_ifBlock(ifBlock)
+    {
+    }
+
+    inline IfElseNode::IfElseNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock)
+        : IfNode(globalData, condition, ifBlock)
+        , m_elseBlock(elseBlock)
+    {
+    }
+
+    inline DoWhileNode::DoWhileNode(JSGlobalData* globalData, StatementNode* statement, ExpressionNode* expr)
+        : StatementNode(globalData)
+        , m_statement(statement)
+        , m_expr(expr)
+    {
+    }
+
+    inline WhileNode::WhileNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement)
+        : StatementNode(globalData)
+        , m_expr(expr)
+        , m_statement(statement)
+    {
+    }
+
+    inline ForNode::ForNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl)
+        : StatementNode(globalData)
+        , m_expr1(expr1)
+        , m_expr2(expr2)
+        , m_expr3(expr3)
+        , m_statement(statement)
+        , m_expr1WasVarDecl(expr1 && expr1WasVarDecl)
+    {
+        ASSERT(statement);
+    }
+
+    inline ContinueNode::ContinueNode(JSGlobalData* globalData)
+        : StatementNode(globalData)
+    {
+    }
+
+    inline ContinueNode::ContinueNode(JSGlobalData* globalData, const Identifier& ident)
+        : StatementNode(globalData)
+        , m_ident(ident)
+    {
+    }
+    
+    inline BreakNode::BreakNode(JSGlobalData* globalData)
+        : StatementNode(globalData)
+    {
+    }
+
+    inline BreakNode::BreakNode(JSGlobalData* globalData, const Identifier& ident)
+        : StatementNode(globalData)
+        , m_ident(ident)
+    {
+    }
+    
+    inline ReturnNode::ReturnNode(JSGlobalData* globalData, ExpressionNode* value)
+        : StatementNode(globalData)
+        , m_value(value)
+    {
+    }
+
+    inline WithNode::WithNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement, uint32_t divot, uint32_t expressionLength)
+        : StatementNode(globalData)
+        , m_expr(expr)
+        , m_statement(statement)
+        , m_divot(divot)
+        , m_expressionLength(expressionLength)
+    {
+    }
+
+    inline LabelNode::LabelNode(JSGlobalData* globalData, const Identifier& name, StatementNode* statement)
+        : StatementNode(globalData)
+        , m_name(name)
+        , m_statement(statement)
+    {
+    }
+
+    inline ThrowNode::ThrowNode(JSGlobalData* globalData, ExpressionNode* expr)
+        : StatementNode(globalData)
+        , m_expr(expr)
+    {
+    }
+
+    inline TryNode::TryNode(JSGlobalData* globalData, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock)
+        : StatementNode(globalData)
+        , m_tryBlock(tryBlock)
+        , m_exceptionIdent(exceptionIdent)
+        , m_catchBlock(catchBlock)
+        , m_finallyBlock(finallyBlock)
+        , m_catchHasEval(catchHasEval)
+    {
+    }
+
+    inline ParameterNode::ParameterNode(JSGlobalData*, const Identifier& ident)
+        : m_ident(ident)
+        , m_next(0)
+    {
+    }
+
+    inline ParameterNode::ParameterNode(JSGlobalData*, ParameterNode* l, const Identifier& ident)
+        : m_ident(ident)
+        , m_next(0)
+    {
+        l->m_next = this;
+    }
+
+    inline FuncExprNode::FuncExprNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter)
+        : ExpressionNode(globalData)
+        , ParserArenaRefCounted(globalData)
+        , m_ident(ident)
+        , m_body(body)
+    {
+        m_body->finishParsing(source, parameter);
+    }
+
+    inline FuncDeclNode::FuncDeclNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter)
+        : StatementNode(globalData)
+        , ParserArenaRefCounted(globalData)
+        , m_ident(ident)
+        , m_body(body)
+    {
+        m_body->finishParsing(source, parameter);
+    }
+
+    inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr)
+        : m_expr(expr)
+    {
+    }
+
+    inline CaseClauseNode::CaseClauseNode(JSGlobalData*, ExpressionNode* expr, SourceElements* children)
+        : m_expr(expr)
+    {
+        if (children)
+            children->releaseContentsIntoVector(m_children);
+    }
+
+    inline ClauseListNode::ClauseListNode(JSGlobalData*, CaseClauseNode* clause)
+        : m_clause(clause)
+        , m_next(0)
+    {
+    }
+
+    inline ClauseListNode::ClauseListNode(JSGlobalData*, ClauseListNode* clauseList, CaseClauseNode* clause)
+        : m_clause(clause)
+        , m_next(0)
+    {
+        clauseList->m_next = this;
+    }
+
+    inline CaseBlockNode::CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2)
+        : m_list1(list1)
+        , m_defaultClause(defaultClause)
+        , m_list2(list2)
+    {
+    }
+
+    inline SwitchNode::SwitchNode(JSGlobalData* globalData, ExpressionNode* expr, CaseBlockNode* block)
+        : StatementNode(globalData)
+        , m_expr(expr)
+        , m_block(block)
+    {
+    }
+
+    inline ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init)
+        : ExpressionNode(globalData)
+        , m_ident(ident)
+        , m_next(0)
+        , m_init(init)
+    {
+    }
+
+    inline BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
+        : StatementNode(globalData)
+    {
+        if (children)
+            children->releaseContentsIntoVector(m_children);
+    }
+
+    inline ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
+        : StatementNode(globalData)
+        , m_init(0)
+        , m_lexpr(l)
+        , m_expr(expr)
+        , m_statement(statement)
+        , m_identIsVarDecl(false)
+    {
+    }
+
+    inline ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
+        : StatementNode(globalData)
+        , m_ident(ident)
+        , m_init(0)
+        , m_lexpr(new (globalData) ResolveNode(globalData, ident, divot - startOffset))
+        , m_expr(expr)
+        , m_statement(statement)
+        , m_identIsVarDecl(true)
+    {
+        if (in) {
+            AssignResolveNode* node = new (globalData) AssignResolveNode(globalData, ident, in, true);
+            node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
+            m_init = node;
+        }
+        // for( var foo = bar in baz )
+    }
+
+} // namespace JSC
+
+#endif // NodeConstructors_h
index a518b23f4e9508792e2740d3aee63f86663cac9d..7f4deffac9018c2a248138884b89190bca5c5e22 100644 (file)
@@ -43,8 +43,8 @@ namespace JSC {
     
     template <typename T> struct NodeDeclarationInfo {
         T m_node;
-        ParserRefCountedData<DeclarationStacks::VarStack>* m_varDeclarations;
-        ParserRefCountedData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
+        ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
+        ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
         CodeFeatures m_features;
         int m_numConstants;
     };
index 8aa1788d78a8516c0ae1931e1d4aa8ead34bbae4..65de89c27b30d5dece001b158b78b4f8d1cae9b0 100644 (file)
 
 #include "config.h"
 #include "Nodes.h"
+#include "NodeConstructors.h"
 
 #include "BytecodeGenerator.h"
 #include "CallFrame.h"
+#include "Debugger.h"
+#include "JIT.h"
+#include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSStaticScopeObject.h"
 #include "LabelScope.h"
+#include "Lexer.h"
+#include "Operations.h"
 #include "Parser.h"
 #include "PropertyNameArray.h"
 #include "RegExpObject.h"
 #include "SamplingTool.h"
-#include "Debugger.h"
-#include "Lexer.h"
-#include "Operations.h"
-#include <math.h>
 #include <wtf/Assertions.h>
-#include <wtf/HashCountedSet.h>
-#include <wtf/HashSet.h>
-#include <wtf/MathExtras.h>
 #include <wtf/RefCountedLeakCounter.h>
 #include <wtf/Threading.h>
 
@@ -50,173 +49,7 @@ using namespace WTF;
 
 namespace JSC {
 
-static void substitute(UString& string, const UString& substring) JSC_FAST_CALL;
-
-// ------------------------------ NodeReleaser --------------------------------
-
-class NodeReleaser : Noncopyable {
-public:
-    // Call this function inside the destructor of a class derived from Node.
-    // This will traverse the tree below this node, destroying all of those nodes,
-    // but without relying on recursion.
-    static void releaseAllNodes(ParserRefCounted* root);
-
-    // Call this on each node in a the releaseNodes virtual function.
-    // It gives the node to the NodeReleaser, which will then release the
-    // node later at the end of the releaseAllNodes process.
-    template <typename T> void release(RefPtr<T>& node) { if (node) adopt(node.release()); }
-    void release(RefPtr<FunctionBodyNode>& node) { if (node) adoptFunctionBodyNode(node); }
-
-private:
-    NodeReleaser() { }
-    ~NodeReleaser() { }
-
-    void adopt(PassRefPtr<ParserRefCounted>);
-    void adoptFunctionBodyNode(RefPtr<FunctionBodyNode>&);
-
-    typedef Vector<RefPtr<ParserRefCounted> > NodeReleaseVector;
-    OwnPtr<NodeReleaseVector> m_vector;
-};
-
-void NodeReleaser::releaseAllNodes(ParserRefCounted* root)
-{
-    ASSERT(root);
-    NodeReleaser releaser;
-    root->releaseNodes(releaser);
-    if (!releaser.m_vector)
-        return;
-    // Note: The call to release.m_vector->size() is intentionally inside
-    // the loop, since calls to releaseNodes are expected to increase the size.
-    for (size_t i = 0; i < releaser.m_vector->size(); ++i) {
-        ParserRefCounted* node = (*releaser.m_vector)[i].get();
-        if (node->hasOneRef())
-            node->releaseNodes(releaser);
-    }
-}
-
-void NodeReleaser::adopt(PassRefPtr<ParserRefCounted> node)
-{
-    ASSERT(node);
-    if (!node->hasOneRef())
-        return;
-    if (!m_vector)
-        m_vector.set(new NodeReleaseVector);
-    m_vector->append(node);
-}
-
-void NodeReleaser::adoptFunctionBodyNode(RefPtr<FunctionBodyNode>& functionBodyNode)
-{
-    // This sidesteps a problem where if you assign a PassRefPtr<FunctionBodyNode>
-    // to a PassRefPtr<Node> we leave the two reference counts (FunctionBodyNode
-    // and ParserRefCounted) unbalanced. It would be nice to fix this problem in
-    // a cleaner way -- perhaps we could remove the FunctionBodyNode reference
-    // count at some point.
-    RefPtr<Node> node = functionBodyNode;
-    functionBodyNode = 0;
-    adopt(node.release());
-}
-
-// ------------------------------ ParserRefCounted -----------------------------------------
-
-#ifndef NDEBUG
-static RefCountedLeakCounter parserRefCountedCounter("JSC::Node");
-#endif
-
-ParserRefCounted::ParserRefCounted(JSGlobalData* globalData)
-    : m_globalData(globalData)
-{
-#ifndef NDEBUG
-    parserRefCountedCounter.increment();
-#endif
-    if (!m_globalData->newParserObjects)
-        m_globalData->newParserObjects = new HashSet<ParserRefCounted*>;
-    m_globalData->newParserObjects->add(this);
-    ASSERT(m_globalData->newParserObjects->contains(this));
-}
-
-ParserRefCounted::~ParserRefCounted()
-{
-#ifndef NDEBUG
-    parserRefCountedCounter.decrement();
-#endif
-}
-
-void ParserRefCounted::releaseNodes(NodeReleaser&)
-{
-}
-
-void ParserRefCounted::ref()
-{
-    // bumping from 0 to 1 is just removing from the new nodes set
-    if (m_globalData->newParserObjects) {
-        HashSet<ParserRefCounted*>::iterator it = m_globalData->newParserObjects->find(this);
-        if (it != m_globalData->newParserObjects->end()) {
-            m_globalData->newParserObjects->remove(it);
-            ASSERT(!m_globalData->parserObjectExtraRefCounts || !m_globalData->parserObjectExtraRefCounts->contains(this));
-            return;
-        }
-    }
-
-    ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));
-
-    if (!m_globalData->parserObjectExtraRefCounts)
-        m_globalData->parserObjectExtraRefCounts = new HashCountedSet<ParserRefCounted*>;
-    m_globalData->parserObjectExtraRefCounts->add(this);
-}
-
-void ParserRefCounted::deref()
-{
-    ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));
-
-    if (!m_globalData->parserObjectExtraRefCounts) {
-        delete this;
-        return;
-    }
-
-    HashCountedSet<ParserRefCounted*>::iterator it = m_globalData->parserObjectExtraRefCounts->find(this);
-    if (it == m_globalData->parserObjectExtraRefCounts->end())
-        delete this;
-    else
-        m_globalData->parserObjectExtraRefCounts->remove(it);
-}
-
-bool ParserRefCounted::hasOneRef()
-{
-    if (m_globalData->newParserObjects && m_globalData->newParserObjects->contains(this)) {
-        ASSERT(!m_globalData->parserObjectExtraRefCounts || !m_globalData->parserObjectExtraRefCounts->contains(this));
-        return false;
-    }
-
-    ASSERT(!m_globalData->newParserObjects || !m_globalData->newParserObjects->contains(this));
-
-    if (!m_globalData->parserObjectExtraRefCounts)
-        return true;
-
-    return !m_globalData->parserObjectExtraRefCounts->contains(this);
-}
-
-void ParserRefCounted::deleteNewObjects(JSGlobalData* globalData)
-{
-    if (!globalData->newParserObjects)
-        return;
-
-#ifndef NDEBUG
-    HashSet<ParserRefCounted*>::iterator end = globalData->newParserObjects->end();
-    for (HashSet<ParserRefCounted*>::iterator it = globalData->newParserObjects->begin(); it != end; ++it)
-        ASSERT(!globalData->parserObjectExtraRefCounts || !globalData->parserObjectExtraRefCounts->contains(*it));
-#endif
-    deleteAllValues(*globalData->newParserObjects);
-    delete globalData->newParserObjects;
-    globalData->newParserObjects = 0;
-}
-
-// ------------------------------ Node --------------------------------
-
-Node::Node(JSGlobalData* globalData)
-    : ParserRefCounted(globalData)
-{
-    m_line = globalData->lexer->lineNo();
-}
+static void substitute(UString& string, const UString& substring);
 
 // ------------------------------ ThrowableExpressionData --------------------------------
 
@@ -247,14 +80,8 @@ RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator
     generator.emitThrow(exception);
     return exception;
 }
-    
-// ------------------------------ StatementNode --------------------------------
 
-StatementNode::StatementNode(JSGlobalData* globalData)
-    : Node(globalData)
-    , m_lastLine(-1)
-{
-}
+// ------------------------------ StatementNode --------------------------------
 
 void StatementNode::setLoc(int firstLine, int lastLine)
 {
@@ -264,11 +91,10 @@ void StatementNode::setLoc(int firstLine, int lastLine)
 
 // ------------------------------ SourceElements --------------------------------
 
-void SourceElements::append(PassRefPtr<StatementNode> statement)
+void SourceElements::append(StatementNode* statement)
 {
     if (statement->isEmptyStatement())
         return;
-
     m_statements.append(statement);
 }
 
@@ -348,47 +174,24 @@ RegisterID* ResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
     return generator.emitResolve(generator.finalDestination(dst), m_ident);
 }
 
-// ------------------------------ ElementNode ------------------------------------
-
-ElementNode::~ElementNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ElementNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_next);
-    releaser.release(m_node);
-}
-
 // ------------------------------ ArrayNode ------------------------------------
 
-ArrayNode::~ArrayNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ArrayNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_element);
-}
-
 RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     // FIXME: Should we put all of this code into emitNewArray?
 
     unsigned length = 0;
     ElementNode* firstPutElement;
-    for (firstPutElement = m_element.get(); firstPutElement; firstPutElement = firstPutElement->next()) {
+    for (firstPutElement = m_element; firstPutElement; firstPutElement = firstPutElement->next()) {
         if (firstPutElement->elision())
             break;
         ++length;
     }
 
     if (!firstPutElement && !m_elision)
-        return generator.emitNewArray(generator.finalDestination(dst), m_element.get());
+        return generator.emitNewArray(generator.finalDestination(dst), m_element);
 
-    RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element.get());
+    RefPtr<RegisterID> array = generator.emitNewArray(generator.tempDestination(dst), m_element);
 
     for (ElementNode* n = firstPutElement; n; n = n->next()) {
         RegisterID* value = generator.emitNode(n->value());
@@ -404,30 +207,35 @@ RegisterID* ArrayNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
     return generator.moveToDestinationIfNeeded(dst, array.get());
 }
 
-// ------------------------------ PropertyNode ----------------------------
-
-PropertyNode::~PropertyNode()
+bool ArrayNode::isSimpleArray() const
 {
-    NodeReleaser::releaseAllNodes(this);
+    if (m_elision || m_optional)
+        return false;
+    for (ElementNode* ptr = m_element; ptr; ptr = ptr->next()) {
+        if (ptr->elision())
+            return false;
+    }
+    return true;
 }
 
-void PropertyNode::releaseNodes(NodeReleaser& releaser)
+ArgumentListNode* ArrayNode::toArgumentList(JSGlobalData* globalData) const
 {
-    releaser.release(m_assign);
+    ASSERT(!m_elision && !m_optional);
+    ElementNode* ptr = m_element;
+    if (!ptr)
+        return 0;
+    ArgumentListNode* head = new (globalData) ArgumentListNode(globalData, ptr->value());
+    ArgumentListNode* tail = head;
+    ptr = ptr->next();
+    for (; ptr; ptr = ptr->next()) {
+        ASSERT(!ptr->elision());
+        tail = new (globalData) ArgumentListNode(globalData, tail, ptr->value());
+    }
+    return head;
 }
 
 // ------------------------------ ObjectLiteralNode ----------------------------
 
-ObjectLiteralNode::~ObjectLiteralNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ObjectLiteralNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_list);
-}
-
 RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
      if (!m_list) {
@@ -435,30 +243,19 @@ RegisterID* ObjectLiteralNode::emitBytecode(BytecodeGenerator& generator, Regist
              return 0;
          return generator.emitNewObject(generator.finalDestination(dst));
      }
-     return generator.emitNode(dst, m_list.get());
+     return generator.emitNode(dst, m_list);
 }
 
 // ------------------------------ PropertyListNode -----------------------------
 
-PropertyListNode::~PropertyListNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void PropertyListNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_node);
-    releaser.release(m_next);
-}
-
 RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     RefPtr<RegisterID> newObj = generator.tempDestination(dst);
     
     generator.emitNewObject(newObj.get());
     
-    for (PropertyListNode* p = this; p; p = p->m_next.get()) {
-        RegisterID* value = generator.emitNode(p->m_node->m_assign.get());
+    for (PropertyListNode* p = this; p; p = p->m_next) {
+        RegisterID* value = generator.emitNode(p->m_node->m_assign);
         
         switch (p->m_node->m_type) {
             case PropertyNode::Constant: {
@@ -483,152 +280,66 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe
 
 // ------------------------------ BracketAccessorNode --------------------------------
 
-BracketAccessorNode::~BracketAccessorNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void BracketAccessorNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-    releaser.release(m_subscript);
-}
-
 RegisterID* BracketAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments, m_subscript->isPure(generator));
-    RegisterID* property = generator.emitNode(m_subscript.get());
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments, m_subscript->isPure(generator));
+    RegisterID* property = generator.emitNode(m_subscript);
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
 }
 
 // ------------------------------ DotAccessorNode --------------------------------
 
-DotAccessorNode::~DotAccessorNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void DotAccessorNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-}
-
 RegisterID* DotAccessorNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RegisterID* base = generator.emitNode(m_base.get());
+    RegisterID* base = generator.emitNode(m_base);
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
 }
 
 // ------------------------------ ArgumentListNode -----------------------------
 
-ArgumentListNode::~ArgumentListNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ArgumentListNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_next);
-    releaser.release(m_expr);
-}
-
 RegisterID* ArgumentListNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     ASSERT(m_expr);
-    return generator.emitNode(dst, m_expr.get());
-}
-
-// ------------------------------ ArgumentsNode -----------------------------
-
-ArgumentsNode::~ArgumentsNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ArgumentsNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_listNode);
+    return generator.emitNode(dst, m_expr);
 }
 
 // ------------------------------ NewExprNode ----------------------------------
 
-NewExprNode::~NewExprNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void NewExprNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-    releaser.release(m_args);
-}
-
 RegisterID* NewExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
-    return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args.get(), divot(), startOffset(), endOffset());
+    RefPtr<RegisterID> func = generator.emitNode(m_expr);
+    return generator.emitConstruct(generator.finalDestination(dst), func.get(), m_args, divot(), startOffset(), endOffset());
 }
 
 // ------------------------------ EvalFunctionCallNode ----------------------------------
 
-EvalFunctionCallNode::~EvalFunctionCallNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void EvalFunctionCallNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_args);
-}
-
 RegisterID* EvalFunctionCallNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     RefPtr<RegisterID> func = generator.tempDestination(dst);
     RefPtr<RegisterID> thisRegister = generator.newTemporary();
     generator.emitExpressionInfo(divot() - startOffset() + 4, 4, 0);
     generator.emitResolveWithBase(thisRegister.get(), func.get(), generator.propertyNames().eval);
-    return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+    return generator.emitCallEval(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
 }
 
 // ------------------------------ FunctionCallValueNode ----------------------------------
 
-FunctionCallValueNode::~FunctionCallValueNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void FunctionCallValueNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-    releaser.release(m_args);
-}
-
 RegisterID* FunctionCallValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> func = generator.emitNode(m_expr.get());
+    RefPtr<RegisterID> func = generator.emitNode(m_expr);
     RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
-    return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+    return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
 }
 
 // ------------------------------ FunctionCallResolveNode ----------------------------------
 
-FunctionCallResolveNode::~FunctionCallResolveNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void FunctionCallResolveNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_args);
-}
-
 RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     if (RefPtr<RegisterID> local = generator.registerFor(m_ident)) {
         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
-        return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+        return generator.emitCall(generator.finalDestination(dst, thisRegister.get()), local.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
     }
 
     int index = 0;
@@ -637,61 +348,143 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator,
     if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> func = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
         RefPtr<RegisterID> thisRegister = generator.emitLoad(generator.newTemporary(), jsNull());
-        return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+        return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
     }
 
-    RefPtr<RegisterID> func = generator.tempDestination(dst);
+    RefPtr<RegisterID> func = generator.newTemporary();
     RefPtr<RegisterID> thisRegister = generator.newTemporary();
     int identifierStart = divot() - startOffset();
     generator.emitExpressionInfo(identifierStart + m_ident.size(), m_ident.size(), 0);
-    generator.emitResolveFunction(thisRegister.get(), func.get(), m_ident);
-    return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+    generator.emitResolveWithBase(thisRegister.get(), func.get(), m_ident);
+    return generator.emitCall(generator.finalDestination(dst, func.get()), func.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
 }
 
 // ------------------------------ FunctionCallBracketNode ----------------------------------
 
-FunctionCallBracketNode::~FunctionCallBracketNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void FunctionCallBracketNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-    releaser.release(m_subscript);
-    releaser.release(m_args);
-}
-
 RegisterID* FunctionCallBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
-    RegisterID* property = generator.emitNode(m_subscript.get());
+    RefPtr<RegisterID> base = generator.emitNode(m_base);
+    RegisterID* property = generator.emitNode(m_subscript);
     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     RefPtr<RegisterID> function = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property);
     RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
-    return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+    return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
 }
 
 // ------------------------------ FunctionCallDotNode ----------------------------------
 
-FunctionCallDotNode::~FunctionCallDotNode()
+RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    NodeReleaser::releaseAllNodes(this);
+    RefPtr<RegisterID> function = generator.tempDestination(dst);
+    RefPtr<RegisterID> thisRegister = generator.newTemporary();
+    generator.emitNode(thisRegister.get(), m_base);
+    generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+    generator.emitMethodCheck();
+    generator.emitGetById(function.get(), thisRegister.get(), m_ident);
+    return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
 }
 
-void FunctionCallDotNode::releaseNodes(NodeReleaser& releaser)
+RegisterID* CallFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    releaser.release(m_base);
-    releaser.release(m_args);
+    RefPtr<Label> realCall = generator.newLabel();
+    RefPtr<Label> end = generator.newLabel();
+    RefPtr<RegisterID> base = generator.emitNode(m_base);
+    generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
+    RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
+    RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
+    generator.emitJumpIfNotFunctionCall(function.get(), realCall.get());
+    {
+        RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+        RefPtr<RegisterID> thisRegister = generator.newTemporary();
+        ArgumentListNode* oldList = m_args->m_listNode;
+        if (m_args->m_listNode && m_args->m_listNode->m_expr) {
+            generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
+            m_args->m_listNode = m_args->m_listNode->m_next;
+        } else
+            generator.emitLoad(thisRegister.get(), jsNull());
+
+        generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+        generator.emitJump(end.get());
+        m_args->m_listNode = oldList;
+    }
+    generator.emitLabel(realCall.get());
+    {
+        RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
+        generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+    }
+    generator.emitLabel(end.get());
+    return finalDestination.get();
+}
+    
+static bool areTrivialApplyArguments(ArgumentsNode* args)
+{
+    return !args->m_listNode || !args->m_listNode->m_expr || !args->m_listNode->m_next
+        || (!args->m_listNode->m_next->m_next && args->m_listNode->m_next->m_expr->isSimpleArray());
 }
 
-RegisterID* FunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+RegisterID* ApplyFunctionCallDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    // A few simple cases can be trivially handled as ordinary function calls.
+    // function.apply(), function.apply(arg) -> identical to function.call
+    // function.apply(thisArg, [arg0, arg1, ...]) -> can be trivially coerced into function.call(thisArg, arg0, arg1, ...) and saves object allocation
+    bool mayBeCall = areTrivialApplyArguments(m_args);
+
+    RefPtr<Label> realCall = generator.newLabel();
+    RefPtr<Label> end = generator.newLabel();
+    RefPtr<RegisterID> base = generator.emitNode(m_base);
     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     RefPtr<RegisterID> function = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
-    RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
-    return generator.emitCall(generator.finalDestination(dst, function.get()), function.get(), thisRegister.get(), m_args.get(), divot(), startOffset(), endOffset());
+    RefPtr<RegisterID> finalDestination = generator.finalDestination(dst, function.get());
+    generator.emitJumpIfNotFunctionApply(function.get(), realCall.get());
+    {
+        if (mayBeCall) {
+            RefPtr<RegisterID> realFunction = generator.emitMove(generator.tempDestination(dst), base.get());
+            RefPtr<RegisterID> thisRegister = generator.newTemporary();
+            ArgumentListNode* oldList = m_args->m_listNode;
+            if (m_args->m_listNode && m_args->m_listNode->m_expr) {
+                generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
+                m_args->m_listNode = m_args->m_listNode->m_next;
+                if (m_args->m_listNode) {
+                    ASSERT(m_args->m_listNode->m_expr->isSimpleArray());
+                    ASSERT(!m_args->m_listNode->m_next);
+                    m_args->m_listNode = static_cast<ArrayNode*>(m_args->m_listNode->m_expr)->toArgumentList(generator.globalData());
+                }
+            } else
+                generator.emitLoad(thisRegister.get(), jsNull());
+            generator.emitCall(finalDestination.get(), realFunction.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+            m_args->m_listNode = oldList;
+        } else {
+            ASSERT(m_args->m_listNode && m_args->m_listNode->m_next);
+            RefPtr<RegisterID> realFunction = generator.emitMove(generator.newTemporary(), base.get());
+            RefPtr<RegisterID> argsCountRegister = generator.newTemporary();
+            RefPtr<RegisterID> thisRegister = generator.newTemporary();
+            RefPtr<RegisterID> argsRegister = generator.newTemporary();
+            generator.emitNode(thisRegister.get(), m_args->m_listNode->m_expr);
+            ArgumentListNode* args = m_args->m_listNode->m_next;
+            bool isArgumentsApply = false;
+            if (args->m_expr->isResolveNode()) {
+                ResolveNode* resolveNode = static_cast<ResolveNode*>(args->m_expr);
+                isArgumentsApply = generator.willResolveToArguments(resolveNode->identifier());
+                if (isArgumentsApply)
+                    generator.emitMove(argsRegister.get(), generator.uncheckedRegisterForArguments());
+            }
+            if (!isArgumentsApply)
+                generator.emitNode(argsRegister.get(), args->m_expr);
+            while ((args = args->m_next))
+                generator.emitNode(args->m_expr);
+
+            generator.emitLoadVarargs(argsCountRegister.get(), argsRegister.get());
+            generator.emitCallVarargs(finalDestination.get(), realFunction.get(), thisRegister.get(), argsCountRegister.get(), divot(), startOffset(), endOffset());
+        }
+        generator.emitJump(end.get());
+    }
+    generator.emitLabel(realCall.get());
+    {
+        RefPtr<RegisterID> thisRegister = generator.emitMove(generator.newTemporary(), base.get());
+        generator.emitCall(finalDestination.get(), function.get(), thisRegister.get(), m_args, divot(), startOffset(), endOffset());
+    }
+    generator.emitLabel(end.get());
+    return finalDestination.get();
 }
 
 // ------------------------------ PostfixResolveNode ----------------------------------
@@ -703,6 +496,8 @@ static RegisterID* emitPreIncOrDec(BytecodeGenerator& generator, RegisterID* src
 
 static RegisterID* emitPostIncOrDec(BytecodeGenerator& generator, RegisterID* dst, RegisterID* srcDst, Operator oper)
 {
+    if (srcDst == dst)
+        return generator.emitToJSNumber(dst, srcDst);
     return (oper == OpPlusPlus) ? generator.emitPostInc(dst, srcDst) : generator.emitPostDec(dst, srcDst);
 }
 
@@ -752,21 +547,10 @@ RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, Regis
 
 // ------------------------------ PostfixBracketNode ----------------------------------
 
-PostfixBracketNode::~PostfixBracketNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void PostfixBracketNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-    releaser.release(m_subscript);
-}
-
 RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
-    RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
+    RefPtr<RegisterID> base = generator.emitNode(m_base);
+    RefPtr<RegisterID> property = generator.emitNode(m_subscript);
 
     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
@@ -787,19 +571,9 @@ RegisterID* PostfixBracketNode::emitBytecode(BytecodeGenerator& generator, Regis
 
 // ------------------------------ PostfixDotNode ----------------------------------
 
-PostfixDotNode::~PostfixDotNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void PostfixDotNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-}
-
 RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> base = generator.emitNode(m_base);
 
     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
@@ -820,16 +594,6 @@ RegisterID* PostfixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterI
 
 // ------------------------------ PostfixErrorNode -----------------------------------
 
-PostfixErrorNode::~PostfixErrorNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void PostfixErrorNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-}
-
 RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
@@ -840,7 +604,7 @@ RegisterID* PostfixErrorNode::emitBytecode(BytecodeGenerator& generator, Registe
 RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     if (generator.registerFor(m_ident))
-        return generator.emitUnexpectedLoad(generator.finalDestination(dst), false);
+        return generator.emitLoad(generator.finalDestination(dst), false);
 
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
@@ -849,21 +613,10 @@ RegisterID* DeleteResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
 
 // ------------------------------ DeleteBracketNode -----------------------------------
 
-DeleteBracketNode::~DeleteBracketNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void DeleteBracketNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-    releaser.release(m_subscript);
-}
-
 RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
-    RegisterID* r1 = generator.emitNode(m_subscript.get());
+    RefPtr<RegisterID> r0 = generator.emitNode(m_base);
+    RegisterID* r1 = generator.emitNode(m_subscript);
 
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1);
@@ -871,19 +624,9 @@ RegisterID* DeleteBracketNode::emitBytecode(BytecodeGenerator& generator, Regist
 
 // ------------------------------ DeleteDotNode -----------------------------------
 
-DeleteDotNode::~DeleteDotNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void DeleteDotNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-}
-
 RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RegisterID* r0 = generator.emitNode(m_base.get());
+    RegisterID* r0 = generator.emitNode(m_base);
 
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
@@ -891,43 +634,23 @@ RegisterID* DeleteDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID
 
 // ------------------------------ DeleteValueNode -----------------------------------
 
-DeleteValueNode::~DeleteValueNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void DeleteValueNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-}
-
 RegisterID* DeleteValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    generator.emitNode(generator.ignoredResult(), m_expr.get());
+    generator.emitNode(generator.ignoredResult(), m_expr);
 
     // delete on a non-location expression ignores the value and returns true
-    return generator.emitUnexpectedLoad(generator.finalDestination(dst), true);
+    return generator.emitLoad(generator.finalDestination(dst), true);
 }
 
 // ------------------------------ VoidNode -------------------------------------
 
-VoidNode::~VoidNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void VoidNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-}
-
 RegisterID* VoidNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     if (dst == generator.ignoredResult()) {
-        generator.emitNode(generator.ignoredResult(), m_expr.get());
+        generator.emitNode(generator.ignoredResult(), m_expr);
         return 0;
     }
-    RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
+    RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
     return generator.emitLoad(dst, jsUndefined());
 }
 
@@ -950,23 +673,13 @@ RegisterID* TypeOfResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
 
 // ------------------------------ TypeOfValueNode -----------------------------------
 
-TypeOfValueNode::~TypeOfValueNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void TypeOfValueNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-}
-
 RegisterID* TypeOfValueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     if (dst == generator.ignoredResult()) {
-        generator.emitNode(generator.ignoredResult(), m_expr.get());
+        generator.emitNode(generator.ignoredResult(), m_expr);
         return 0;
     }
-    RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
+    RefPtr<RegisterID> src = generator.emitNode(m_expr);
     return generator.emitTypeOf(generator.finalDestination(dst), src.get());
 }
 
@@ -978,7 +691,7 @@ RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
         if (generator.isLocalConstant(m_ident)) {
             if (dst == generator.ignoredResult())
                 return 0;
-            RefPtr<RegisterID> r0 = generator.emitUnexpectedLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
+            RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), (m_operator == OpPlusPlus) ? 1.0 : -1.0);
             return generator.emitBinaryOp(op_add, r0.get(), local, r0.get(), OperandTypes());
         }
 
@@ -1006,21 +719,10 @@ RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
 
 // ------------------------------ PrefixBracketNode ----------------------------------
 
-PrefixBracketNode::~PrefixBracketNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void PrefixBracketNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-    releaser.release(m_subscript);
-}
-
 RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
-    RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
+    RefPtr<RegisterID> base = generator.emitNode(m_base);
+    RefPtr<RegisterID> property = generator.emitNode(m_subscript);
     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
 
     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
@@ -1036,19 +738,9 @@ RegisterID* PrefixBracketNode::emitBytecode(BytecodeGenerator& generator, Regist
 
 // ------------------------------ PrefixDotNode ----------------------------------
 
-PrefixDotNode::~PrefixDotNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void PrefixDotNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-}
-
 RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> base = generator.emitNode(m_base);
     RefPtr<RegisterID> propDst = generator.tempDestination(dst);
 
     generator.emitExpressionInfo(divot() + m_subexpressionDivotOffset, m_subexpressionStartOffset, endOffset() - m_subexpressionDivotOffset);
@@ -1064,16 +756,6 @@ RegisterID* PrefixDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID
 
 // ------------------------------ PrefixErrorNode -----------------------------------
 
-PrefixErrorNode::~PrefixErrorNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void PrefixErrorNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-}
-
 RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
     return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
@@ -1081,48 +763,149 @@ RegisterID* PrefixErrorNode::emitBytecode(BytecodeGenerator& generator, Register
 
 // ------------------------------ Unary Operation Nodes -----------------------------------
 
-UnaryOpNode::~UnaryOpNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void UnaryOpNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-}
-
 RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RegisterID* src = generator.emitNode(m_expr.get());
+    RegisterID* src = generator.emitNode(m_expr);
     return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
 }
 
 // ------------------------------ Binary Operation Nodes -----------------------------------
 
-BinaryOpNode::~BinaryOpNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
+// BinaryOpNode::emitStrcat:
+//
+// This node generates an op_strcat operation.  This opcode can handle concatenation of three or
+// more values, where we can determine a set of separate op_add operations would be operating on
+// string values.
+//
+// This function expects to be operating on a graph of AST nodes looking something like this:
+//
+//     (a)...     (b)
+//          \   /
+//           (+)     (c)
+//              \   /
+//      [d]     ((+))
+//         \    /
+//          [+=]
+//
+// The assignment operation is optional, if it exists the register holding the value on the
+// lefthand side of the assignment should be passing as the optional 'lhs' argument.
+//
+// The method should be called on the node at the root of the tree of regular binary add
+// operations (marked in the diagram with a double set of parentheses).  This node must
+// be performing a string concatenation (determined by statically detecting that at least
+// one child must be a string).  
+//
+// Since the minimum number of values being concatenated together is expected to be 3, if
+// a lhs to a concatenating assignment is not provided then the  root add should have at
+// least one left child that is also an add that can be determined to be operating on strings.
+//
+RegisterID* BinaryOpNode::emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs, ReadModifyResolveNode* emitExpressionInfoForMe)
+{
+    ASSERT(isAdd());
+    ASSERT(resultDescriptor().definitelyIsString());
+
+    // Create a list of expressions for all the adds in the tree of nodes we can convert into
+    // a string concatenation.  The rightmost node (c) is added first.  The rightmost node is
+    // added first, and the leftmost child is never added, so the vector produced for the
+    // example above will be [ c, b ].
+    Vector<ExpressionNode*, 16> reverseExpressionList;
+    reverseExpressionList.append(m_expr2);
+
+    // Examine the left child of the add.  So long as this is a string add, add its right-child
+    // to the list, and keep processing along the left fork.
+    ExpressionNode* leftMostAddChild = m_expr1;
+    while (leftMostAddChild->isAdd() && leftMostAddChild->resultDescriptor().definitelyIsString()) {
+        reverseExpressionList.append(static_cast<AddNode*>(leftMostAddChild)->m_expr2);
+        leftMostAddChild = static_cast<AddNode*>(leftMostAddChild)->m_expr1;
+    }
 
-void BinaryOpNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr1);
-    releaser.release(m_expr2);
+    Vector<RefPtr<RegisterID>, 16> temporaryRegisters;
+
+    // If there is an assignment, allocate a temporary to hold the lhs after conversion.
+    // We could possibly avoid this (the lhs is converted last anyway, we could let the
+    // op_strcat node handle its conversion if required).
+    if (lhs)
+        temporaryRegisters.append(generator.newTemporary());
+
+    // Emit code for the leftmost node ((a) in the example).
+    temporaryRegisters.append(generator.newTemporary());
+    RegisterID* leftMostAddChildTempRegister = temporaryRegisters.last().get();
+    generator.emitNode(leftMostAddChildTempRegister, leftMostAddChild);
+
+    // Note on ordering of conversions:
+    //
+    // We maintain the same ordering of conversions as we would see if the concatenations
+    // was performed as a sequence of adds (otherwise this optimization could change
+    // behaviour should an object have been provided a valueOf or toString method).
+    //
+    // Considering the above example, the sequnce of execution is:
+    //     * evaluate operand (a)
+    //     * evaluate operand (b)
+    //     * convert (a) to primitive   <-  (this would be triggered by the first add)
+    //     * convert (b) to primitive   <-  (ditto)
+    //     * evaluate operand (c)
+    //     * convert (c) to primitive   <-  (this would be triggered by the second add)
+    // And optionally, if there is an assignment:
+    //     * convert (d) to primitive   <-  (this would be triggered by the assigning addition)
+    //
+    // As such we do not plant an op to convert the leftmost child now.  Instead, use
+    // 'leftMostAddChildTempRegister' as a flag to trigger generation of the conversion
+    // once the second node has been generated.  However, if the leftmost child is an
+    // immediate we can trivially determine that no conversion will be required.
+    // If this is the case
+    if (leftMostAddChild->isString())
+        leftMostAddChildTempRegister = 0;
+
+    while (reverseExpressionList.size()) {
+        ExpressionNode* node = reverseExpressionList.last();
+        reverseExpressionList.removeLast();
+
+        // Emit the code for the current node.
+        temporaryRegisters.append(generator.newTemporary());
+        generator.emitNode(temporaryRegisters.last().get(), node);
+
+        // On the first iteration of this loop, when we first reach this point we have just
+        // generated the second node, which means it is time to convert the leftmost operand.
+        if (leftMostAddChildTempRegister) {
+            generator.emitToPrimitive(leftMostAddChildTempRegister, leftMostAddChildTempRegister);
+            leftMostAddChildTempRegister = 0; // Only do this once.
+        }
+        // Plant a conversion for this node, if necessary.
+        if (!node->isString())
+            generator.emitToPrimitive(temporaryRegisters.last().get(), temporaryRegisters.last().get());
+    }
+    ASSERT(temporaryRegisters.size() >= 3);
+
+    // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
+    // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
+    if (emitExpressionInfoForMe)
+        generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
+
+    // If there is an assignment convert the lhs now.  This will also copy lhs to
+    // the temporary register we allocated for it.
+    if (lhs)
+        generator.emitToPrimitive(temporaryRegisters[0].get(), lhs);
+
+    return generator.emitStrcat(generator.finalDestination(dst, temporaryRegisters[0].get()), temporaryRegisters[0].get(), temporaryRegisters.size());
 }
 
 RegisterID* BinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     OpcodeID opcodeID = this->opcodeID();
+
+    if (opcodeID == op_add && m_expr1->isAdd() && m_expr1->resultDescriptor().definitelyIsString())
+        return emitStrcat(generator, dst);
+
     if (opcodeID == op_neq) {
         if (m_expr1->isNull() || m_expr2->isNull()) {
             RefPtr<RegisterID> src = generator.tempDestination(dst);
-            generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
+            generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
             return generator.emitUnaryOp(op_neq_null, generator.finalDestination(dst, src.get()), src.get());
         }
     }
 
-    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
-    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+    RegisterID* src2 = generator.emitNode(m_expr2);
     return generator.emitBinaryOp(opcodeID, generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
 }
 
@@ -1130,41 +913,41 @@ RegisterID* EqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
 {
     if (m_expr1->isNull() || m_expr2->isNull()) {
         RefPtr<RegisterID> src = generator.tempDestination(dst);
-        generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2.get() : m_expr1.get());
+        generator.emitNode(src.get(), m_expr1->isNull() ? m_expr2 : m_expr1);
         return generator.emitUnaryOp(op_eq_null, generator.finalDestination(dst, src.get()), src.get());
     }
 
-    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
-    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+    RegisterID* src2 = generator.emitNode(m_expr2);
     return generator.emitEqualityOp(op_eq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
 }
 
 RegisterID* StrictEqualNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
-    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+    RegisterID* src2 = generator.emitNode(m_expr2);
     return generator.emitEqualityOp(op_stricteq, generator.finalDestination(dst, src1.get()), src1.get(), src2);
 }
 
 RegisterID* ReverseBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
-    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+    RegisterID* src2 = generator.emitNode(m_expr2);
     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src2, src1.get(), OperandTypes(m_expr2->resultDescriptor(), m_expr1->resultDescriptor()));
 }
 
 RegisterID* ThrowableBinaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
-    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+    RegisterID* src2 = generator.emitNode(m_expr2);
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     return generator.emitBinaryOp(opcodeID(), generator.finalDestination(dst, src1.get()), src1.get(), src2, OperandTypes(m_expr1->resultDescriptor(), m_expr2->resultDescriptor()));
 }
 
 RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1.get(), m_rightHasAssignments, m_expr2->isPure(generator));
-    RefPtr<RegisterID> src2 = generator.emitNode(m_expr2.get());
+    RefPtr<RegisterID> src1 = generator.emitNodeForLeftHandSide(m_expr1, m_rightHasAssignments, m_expr2->isPure(generator));
+    RefPtr<RegisterID> src2 = generator.emitNode(m_expr2);
 
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     generator.emitGetByIdExceptionInfo(op_instanceof);
@@ -1176,28 +959,17 @@ RegisterID* InstanceOfNode::emitBytecode(BytecodeGenerator& generator, RegisterI
 
 // ------------------------------ LogicalOpNode ----------------------------
 
-LogicalOpNode::~LogicalOpNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void LogicalOpNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr1);
-    releaser.release(m_expr2);
-}
-
 RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     RefPtr<RegisterID> temp = generator.tempDestination(dst);
     RefPtr<Label> target = generator.newLabel();
     
-    generator.emitNode(temp.get(), m_expr1.get());
+    generator.emitNode(temp.get(), m_expr1);
     if (m_operator == OpLogicalAnd)
         generator.emitJumpIfFalse(temp.get(), target.get());
     else
         generator.emitJumpIfTrue(temp.get(), target.get());
-    generator.emitNode(temp.get(), m_expr2.get());
+    generator.emitNode(temp.get(), m_expr2);
     generator.emitLabel(target.get());
 
     return generator.moveToDestinationIfNeeded(dst, temp.get());
@@ -1205,32 +977,20 @@ RegisterID* LogicalOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID
 
 // ------------------------------ ConditionalNode ------------------------------
 
-ConditionalNode::~ConditionalNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ConditionalNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_logical);
-    releaser.release(m_expr1);
-    releaser.release(m_expr2);
-}
-
 RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     RefPtr<RegisterID> newDst = generator.finalDestination(dst);
     RefPtr<Label> beforeElse = generator.newLabel();
     RefPtr<Label> afterElse = generator.newLabel();
 
-    RegisterID* cond = generator.emitNode(m_logical.get());
+    RegisterID* cond = generator.emitNode(m_logical);
     generator.emitJumpIfFalse(cond, beforeElse.get());
 
-    generator.emitNode(newDst.get(), m_expr1.get());
+    generator.emitNode(newDst.get(), m_expr1);
     generator.emitJump(afterElse.get());
 
     generator.emitLabel(beforeElse.get());
-    generator.emitNode(newDst.get(), m_expr2.get());
+    generator.emitNode(newDst.get(), m_expr2);
 
     generator.emitLabel(afterElse.get());
 
@@ -1239,18 +999,8 @@ RegisterID* ConditionalNode::emitBytecode(BytecodeGenerator& generator, Register
 
 // ------------------------------ ReadModifyResolveNode -----------------------------------
 
-ReadModifyResolveNode::~ReadModifyResolveNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ReadModifyResolveNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_right);
-}
-
 // FIXME: should this be moved to be a method on BytecodeGenerator?
-static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper, OperandTypes types)
+static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& generator, RegisterID* dst, RegisterID* src1, ExpressionNode* m_right, Operator oper, OperandTypes types, ReadModifyResolveNode* emitExpressionInfoForMe = 0)
 {
     OpcodeID opcodeID;
     switch (oper) {
@@ -1261,6 +1011,8 @@ static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& gen
             opcodeID = op_div;
             break;
         case OpPlusEq:
+            if (m_right->isAdd() && m_right->resultDescriptor().definitelyIsString())
+                return static_cast<AddNode*>(m_right)->emitStrcat(generator, dst, src1, emitExpressionInfoForMe);
             opcodeID = op_add;
             break;
         case OpMinusEq:
@@ -1291,7 +1043,14 @@ static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(BytecodeGenerator& gen
             ASSERT_NOT_REACHED();
             return dst;
     }
-    
+
+    RegisterID* src2 = generator.emitNode(m_right);
+
+    // Certain read-modify nodes require expression info to be emitted *after* m_right has been generated.
+    // If this is required the node is passed as 'emitExpressionInfoForMe'; do so now.
+    if (emitExpressionInfoForMe)
+        generator.emitExpressionInfo(emitExpressionInfoForMe->divot(), emitExpressionInfoForMe->startOffset(), emitExpressionInfoForMe->endOffset());
+
     return generator.emitBinaryOp(opcodeID, dst, src1, src2, types);
 }
 
@@ -1299,21 +1058,18 @@ RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, Re
 {
     if (RegisterID* local = generator.registerFor(m_ident)) {
         if (generator.isLocalConstant(m_ident)) {
-            RegisterID* src2 = generator.emitNode(m_right.get());
-            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
         }
         
         if (generator.leftHandSideNeedsCopy(m_rightHasAssignments, m_right->isPure(generator))) {
             RefPtr<RegisterID> result = generator.newTemporary();
             generator.emitMove(result.get(), local);
-            RegisterID* src2 = generator.emitNode(m_right.get());
-            emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+            emitReadModifyAssignment(generator, result.get(), result.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
             generator.emitMove(local, result.get());
             return generator.moveToDestinationIfNeeded(dst, result.get());
         }
         
-        RegisterID* src2 = generator.emitNode(m_right.get());
-        RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+        RegisterID* result = emitReadModifyAssignment(generator, local, local, m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
         return generator.moveToDestinationIfNeeded(dst, result);
     }
 
@@ -1322,8 +1078,7 @@ RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, Re
     JSObject* globalObject = 0;
     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
-        RegisterID* src2 = generator.emitNode(m_right.get());
-        RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+        RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
         generator.emitPutScopedVar(depth, index, result, globalObject);
         return result;
     }
@@ -1331,31 +1086,19 @@ RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, Re
     RefPtr<RegisterID> src1 = generator.tempDestination(dst);
     generator.emitExpressionInfo(divot() - startOffset() + m_ident.size(), m_ident.size(), 0);
     RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
-    RegisterID* src2 = generator.emitNode(m_right.get());
-    generator.emitExpressionInfo(divot(), startOffset(), endOffset());
-    RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+    RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()), this);
     return generator.emitPutById(base.get(), m_ident, result);
 }
 
 // ------------------------------ AssignResolveNode -----------------------------------
 
-AssignResolveNode::~AssignResolveNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void AssignResolveNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_right);
-}
-
 RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     if (RegisterID* local = generator.registerFor(m_ident)) {
         if (generator.isLocalConstant(m_ident))
-            return generator.emitNode(dst, m_right.get());
+            return generator.emitNode(dst, m_right);
         
-        RegisterID* result = generator.emitNode(local, m_right.get());
+        RegisterID* result = generator.emitNode(local, m_right);
         return generator.moveToDestinationIfNeeded(dst, result);
     }
 
@@ -1365,7 +1108,7 @@ RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
     if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
         if (dst == generator.ignoredResult())
             dst = 0;
-        RegisterID* value = generator.emitNode(dst, m_right.get());
+        RegisterID* value = generator.emitNode(dst, m_right);
         generator.emitPutScopedVar(depth, index, value, globalObject);
         return value;
     }
@@ -1373,55 +1116,32 @@ RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
     if (dst == generator.ignoredResult())
         dst = 0;
-    RegisterID* value = generator.emitNode(dst, m_right.get());
+    RegisterID* value = generator.emitNode(dst, m_right);
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     return generator.emitPutById(base.get(), m_ident, value);
 }
 
 // ------------------------------ AssignDotNode -----------------------------------
 
-AssignDotNode::~AssignDotNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void AssignDotNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-    releaser.release(m_right);
-}
-
 RegisterID* AssignDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
-    RegisterID* result = generator.emitNode(value.get(), m_right.get());
+    RegisterID* result = generator.emitNode(value.get(), m_right);
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     generator.emitPutById(base.get(), m_ident, result);
     return generator.moveToDestinationIfNeeded(dst, result);
 }
 
-// ------------------------------ ReadModifyDotNode -----------------------------------
-
-ReadModifyDotNode::~ReadModifyDotNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ReadModifyDotNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-    releaser.release(m_right);
-}
+// ------------------------------ ReadModifyDotNode -----------------------------------
 
 RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments, m_right->isPure(generator));
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
 
     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
-    RegisterID* change = generator.emitNode(m_right.get());
-    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
 
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     return generator.emitPutById(base.get(), m_ident, updatedValue);
@@ -1429,17 +1149,6 @@ RegisterID* ReadModifyDotNode::emitBytecode(BytecodeGenerator& generator, Regist
 
 // ------------------------------ AssignErrorNode -----------------------------------
 
-AssignErrorNode::~AssignErrorNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void AssignErrorNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_left);
-    releaser.release(m_right);
-}
-
 RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
     return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
@@ -1447,24 +1156,12 @@ RegisterID* AssignErrorNode::emitBytecode(BytecodeGenerator& generator, Register
 
 // ------------------------------ AssignBracketNode -----------------------------------
 
-AssignBracketNode::~AssignBracketNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void AssignBracketNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-    releaser.release(m_subscript);
-    releaser.release(m_right);
-}
-
 RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
-    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
+    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
     RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
-    RegisterID* result = generator.emitNode(value.get(), m_right.get());
+    RegisterID* result = generator.emitNode(value.get(), m_right);
 
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     generator.emitPutByVal(base.get(), property.get(), result);
@@ -1473,27 +1170,14 @@ RegisterID* AssignBracketNode::emitBytecode(BytecodeGenerator& generator, Regist
 
 // ------------------------------ ReadModifyBracketNode -----------------------------------
 
-ReadModifyBracketNode::~ReadModifyBracketNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ReadModifyBracketNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_base);
-    releaser.release(m_subscript);
-    releaser.release(m_right);
-}
-
 RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
-    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments, m_right->isPure(generator));
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_subscriptHasAssignments || m_rightHasAssignments, m_subscript->isPure(generator) && m_right->isPure(generator));
+    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
 
     generator.emitExpressionInfo(divot() - m_subexpressionDivotOffset, startOffset() - m_subexpressionDivotOffset, m_subexpressionEndOffset);
     RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
-    RegisterID* change = generator.emitNode(m_right.get());
-    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
+    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), m_right, m_operator, OperandTypes(ResultType::unknownType(), m_right->resultDescriptor()));
 
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     generator.emitPutByVal(base.get(), property.get(), updatedValue);
@@ -1503,63 +1187,36 @@ RegisterID* ReadModifyBracketNode::emitBytecode(BytecodeGenerator& generator, Re
 
 // ------------------------------ CommaNode ------------------------------------
 
-CommaNode::~CommaNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void CommaNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr1);
-    releaser.release(m_expr2);
-}
-
 RegisterID* CommaNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    generator.emitNode(generator.ignoredResult(), m_expr1.get());
-    return generator.emitNode(dst, m_expr2.get());
+    ASSERT(m_expressions.size() > 1);
+    for (size_t i = 0; i < m_expressions.size() - 1; i++)
+        generator.emitNode(generator.ignoredResult(), m_expressions[i]);
+    return generator.emitNode(dst, m_expressions.last());
 }
 
 // ------------------------------ ConstDeclNode ------------------------------------
 
-ConstDeclNode::~ConstDeclNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ConstDeclNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_next);
-    releaser.release(m_init);
-}
-
-ConstDeclNode::ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* init)
-    : ExpressionNode(globalData)
-    , m_ident(ident)
-    , m_init(init)
-{
-}
-
 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
 {
     if (RegisterID* local = generator.constRegisterFor(m_ident)) {
         if (!m_init)
             return local;
 
-        return generator.emitNode(local, m_init.get());
+        return generator.emitNode(local, m_init);
     }
     
     // FIXME: While this code should only be hit in eval code, it will potentially
     // assign to the wrong base if m_ident exists in an intervening dynamic scope.
     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
-    RegisterID* value = m_init ? generator.emitNode(m_init.get()) : generator.emitLoad(0, jsUndefined());
+    RegisterID* value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
     return generator.emitPutById(base.get(), m_ident, value);
 }
 
 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
     RegisterID* result = 0;
-    for (ConstDeclNode* n = this; n; n = n->m_next.get())
+    for (ConstDeclNode* n = this; n; n = n->m_next)
         result = n->emitCodeSingle(generator);
 
     return result;
@@ -1567,65 +1224,34 @@ RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID
 
 // ------------------------------ ConstStatementNode -----------------------------
 
-ConstStatementNode::~ConstStatementNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ConstStatementNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_next);
-}
-
 RegisterID* ConstStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
-    return generator.emitNode(m_next.get());
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+    return generator.emitNode(m_next);
 }
 
 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
 
-static inline RegisterID* statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
-{
-    StatementVector::const_iterator end = statements.end();
-    for (StatementVector::const_iterator it = statements.begin(); it != end; ++it) {
-        StatementNode* n = it->get();
-        if (!n->isLoop())
-            generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
-        generator.emitNode(dst, n);
-    }
-    return 0;
-}
-
-// ------------------------------ BlockNode ------------------------------------
-
-BlockNode::~BlockNode()
+static inline void statementListEmitCode(const StatementVector& statements, BytecodeGenerator& generator, RegisterID* dst)
 {
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void BlockNode::releaseNodes(NodeReleaser& releaser)
-{
-    size_t size = m_children.size();
+    size_t size = statements.size();
     for (size_t i = 0; i < size; ++i)
-        releaser.release(m_children[i]);
+        generator.emitNode(dst, statements[i]);
 }
 
-BlockNode::BlockNode(JSGlobalData* globalData, SourceElements* children)
-    : StatementNode(globalData)
-{
-    if (children)
-        children->releaseContentsIntoVector(m_children);
-}
+// ------------------------------ BlockNode ------------------------------------
 
 RegisterID* BlockNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    return statementListEmitCode(m_children, generator, dst);
+    statementListEmitCode(m_children, generator, dst);
+    return 0;
 }
 
 // ------------------------------ EmptyStatementNode ---------------------------
 
-RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator&, RegisterID* dst)
+RegisterID* EmptyStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
     return dst;
 }
 
@@ -1642,51 +1268,31 @@ RegisterID* DebuggerStatementNode::emitBytecode(BytecodeGenerator& generator, Re
 RegisterID* ExprStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     ASSERT(m_expr);
-    return generator.emitNode(dst, m_expr.get());
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine()); 
+    return generator.emitNode(dst, m_expr);
 }
 
 // ------------------------------ VarStatementNode ----------------------------
 
-VarStatementNode::~VarStatementNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void VarStatementNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-}
-
 RegisterID* VarStatementNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
 {
     ASSERT(m_expr);
-    return generator.emitNode(m_expr.get());
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+    return generator.emitNode(m_expr);
 }
 
 // ------------------------------ IfNode ---------------------------------------
 
-IfNode::~IfNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void IfNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_condition);
-    releaser.release(m_ifBlock);
-}
-
 RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+    
     RefPtr<Label> afterThen = generator.newLabel();
 
-    RegisterID* cond = generator.emitNode(m_condition.get());
+    RegisterID* cond = generator.emitNode(m_condition);
     generator.emitJumpIfFalse(cond, afterThen.get());
 
-    if (!m_ifBlock->isBlock())
-        generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
-
-    generator.emitNode(dst, m_ifBlock.get());
+    generator.emitNode(dst, m_ifBlock);
     generator.emitLabel(afterThen.get());
 
     // FIXME: This should return the last statement executed so that it can be returned as a Completion.
@@ -1695,37 +1301,22 @@ RegisterID* IfNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 
 // ------------------------------ IfElseNode ---------------------------------------
 
-IfElseNode::~IfElseNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void IfElseNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_elseBlock);
-    IfNode::releaseNodes(releaser);
-}
-
 RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+    
     RefPtr<Label> beforeElse = generator.newLabel();
     RefPtr<Label> afterElse = generator.newLabel();
 
-    RegisterID* cond = generator.emitNode(m_condition.get());
+    RegisterID* cond = generator.emitNode(m_condition);
     generator.emitJumpIfFalse(cond, beforeElse.get());
 
-    if (!m_ifBlock->isBlock())
-        generator.emitDebugHook(WillExecuteStatement, m_ifBlock->firstLine(), m_ifBlock->lastLine());
-
-    generator.emitNode(dst, m_ifBlock.get());
+    generator.emitNode(dst, m_ifBlock);
     generator.emitJump(afterElse.get());
 
     generator.emitLabel(beforeElse.get());
 
-    if (!m_elseBlock->isBlock())
-        generator.emitDebugHook(WillExecuteStatement, m_elseBlock->firstLine(), m_elseBlock->lastLine());
-
-    generator.emitNode(dst, m_elseBlock.get());
+    generator.emitNode(dst, m_elseBlock);
 
     generator.emitLabel(afterElse.get());
 
@@ -1735,17 +1326,6 @@ RegisterID* IfElseNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
 
 // ------------------------------ DoWhileNode ----------------------------------
 
-DoWhileNode::~DoWhileNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void DoWhileNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_statement);
-    releaser.release(m_expr);
-}
-
 RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
@@ -1754,15 +1334,12 @@ RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
     generator.emitLabel(topOfLoop.get());
 
     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
-
-    if (!m_statement->isBlock())
-        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
-        
-    RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
+   
+    RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
 
     generator.emitLabel(scope->continueTarget());
     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
-    RegisterID* cond = generator.emitNode(m_expr.get());
+    RegisterID* cond = generator.emitNode(m_expr);
     generator.emitJumpIfTrue(cond, topOfLoop.get());
 
     generator.emitLabel(scope->breakTarget());
@@ -1771,17 +1348,6 @@ RegisterID* DoWhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
 
 // ------------------------------ WhileNode ------------------------------------
 
-WhileNode::~WhileNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void WhileNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-    releaser.release(m_statement);
-}
-
 RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
@@ -1790,15 +1356,12 @@ RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
 
     RefPtr<Label> topOfLoop = generator.newLabel();
     generator.emitLabel(topOfLoop.get());
-
-    if (!m_statement->isBlock())
-        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
-    generator.emitNode(dst, m_statement.get());
+    
+    generator.emitNode(dst, m_statement);
 
     generator.emitLabel(scope->continueTarget());
     generator.emitDebugHook(WillExecuteStatement, m_expr->lineNo(), m_expr->lineNo());
-    RegisterID* cond = generator.emitNode(m_expr.get());
+    RegisterID* cond = generator.emitNode(m_expr);
     generator.emitJumpIfTrue(cond, topOfLoop.get());
 
     generator.emitLabel(scope->breakTarget());
@@ -1809,30 +1372,14 @@ RegisterID* WhileNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
 
 // ------------------------------ ForNode --------------------------------------
 
-ForNode::~ForNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ForNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr1);
-    releaser.release(m_expr2);
-    releaser.release(m_expr3);
-    releaser.release(m_statement);
-}
-
 RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    if (dst == generator.ignoredResult())
-        dst = 0;
-
     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
 
     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
 
     if (m_expr1)
-        generator.emitNode(generator.ignoredResult(), m_expr1.get());
+        generator.emitNode(generator.ignoredResult(), m_expr1);
 
     RefPtr<Label> condition = generator.newLabel();
     generator.emitJump(condition.get());
@@ -1840,17 +1387,16 @@ RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     RefPtr<Label> topOfLoop = generator.newLabel();
     generator.emitLabel(topOfLoop.get());
 
-    if (!m_statement->isBlock())
-        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
-    RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
+    RefPtr<RegisterID> result = generator.emitNode(dst, m_statement);
 
     generator.emitLabel(scope->continueTarget());
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
     if (m_expr3)
-        generator.emitNode(generator.ignoredResult(), m_expr3.get());
+        generator.emitNode(generator.ignoredResult(), m_expr3);
 
     generator.emitLabel(condition.get());
     if (m_expr2) {
-        RegisterID* cond = generator.emitNode(m_expr2.get());
+        RegisterID* cond = generator.emitNode(m_expr2);
         generator.emitJumpIfTrue(cond, topOfLoop.get());
     } else
         generator.emitJump(topOfLoop.get());
@@ -1861,45 +1407,6 @@ RegisterID* ForNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 
 // ------------------------------ ForInNode ------------------------------------
 
-ForInNode::~ForInNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ForInNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_init);
-    releaser.release(m_lexpr);
-    releaser.release(m_expr);
-    releaser.release(m_statement);
-}
-
-ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
-    : StatementNode(globalData)
-    , m_init(0L)
-    , m_lexpr(l)
-    , m_expr(expr)
-    , m_statement(statement)
-    , m_identIsVarDecl(false)
-{
-}
-
-ForInNode::ForInNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in, ExpressionNode* expr, StatementNode* statement, int divot, int startOffset, int endOffset)
-    : StatementNode(globalData)
-    , m_ident(ident)
-    , m_lexpr(new ResolveNode(globalData, ident, divot - startOffset))
-    , m_expr(expr)
-    , m_statement(statement)
-    , m_identIsVarDecl(true)
-{
-    if (in) {
-        AssignResolveNode* node = new AssignResolveNode(globalData, ident, in, true);
-        node->setExceptionSourceCode(divot, divot - startOffset, endOffset - divot);
-        m_init = node;
-    }
-    // for( var foo = bar in baz )
-}
-
 RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Loop);
@@ -1912,8 +1419,8 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
     generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
 
     if (m_init)
-        generator.emitNode(generator.ignoredResult(), m_init.get());
-    RegisterID* forInBase = generator.emitNode(m_expr.get());
+        generator.emitNode(generator.ignoredResult(), m_init);
+    RegisterID* forInBase = generator.emitNode(m_expr);
     RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
     generator.emitJump(scope->continueTarget());
 
@@ -1922,7 +1429,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
 
     RegisterID* propertyName;
     if (m_lexpr->isResolveNode()) {
-        const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
+        const Identifier& ident = static_cast<ResolveNode*>(m_lexpr)->identifier();
         propertyName = generator.registerFor(ident);
         if (!propertyName) {
             propertyName = generator.newTemporary();
@@ -1933,7 +1440,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
             generator.emitPutById(base, ident, propertyName);
         }
     } else if (m_lexpr->isDotAccessorNode()) {
-        DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
+        DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr);
         const Identifier& ident = assignNode->identifier();
         propertyName = generator.newTemporary();
         RefPtr<RegisterID> protect = propertyName;
@@ -1943,7 +1450,7 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
         generator.emitPutById(base, ident, propertyName);
     } else {
         ASSERT(m_lexpr->isBracketAccessorNode());
-        BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
+        BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr);
         propertyName = generator.newTemporary();
         RefPtr<RegisterID> protect = propertyName;
         RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
@@ -1953,12 +1460,11 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
         generator.emitPutByVal(base.get(), subscript, propertyName);
     }   
 
-    if (!m_statement->isBlock())
-        generator.emitDebugHook(WillExecuteStatement, m_statement->firstLine(), m_statement->lastLine());
-    generator.emitNode(dst, m_statement.get());
+    generator.emitNode(dst, m_statement);
 
     generator.emitLabel(scope->continueTarget());
     generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
     generator.emitLabel(scope->breakTarget());
     return dst;
 }
@@ -1968,6 +1474,8 @@ RegisterID* ForInNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
 // ECMA 12.7
 RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+    
     LabelScope* scope = generator.continueTarget(m_ident);
 
     if (!scope)
@@ -1984,6 +1492,8 @@ RegisterID* ContinueNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
 // ECMA 12.8
 RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+    
     LabelScope* scope = generator.breakTarget(m_ident);
     
     if (!scope)
@@ -1997,24 +1507,15 @@ RegisterID* BreakNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
 
 // ------------------------------ ReturnNode -----------------------------------
 
-ReturnNode::~ReturnNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ReturnNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_value);
-}
-
 RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
     if (generator.codeType() != FunctionCode)
         return emitThrowError(generator, SyntaxError, "Invalid return statement.");
 
     if (dst == generator.ignoredResult())
         dst = 0;
-    RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(dst, jsUndefined());
+    RegisterID* r0 = m_value ? generator.emitNode(dst, m_value) : generator.emitLoad(dst, jsUndefined());
     RefPtr<RegisterID> returnRegister;
     if (generator.scopeDepth()) {
         RefPtr<Label> l0 = generator.newLabel();
@@ -2031,67 +1532,21 @@ RegisterID* ReturnNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
 
 // ------------------------------ WithNode -------------------------------------
 
-WithNode::~WithNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void WithNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-    releaser.release(m_statement);
-}
-
 RegisterID* WithNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+    
     RefPtr<RegisterID> scope = generator.newTemporary();
-    generator.emitNode(scope.get(), m_expr.get()); // scope must be protected until popped
+    generator.emitNode(scope.get(), m_expr); // scope must be protected until popped
     generator.emitExpressionInfo(m_divot, m_expressionLength, 0);
     generator.emitPushScope(scope.get());
-    RegisterID* result = generator.emitNode(dst, m_statement.get());
+    RegisterID* result = generator.emitNode(dst, m_statement);
     generator.emitPopScope();
     return result;
 }
 
-// ------------------------------ CaseClauseNode --------------------------------
-
-CaseClauseNode::~CaseClauseNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void CaseClauseNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-}
-
-// ------------------------------ ClauseListNode --------------------------------
-
-ClauseListNode::~ClauseListNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ClauseListNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_clause);
-    releaser.release(m_next);
-}
-
 // ------------------------------ CaseBlockNode --------------------------------
 
-CaseBlockNode::~CaseBlockNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void CaseBlockNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_list1);
-    releaser.release(m_defaultClause);
-    releaser.release(m_list2);
-}
-
 enum SwitchKind { 
     SwitchUnset = 0,
     SwitchNumber = 1, 
@@ -2106,13 +1561,11 @@ static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>&
         literalVector.append(clauseExpression);
         if (clauseExpression->isNumber()) {
             double value = static_cast<NumberNode*>(clauseExpression)->value();
-            JSValuePtr jsValue = JSValuePtr::makeInt32Fast(static_cast<int32_t>(value));
-            if ((typeForTable & ~SwitchNumber) || !jsValue || (jsValue.getInt32Fast() != value)) {
+            int32_t intVal = static_cast<int32_t>(value);
+            if ((typeForTable & ~SwitchNumber) || (intVal != value)) {
                 typeForTable = SwitchNeither;
                 break;
             }
-            int32_t intVal = static_cast<int32_t>(value);
-            ASSERT(intVal == value);
             if (intVal < min_num)
                 min_num = intVal;
             if (intVal > max_num)
@@ -2146,8 +1599,8 @@ SwitchInfo::SwitchType CaseBlockNode::tryOptimizedSwitch(Vector<ExpressionNode*,
     SwitchKind typeForTable = SwitchUnset;
     bool singleCharacterSwitch = true;
     
-    processClauseList(m_list1.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
-    processClauseList(m_list2.get(), literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
+    processClauseList(m_list1, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
+    processClauseList(m_list2, literalVector, typeForTable, singleCharacterSwitch, min_num, max_num);
     
     if (typeForTable == SwitchUnset || typeForTable == SwitchNeither)
         return SwitchInfo::SwitchNone;
@@ -2187,7 +1640,7 @@ RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, Re
         generator.beginSwitch(switchExpression, switchType);
     } else {
         // Setup jumps
-        for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
+        for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
             RefPtr<RegisterID> clauseVal = generator.newTemporary();
             generator.emitNode(clauseVal.get(), list->getClause()->expr());
             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
@@ -2195,7 +1648,7 @@ RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, Re
             generator.emitJumpIfTrue(clauseVal.get(), labelVector[labelVector.size() - 1].get());
         }
         
-        for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
+        for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
             RefPtr<RegisterID> clauseVal = generator.newTemporary();
             generator.emitNode(clauseVal.get(), list->getClause()->expr());
             generator.emitBinaryOp(op_stricteq, clauseVal.get(), clauseVal.get(), switchExpression, OperandTypes());
@@ -2209,19 +1662,19 @@ RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, Re
     RegisterID* result = 0;
 
     size_t i = 0;
-    for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
+    for (ClauseListNode* list = m_list1; list; list = list->getNext()) {
         generator.emitLabel(labelVector[i++].get());
-        result = statementListEmitCode(list->getClause()->children(), generator, dst);
+        statementListEmitCode(list->getClause()->children(), generator, dst);
     }
 
     if (m_defaultClause) {
         generator.emitLabel(defaultLabel.get());
-        result = statementListEmitCode(m_defaultClause->children(), generator, dst);
+        statementListEmitCode(m_defaultClause->children(), generator, dst);
     }
 
-    for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
+    for (ClauseListNode* list = m_list2; list; list = list->getNext()) {
         generator.emitLabel(labelVector[i++].get());
-        result = statementListEmitCode(list->getClause()->children(), generator, dst);
+        statementListEmitCode(list->getClause()->children(), generator, dst);
     }
     if (!m_defaultClause)
         generator.emitLabel(defaultLabel.get());
@@ -2236,22 +1689,13 @@ RegisterID* CaseBlockNode::emitBytecodeForBlock(BytecodeGenerator& generator, Re
 
 // ------------------------------ SwitchNode -----------------------------------
 
-SwitchNode::~SwitchNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void SwitchNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-    releaser.release(m_block);
-}
-
 RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+    
     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::Switch);
 
-    RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
+    RefPtr<RegisterID> r0 = generator.emitNode(m_expr);
     RegisterID* r1 = m_block->emitBytecodeForBlock(generator, r0.get(), dst);
 
     generator.emitLabel(scope->breakTarget());
@@ -2260,23 +1704,15 @@ RegisterID* SwitchNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
 
 // ------------------------------ LabelNode ------------------------------------
 
-LabelNode::~LabelNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void LabelNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_statement);
-}
-
 RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
     if (generator.breakTarget(m_name))
         return emitThrowError(generator, SyntaxError, "Duplicate label: %s.", m_name);
 
     RefPtr<LabelScope> scope = generator.newLabelScope(LabelScope::NamedLabel, &m_name);
-    RegisterID* r0 = generator.emitNode(dst, m_statement.get());
+    RegisterID* r0 = generator.emitNode(dst, m_statement);
 
     generator.emitLabel(scope->breakTarget());
     return r0;
@@ -2284,44 +1720,28 @@ RegisterID* LabelNode::emitBytecode(BytecodeGenerator& generator, RegisterID* ds
 
 // ------------------------------ ThrowNode ------------------------------------
 
-ThrowNode::~ThrowNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ThrowNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_expr);
-}
-
 RegisterID* ThrowNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
+
     if (dst == generator.ignoredResult())
         dst = 0;
-    RefPtr<RegisterID> expr = generator.emitNode(dst, m_expr.get());
+    RefPtr<RegisterID> expr = generator.emitNode(m_expr);
     generator.emitExpressionInfo(divot(), startOffset(), endOffset());
     generator.emitThrow(expr.get());
-    return dst;
+    return 0;
 }
 
 // ------------------------------ TryNode --------------------------------------
 
-TryNode::~TryNode()
+RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    NodeReleaser::releaseAllNodes(this);
-}
+    // NOTE: The catch and finally blocks must be labeled explicitly, so the
+    // optimizer knows they may be jumped to from anywhere.
 
-void TryNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_tryBlock);
-    releaser.release(m_catchBlock);
-    releaser.release(m_finallyBlock);
-}
+    generator.emitDebugHook(WillExecuteStatement, firstLine(), lastLine());
 
-RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
-{
     RefPtr<Label> tryStartLabel = generator.newLabel();
-    RefPtr<Label> tryEndLabel = generator.newLabel();
     RefPtr<Label> finallyStart;
     RefPtr<RegisterID> finallyReturnAddr;
     if (m_finallyBlock) {
@@ -2329,14 +1749,19 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
         finallyReturnAddr = generator.newTemporary();
         generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
     }
+
     generator.emitLabel(tryStartLabel.get());
-    generator.emitNode(dst, m_tryBlock.get());
-    generator.emitLabel(tryEndLabel.get());
+    generator.emitNode(dst, m_tryBlock);
 
     if (m_catchBlock) {
-        RefPtr<Label> handlerEndLabel = generator.newLabel();
-        generator.emitJump(handlerEndLabel.get());
-        RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
+        RefPtr<Label> catchEndLabel = generator.newLabel();
+        
+        // Normal path: jump over the catch block.
+        generator.emitJump(catchEndLabel.get());
+
+        // Uncaught exception path: the catch block.
+        RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
+        RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
         if (m_catchHasEval) {
             RefPtr<RegisterID> dynamicScopeObject = generator.emitNewObject(generator.newTemporary());
             generator.emitPutById(dynamicScopeObject.get(), m_exceptionIdent, exceptionRegister.get());
@@ -2344,9 +1769,9 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
             generator.emitPushScope(exceptionRegister.get());
         } else
             generator.emitPushNewScope(exceptionRegister.get(), m_exceptionIdent, exceptionRegister.get());
-        generator.emitNode(dst, m_catchBlock.get());
+        generator.emitNode(dst, m_catchBlock);
         generator.emitPopScope();
-        generator.emitLabel(handlerEndLabel.get());
+        generator.emitLabel(catchEndLabel.get());
     }
 
     if (m_finallyBlock) {
@@ -2357,23 +1782,20 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
         // approach to not clobbering anything important
         RefPtr<RegisterID> highestUsedRegister = generator.highestUsedRegister();
         RefPtr<Label> finallyEndLabel = generator.newLabel();
+
+        // Normal path: invoke the finally block, then jump over it.
         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
-        // Use a label to record the subtle fact that sret will return to the
-        // next instruction. sret is the only way to jump without an explicit label.
-        generator.emitLabel(generator.newLabel().get());
         generator.emitJump(finallyEndLabel.get());
 
-        // Finally block for exception path
-        RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
+        // Uncaught exception path: invoke the finally block, then re-throw the exception.
+        RefPtr<Label> here = generator.emitLabel(generator.newLabel().get());
+        RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), here.get());
         generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
-        // Use a label to record the subtle fact that sret will return to the
-        // next instruction. sret is the only way to jump without an explicit label.
-        generator.emitLabel(generator.newLabel().get());
         generator.emitThrow(tempExceptionRegister.get());
 
-        // emit the finally block itself
+        // The finally block.
         generator.emitLabel(finallyStart.get());
-        generator.emitNode(dst, m_finallyBlock.get());
+        generator.emitNode(dst, m_finallyBlock);
         generator.emitSubroutineReturn(finallyReturnAddr.get());
 
         generator.emitLabel(finallyEndLabel.get());
@@ -2382,27 +1804,16 @@ RegisterID* TryNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
     return dst;
 }
 
-// ------------------------------ ParameterNode -----------------------------
-
-ParameterNode::~ParameterNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ParameterNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_next);
-}
-
 // -----------------------------ScopeNodeData ---------------------------
 
-ScopeNodeData::ScopeNodeData(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
+ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, int numConstants)
     : m_numConstants(numConstants)
 {
+    m_arena.swap(arena);
     if (varStack)
-        m_varStack = *varStack;
+        m_varStack.swap(*varStack);
     if (funcStack)
-        m_functionStack = *funcStack;
+        m_functionStack.swap(*funcStack);
     if (children)
         children->releaseContentsIntoVector(m_children);
 }
@@ -2422,48 +1833,44 @@ void ScopeNodeData::mark()
 
 ScopeNode::ScopeNode(JSGlobalData* globalData)
     : StatementNode(globalData)
+    , ParserArenaRefCounted(globalData)
     , m_features(NoFeatures)
 {
-#if ENABLE(OPCODE_SAMPLING)
-    globalData->interpreter->sampler()->notifyOfScope(this);
+#if ENABLE(CODEBLOCK_SAMPLING)
+    if (SamplingTool* sampler = globalData->interpreter->sampler())
+        sampler->notifyOfScope(this);
 #endif
 }
 
 ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
     : StatementNode(globalData)
-    , m_data(new ScopeNodeData(children, varStack, funcStack, numConstants))
+    , ParserArenaRefCounted(globalData)
+    , m_data(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, numConstants))
     , m_features(features)
     , m_source(source)
 {
-#if ENABLE(OPCODE_SAMPLING)
-    globalData->interpreter->sampler()->notifyOfScope(this);
+#if ENABLE(CODEBLOCK_SAMPLING)
+    if (SamplingTool* sampler = globalData->interpreter->sampler())
+        sampler->notifyOfScope(this);
 #endif
 }
 
-ScopeNode::~ScopeNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void ScopeNode::releaseNodes(NodeReleaser& releaser)
-{
-    if (!m_data)
-        return;
-    size_t size = m_data->m_children.size();
-    for (size_t i = 0; i < size; ++i)
-        releaser.release(m_data->m_children[i]);
-}
-
 // ------------------------------ ProgramNode -----------------------------
 
-ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
     : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
 {
 }
 
-ProgramNode* ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
 {
-    return new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
+    RefPtr<ProgramNode> node = new ProgramNode(globalData, children, varStack, funcStack, source, features, numConstants);
+
+    ASSERT(node->data()->m_arena.last() == node);
+    node->data()->m_arena.removeLast();
+    ASSERT(!node->data()->m_arena.contains(node.get()));
+
+    return node.release();
 }
 
 RegisterID* ProgramNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
@@ -2486,22 +1893,39 @@ void ProgramNode::generateBytecode(ScopeChainNode* scopeChainNode)
     
     m_code.set(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
     
-    BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get());
-    generator.generate();
+    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get()));
+    generator->generate();
 
     destroyData();
 }
 
+#if ENABLE(JIT)
+void ProgramNode::generateJITCode(ScopeChainNode* scopeChainNode)
+{
+    bytecode(scopeChainNode);
+    ASSERT(m_code);
+    ASSERT(!m_jitCode);
+    JIT::compile(scopeChainNode->globalData, m_code.get());
+    ASSERT(m_jitCode);
+}
+#endif
+
 // ------------------------------ EvalNode -----------------------------
 
-EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
     : ScopeNode(globalData, source, children, varStack, funcStack, features, numConstants)
 {
 }
 
-EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
+PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& source, CodeFeatures features, int numConstants)
 {
-    return new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
+    RefPtr<EvalNode> node = new EvalNode(globalData, children, varStack, funcStack, source, features, numConstants);
+
+    ASSERT(node->data()->m_arena.last() == node);
+    node->data()->m_arena.removeLast();
+    ASSERT(!node->data()->m_arena.contains(node.get()));
+
+    return node.release();
 }
 
 RegisterID* EvalNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
@@ -2524,8 +1948,8 @@ void EvalNode::generateBytecode(ScopeChainNode* scopeChainNode)
 
     m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
 
-    BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
-    generator.generate();
+    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get()));
+    generator->generate();
 
     // Eval code needs to hang on to its declaration stacks to keep declaration info alive until Interpreter::execute time,
     // so the entire ScopeNodeData cannot be destoyed.
@@ -2541,9 +1965,9 @@ EvalCodeBlock& EvalNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeCh
 
     m_code.set(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
 
-    BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
-    generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
-    generator.generate();
+    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get()));
+    generator->setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
+    generator->generate();
 
     return *m_code;
 }
@@ -2554,27 +1978,35 @@ void EvalNode::mark()
     data()->mark();
 }
 
+#if ENABLE(JIT)
+void EvalNode::generateJITCode(ScopeChainNode* scopeChainNode)
+{
+    bytecode(scopeChainNode);
+    ASSERT(m_code);
+    ASSERT(!m_jitCode);
+    JIT::compile(scopeChainNode->globalData, m_code.get());
+    ASSERT(m_jitCode);
+}
+#endif
+
 // ------------------------------ FunctionBodyNode -----------------------------
 
-FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
     : ScopeNode(globalData)
     , m_parameters(0)
     , m_parameterCount(0)
-    , m_refCount(0)
 {
 }
 
-FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
     : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
     , m_parameters(0)
     , m_parameterCount(0)
-    , m_refCount(0)
 {
 }
 
 FunctionBodyNode::~FunctionBodyNode()
 {
-    ASSERT(!m_refCount);
     for (size_t i = 0; i < m_parameterCount; ++i)
         m_parameters[i].~Identifier();
     fastFree(m_parameters);
@@ -2604,14 +2036,36 @@ void FunctionBodyNode::mark()
         m_code->mark();
 }
 
+#if ENABLE(JIT)
+PassRefPtr<FunctionBodyNode> FunctionBodyNode::createNativeThunk(JSGlobalData* globalData)
+{
+    RefPtr<FunctionBodyNode> body = new FunctionBodyNode(globalData);
+    globalData->parser->arena().reset();
+    body->m_code.set(new CodeBlock(body.get()));
+    body->m_jitCode = JITCode(JITCode::HostFunction(globalData->jitStubs.ctiNativeCallThunk()));
+    return body.release();
+}
+#endif
+
+bool FunctionBodyNode::isHostFunction() const
+{
+    return m_code && m_code->codeType() == NativeCode;
+}
+
 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
 {
     return new FunctionBodyNode(globalData);
 }
 
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
 {
-    return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
+    RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
+
+    ASSERT(node->data()->m_arena.last() == node);
+    node->data()->m_arena.removeLast();
+    ASSERT(!node->data()->m_arena.contains(node.get()));
+
+    return node.release();
 }
 
 void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
@@ -2627,12 +2081,23 @@ void FunctionBodyNode::generateBytecode(ScopeChainNode* scopeChainNode)
 
     m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
 
-    BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
-    generator.generate();
+    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get()));
+    generator->generate();
 
     destroyData();
 }
 
+#if ENABLE(JIT)
+void FunctionBodyNode::generateJITCode(ScopeChainNode* scopeChainNode)
+{
+    bytecode(scopeChainNode);
+    ASSERT(m_code);
+    ASSERT(!m_jitCode);
+    JIT::compile(scopeChainNode->globalData, m_code.get());
+    ASSERT(m_jitCode);
+}
+#endif
+
 CodeBlock& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode* scopeChainNode, CodeBlock* codeBlockBeingRegeneratedFrom)
 {
     ASSERT(!m_code);
@@ -2642,9 +2107,9 @@ CodeBlock& FunctionBodyNode::bytecodeForExceptionInfoReparse(ScopeChainNode* sco
 
     m_code.set(new CodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
 
-    BytecodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get());
-    generator.setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
-    generator.generate();
+    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(this, globalObject->debugger(), scopeChain, &m_code->symbolTable(), m_code.get()));
+    generator->setRegeneratingForExceptionInfo(codeBlockBeingRegeneratedFrom);
+    generator->generate();
 
     return *m_code;
 }
@@ -2654,7 +2119,7 @@ RegisterID* FunctionBodyNode::emitBytecode(BytecodeGenerator& generator, Registe
     generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
     statementListEmitCode(children(), generator, generator.ignoredResult());
     if (children().size() && children().last()->isBlock()) {
-        BlockNode* blockNode = static_cast<BlockNode*>(children().last().get());
+        BlockNode* blockNode = static_cast<BlockNode*>(children().last());
         if (blockNode->children().size() && blockNode->children().last()->isReturnNode())
             return 0;
     }
@@ -2686,17 +2151,6 @@ Identifier* FunctionBodyNode::copyParameters()
 
 // ------------------------------ FuncDeclNode ---------------------------------
 
-FuncDeclNode::~FuncDeclNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void FuncDeclNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_parameter);
-    releaser.release(m_body);
-}
-
 JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
 {
     return new (exec) JSFunction(exec, m_ident, m_body.get(), scopeChain);
@@ -2711,17 +2165,6 @@ RegisterID* FuncDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
 
 // ------------------------------ FuncExprNode ---------------------------------
 
-FuncExprNode::~FuncExprNode()
-{
-    NodeReleaser::releaseAllNodes(this);
-}
-
-void FuncExprNode::releaseNodes(NodeReleaser& releaser)
-{
-    releaser.release(m_parameter);
-    releaser.release(m_body);
-}
-
 RegisterID* FuncExprNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
     return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
index 2496a4f8f37ef0a2a4864ffcebc9b7a2e7a4ca0d..a9f88b7378352994bf6ccf3049d8a0227fb1b0ce 100644 (file)
  *
  */
 
-#ifndef NODES_H_
-#define NODES_H_
+#ifndef Nodes_h
+#define Nodes_h
 
 #include "Error.h"
+#include "JITCode.h"
 #include "Opcode.h"
+#include "ParserArena.h"
 #include "ResultType.h"
 #include "SourceCode.h"
 #include "SymbolTable.h"
 #include <wtf/MathExtras.h>
 #include <wtf/OwnPtr.h>
-#include <wtf/Vector.h>
-
-#if PLATFORM(X86) && COMPILER(GCC)
-#define JSC_FAST_CALL __attribute__((regparm(3)))
-#else
-#define JSC_FAST_CALL
-#endif
 
 namespace JSC {
 
+    class ArgumentListNode;
     class CodeBlock;
     class BytecodeGenerator;
     class FuncDeclNode;
     class EvalCodeBlock;
     class JSFunction;
-    class NodeReleaser;
     class ProgramCodeBlock;
     class PropertyListNode;
+    class ReadModifyResolveNode;
     class RegisterID;
     class ScopeChainNode;
 
@@ -91,7 +87,7 @@ namespace JSC {
     namespace DeclarationStacks {
         enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
         typedef Vector<std::pair<Identifier, unsigned> > VarStack;
-        typedef Vector<RefPtr<FuncDeclNode> > FunctionStack;
+        typedef Vector<FuncDeclNode*> FunctionStack;
     }
 
     struct SwitchInfo {
@@ -100,30 +96,37 @@ namespace JSC {
         SwitchType switchType;
     };
 
-    class ParserRefCounted : Noncopyable {
+    class ParserArenaDeletable {
     protected:
-        ParserRefCounted(JSGlobalData*) JSC_FAST_CALL;
+        ParserArenaDeletable() { }
 
     public:
-        virtual ~ParserRefCounted();
+        virtual ~ParserArenaDeletable() { }
 
-        // Nonrecursive destruction.
-        virtual void releaseNodes(NodeReleaser&);
+        // Objects created with this version of new are deleted when the arena is deleted.
+        void* operator new(size_t, JSGlobalData*);
 
-        void ref() JSC_FAST_CALL;
-        void deref() JSC_FAST_CALL;
-        bool hasOneRef() JSC_FAST_CALL;
+        // Objects created with this version of new are not deleted when the arena is deleted.
+        // Other arrangements must be made.
+        void* operator new(size_t);
+    };
 
-        static void deleteNewObjects(JSGlobalData*) JSC_FAST_CALL;
+    class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
+    protected:
+        ParserArenaRefCounted(JSGlobalData*);
 
-    private:
-        JSGlobalData* m_globalData;
+    public:
+        virtual ~ParserArenaRefCounted()
+        {
+            ASSERT(deletionHasBegun());
+        }
     };
 
-    class Node : public ParserRefCounted {
-    public:
-        Node(JSGlobalData*) JSC_FAST_CALL;
+    class Node : public ParserArenaDeletable {
+    protected:
+        Node(JSGlobalData*);
 
+    public:
         /*
             Return value: The register holding the production's value.
                      dst: An optional parameter specifying the most efficient
@@ -146,7 +149,7 @@ namespace JSC {
             because the assignment node, "x =", passes r[x] as dst to the number
             node, "1".
         */
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL = 0;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) = 0;
 
         int lineNo() const { return m_line; }
 
@@ -156,46 +159,45 @@ namespace JSC {
 
     class ExpressionNode : public Node {
     public:
-        ExpressionNode(JSGlobalData* globalData, ResultType resultDesc = ResultType::unknownType()) JSC_FAST_CALL
-            : Node(globalData)
-            , m_resultDesc(resultDesc)
-        {
-        }
-
-        virtual bool isNumber() const JSC_FAST_CALL { return false; }
-        virtual bool isString() const JSC_FAST_CALL { return false; }
-        virtual bool isNull() const JSC_FAST_CALL { return false; }
-        virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return false; }        
-        virtual bool isLocation() const JSC_FAST_CALL { return false; }
-        virtual bool isResolveNode() const JSC_FAST_CALL { return false; }
-        virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return false; }
-        virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; }
-        virtual bool isFuncExprNode() const JSC_FAST_CALL { return false; } 
+        ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType());
+
+        virtual bool isNumber() const { return false; }
+        virtual bool isString() const { return false; }
+        virtual bool isNull() const { return false; }
+        virtual bool isPure(BytecodeGenerator&) const { return false; }        
+        virtual bool isLocation() const { return false; }
+        virtual bool isResolveNode() const { return false; }
+        virtual bool isBracketAccessorNode() const { return false; }
+        virtual bool isDotAccessorNode() const { return false; }
+        virtual bool isFuncExprNode() const { return false; }
+        virtual bool isCommaNode() const { return false; }
+        virtual bool isSimpleArray() const { return false; }
+        virtual bool isAdd() const { return false; }
 
         virtual ExpressionNode* stripUnaryPlus() { return this; }
 
-        ResultType resultDescriptor() const JSC_FAST_CALL { return m_resultDesc; }
+        ResultType resultDescriptor() const { return m_resultType; }
 
         // This needs to be in public in order to compile using GCC 3.x 
         typedef enum { EvalOperator, FunctionCall } CallerType;
 
     private:
-        ResultType m_resultDesc;
+        ResultType m_resultType;
     };
 
     class StatementNode : public Node {
     public:
-        StatementNode(JSGlobalData*) JSC_FAST_CALL;
-        void setLoc(int line0, int line1) JSC_FAST_CALL;
-        int firstLine() const JSC_FAST_CALL { return lineNo(); }
-        int lastLine() const JSC_FAST_CALL { return m_lastLine; }
+        StatementNode(JSGlobalData*);
 
-        virtual bool isEmptyStatement() const JSC_FAST_CALL { return false; }
-        virtual bool isReturnNode() const JSC_FAST_CALL { return false; }
-        virtual bool isExprStatement() const JSC_FAST_CALL { return false; }
+        void setLoc(int line0, int line1);
+        int firstLine() const { return lineNo(); }
+        int lastLine() const { return m_lastLine; }
 
-        virtual bool isBlock() const JSC_FAST_CALL { return false; }
-        virtual bool isLoop() const JSC_FAST_CALL { return false; }
+        virtual bool isEmptyStatement() const { return false; }
+        virtual bool isReturnNode() const { return false; }
+        virtual bool isExprStatement() const { return false; }
+
+        virtual bool isBlock() const { return false; }
 
     private:
         int m_lastLine;
@@ -203,66 +205,54 @@ namespace JSC {
 
     class NullNode : public ExpressionNode {
     public:
-        NullNode(JSGlobalData* globalData) JSC_FAST_CALL
-            : ExpressionNode(globalData, ResultType::nullType())
-        {
-        }
+        NullNode(JSGlobalData*);
 
-        virtual bool isNull() const JSC_FAST_CALL { return true; }
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        virtual bool isNull() const { return true; }
     };
 
     class BooleanNode : public ExpressionNode {
     public:
-        BooleanNode(JSGlobalData* globalData, bool value) JSC_FAST_CALL
-            : ExpressionNode(globalData, ResultType::booleanType())
-            , m_value(value)
-        {
-        }
+        BooleanNode(JSGlobalData*, bool value);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
+        virtual bool isPure(BytecodeGenerator&) const { return true; }
 
-    private:
         bool m_value;
     };
 
     class NumberNode : public ExpressionNode {
     public:
-        NumberNode(JSGlobalData* globalData, double v) JSC_FAST_CALL
-            : ExpressionNode(globalData, ResultType::numberType())
-            , m_double(v)
-        {
-        }
+        NumberNode(JSGlobalData*, double v);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
-        virtual bool isNumber() const JSC_FAST_CALL { return true; }
-        virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
-        double value() const JSC_FAST_CALL { return m_double; }
-        void setValue(double d) JSC_FAST_CALL { m_double = d; }
+        double value() const { return m_double; }
+        void setValue(double d) { m_double = d; }
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        virtual bool isNumber() const { return true; }
+        virtual bool isPure(BytecodeGenerator&) const { return true; }
+
         double m_double;
     };
 
     class StringNode : public ExpressionNode {
     public:
-        StringNode(JSGlobalData* globalData, const Identifier& v) JSC_FAST_CALL
-            : ExpressionNode(globalData, ResultType::stringType())
-            , m_value(v)
-        {
-        }
+        StringNode(JSGlobalData*, const Identifier& v);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-        
-        virtual bool isString() const JSC_FAST_CALL { return true; }
         const Identifier& value() { return m_value; }
-        virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
+        virtual bool isPure(BytecodeGenerator&) const { return true; }
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        
+        virtual bool isString() const { return true; }
+
         Identifier m_value;
     };
     
@@ -365,1158 +355,682 @@ namespace JSC {
 
     class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_pattern(pattern)
-            , m_flags(flags)
-        {
-        }
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        RegExpNode(JSGlobalData*, const UString& pattern, const UString& flags);
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         UString m_pattern;
         UString m_flags;
     };
 
     class ThisNode : public ExpressionNode {
     public:
-        ThisNode(JSGlobalData* globalData) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-        {
-        }
+        ThisNode(JSGlobalData*);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
     class ResolveNode : public ExpressionNode {
     public:
-        ResolveNode(JSGlobalData* globalData, const Identifier& ident, int startOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_ident(ident)
-            , m_startOffset(startOffset)
-        {
-        }
+        ResolveNode(JSGlobalData*, const Identifier&, int startOffset);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
-        virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL;
-        virtual bool isLocation() const JSC_FAST_CALL { return true; }
-        virtual bool isResolveNode() const JSC_FAST_CALL { return true; }
-        const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
+        const Identifier& identifier() const { return m_ident; }
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        virtual bool isPure(BytecodeGenerator&) const ;
+        virtual bool isLocation() const { return true; }
+        virtual bool isResolveNode() const { return true; }
+
         Identifier m_ident;
         int32_t m_startOffset;
     };
 
-    class ElementNode : public ParserRefCounted {
+    class ElementNode : public ParserArenaDeletable {
     public:
-        ElementNode(JSGlobalData* globalData, int elision, ExpressionNode* node) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_elision(elision)
-            , m_node(node)
-        {
-        }
-
-        ElementNode(JSGlobalData* globalData, ElementNode* l, int elision, ExpressionNode* node) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_elision(elision)
-            , m_node(node)
-        {
-            l->m_next = this;
-        }
-
-        virtual ~ElementNode();
-        virtual void releaseNodes(NodeReleaser&);
+        ElementNode(JSGlobalData*, int elision, ExpressionNode*);
+        ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*);
 
         int elision() const { return m_elision; }
-        ExpressionNode* value() { return m_node.get(); }
-
-        ElementNode* next() { return m_next.get(); }
+        ExpressionNode* value() { return m_node; }
+        ElementNode* next() { return m_next; }
 
     private:
-        RefPtr<ElementNode> m_next;
+        ElementNode* m_next;
         int m_elision;
-        RefPtr<ExpressionNode> m_node;
+        ExpressionNode* m_node;
     };
 
     class ArrayNode : public ExpressionNode {
     public:
-        ArrayNode(JSGlobalData* globalData, int elision) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_elision(elision)
-            , m_optional(true)
-        {
-        }
-
-        ArrayNode(JSGlobalData* globalData, ElementNode* element) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_element(element)
-            , m_elision(0)
-            , m_optional(false)
-        {
-        }
+        ArrayNode(JSGlobalData*, int elision);
+        ArrayNode(JSGlobalData*, ElementNode*);
+        ArrayNode(JSGlobalData*, int elision, ElementNode*);
 
-        ArrayNode(JSGlobalData* globalData, int elision, ElementNode* element) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_element(element)
-            , m_elision(elision)
-            , m_optional(true)
-        {
-        }
+        ArgumentListNode* toArgumentList(JSGlobalData*) const;
 
-        virtual ~ArrayNode();
-        virtual void releaseNodes(NodeReleaser&);
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        virtual bool isSimpleArray() const ;
 
-    private:
-        RefPtr<ElementNode> m_element;
+        ElementNode* m_element;
         int m_elision;
         bool m_optional;
     };
 
-    class PropertyNode : public ParserRefCounted {
+    class PropertyNode : public ParserArenaDeletable {
     public:
         enum Type { Constant, Getter, Setter };
 
-        PropertyNode(JSGlobalData* globalData, const Identifier& name, ExpressionNode* assign, Type type) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_name(name)
-            , m_assign(assign)
-            , m_type(type)
-        {
-        }
-
-        virtual ~PropertyNode();
-        virtual void releaseNodes(NodeReleaser&);
+        PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type);
 
         const Identifier& name() const { return m_name; }
 
     private:
         friend class PropertyListNode;
         Identifier m_name;
-        RefPtr<ExpressionNode> m_assign;
+        ExpressionNode* m_assign;
         Type m_type;
     };
 
     class PropertyListNode : public Node {
     public:
-        PropertyListNode(JSGlobalData* globalData, PropertyNode* node) JSC_FAST_CALL
-            : Node(globalData)
-            , m_node(node)
-        {
-        }
-
-        PropertyListNode(JSGlobalData* globalData, PropertyNode* node, PropertyListNode* list) JSC_FAST_CALL
-            : Node(globalData)
-            , m_node(node)
-        {
-            list->m_next = this;
-        }
-
-        virtual ~PropertyListNode();
-        virtual void releaseNodes(NodeReleaser&);
+        PropertyListNode(JSGlobalData*, PropertyNode*);
+        PropertyListNode(JSGlobalData*, PropertyNode*, PropertyListNode*);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
     private:
-        RefPtr<PropertyNode> m_node;
-        RefPtr<PropertyListNode> m_next;
+        PropertyNode* m_node;
+        PropertyListNode* m_next;
     };
 
     class ObjectLiteralNode : public ExpressionNode {
     public:
-        ObjectLiteralNode(JSGlobalData* globalData) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-        {
-        }
-
-        ObjectLiteralNode(JSGlobalData* globalData, PropertyListNode* list) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_list(list)
-        {
-        }
-
-        virtual ~ObjectLiteralNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        ObjectLiteralNode(JSGlobalData*);
+        ObjectLiteralNode(JSGlobalData*, PropertyListNode*);
 
     private:
-        RefPtr<PropertyListNode> m_list;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        PropertyListNode* m_list;
     };
     
     class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        BracketAccessorNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_base(base)
-            , m_subscript(subscript)
-            , m_subscriptHasAssignments(subscriptHasAssignments)
-        {
-        }
+        BracketAccessorNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
 
-        virtual ~BracketAccessorNode();
-        virtual void releaseNodes(NodeReleaser&);
+        ExpressionNode* base() const { return m_base; }
+        ExpressionNode* subscript() const { return m_subscript; }
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual bool isLocation() const JSC_FAST_CALL { return true; }
-        virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return true; }
-        ExpressionNode* base() JSC_FAST_CALL { return m_base.get(); }
-        ExpressionNode* subscript() JSC_FAST_CALL { return m_subscript.get(); }
+        virtual bool isLocation() const { return true; }
+        virtual bool isBracketAccessorNode() const { return true; }
 
-    private:
-        RefPtr<ExpressionNode> m_base;
-        RefPtr<ExpressionNode> m_subscript;
+        ExpressionNode* m_base;
+        ExpressionNode* m_subscript;
         bool m_subscriptHasAssignments;
     };
 
     class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DotAccessorNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_base(base)
-            , m_ident(ident)
-        {
-        }
+        DotAccessorNode(JSGlobalData*, ExpressionNode* base, const Identifier&);
 
-        virtual ~DotAccessorNode();
-        virtual void releaseNodes(NodeReleaser&);
+        ExpressionNode* base() const { return m_base; }
+        const Identifier& identifier() const { return m_ident; }
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual bool isLocation() const JSC_FAST_CALL { return true; }
-        virtual bool isDotAccessorNode() const JSC_FAST_CALL { return true; }
-        ExpressionNode* base() const JSC_FAST_CALL { return m_base.get(); }
-        const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
+        virtual bool isLocation() const { return true; }
+        virtual bool isDotAccessorNode() const { return true; }
 
-    private:
-        RefPtr<ExpressionNode> m_base;
+        ExpressionNode* m_base;
         Identifier m_ident;
     };
 
     class ArgumentListNode : public Node {
     public:
-        ArgumentListNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : Node(globalData)
-            , m_expr(expr)
-        {
-        }
+        ArgumentListNode(JSGlobalData*, ExpressionNode*);
+        ArgumentListNode(JSGlobalData*, ArgumentListNode*, ExpressionNode*);
 
-        ArgumentListNode(JSGlobalData* globalData, ArgumentListNode* listNode, ExpressionNode* expr) JSC_FAST_CALL
-            : Node(globalData)
-            , m_expr(expr)
-        {
-            listNode->m_next = this;
-        }
-
-        virtual ~ArgumentListNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        ArgumentListNode* m_next;
+        ExpressionNode* m_expr;
 
-        RefPtr<ArgumentListNode> m_next;
-        RefPtr<ExpressionNode> m_expr;
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
-    class ArgumentsNode : public ParserRefCounted {
+    class ArgumentsNode : public ParserArenaDeletable {
     public:
-        ArgumentsNode(JSGlobalData* globalData) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-        {
-        }
-
-        ArgumentsNode(JSGlobalData* globalData, ArgumentListNode* listNode) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_listNode(listNode)
-        {
-        }
+        ArgumentsNode(JSGlobalData*);
+        ArgumentsNode(JSGlobalData*, ArgumentListNode*);
 
-        virtual ~ArgumentsNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        RefPtr<ArgumentListNode> m_listNode;
+        ArgumentListNode* m_listNode;
     };
 
     class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        NewExprNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_expr(expr)
-        {
-        }
-
-        NewExprNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_expr(expr)
-            , m_args(args)
-        {
-        }
-
-        virtual ~NewExprNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        NewExprNode(JSGlobalData*, ExpressionNode*);
+        NewExprNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
-        RefPtr<ArgumentsNode> m_args;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
+        ArgumentsNode* m_args;
     };
 
     class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        EvalFunctionCallNode(JSGlobalData* globalData, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_args(args)
-        {
-        }
-
-        virtual ~EvalFunctionCallNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        EvalFunctionCallNode(JSGlobalData*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ArgumentsNode> m_args;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ArgumentsNode* m_args;
     };
 
     class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        FunctionCallValueNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_expr(expr)
-            , m_args(args)
-        {
-        }
-
-        virtual ~FunctionCallValueNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        FunctionCallValueNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
-        RefPtr<ArgumentsNode> m_args;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
+        ArgumentsNode* m_args;
     };
 
     class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        FunctionCallResolveNode(JSGlobalData* globalData, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_ident(ident)
-            , m_args(args)
-        {
-        }
-
-        virtual ~FunctionCallResolveNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        FunctionCallResolveNode(JSGlobalData*, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Identifier m_ident;
-        RefPtr<ArgumentsNode> m_args;
+        ArgumentsNode* m_args;
         size_t m_index; // Used by LocalVarFunctionCallNode.
         size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
     };
     
     class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        FunctionCallBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableSubExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_subscript(subscript)
-            , m_args(args)
-        {
-        }
-
-        virtual ~FunctionCallBracketNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        FunctionCallBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
-        RefPtr<ExpressionNode> m_subscript;
-        RefPtr<ArgumentsNode> m_args;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
+        ExpressionNode* m_subscript;
+        ArgumentsNode* m_args;
     };
 
     class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        FunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableSubExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_ident(ident)
-            , m_args(args)
-        {
-        }
+        FunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual ~FunctionCallDotNode();
-        virtual void releaseNodes(NodeReleaser&);
+    protected:
+        ExpressionNode* m_base;
+        const Identifier m_ident;
+        ArgumentsNode* m_args;
+    };
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    class CallFunctionCallDotNode : public FunctionCallDotNode {
+    public:
+        CallFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
-        Identifier m_ident;
-        RefPtr<ArgumentsNode> m_args;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+    };
+    
+    class ApplyFunctionCallDotNode : public FunctionCallDotNode {
+    public:
+        ApplyFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
     class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        PrePostResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData, ResultType::numberType()) // could be reusable for pre?
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_ident(ident)
-        {
-        }
+        PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     protected:
-        Identifier m_ident;
+        const Identifier m_ident;
     };
 
     class PostfixResolveNode : public PrePostResolveNode {
     public:
-        PostfixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
-            , m_operator(oper)
-        {
-        }
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        PostfixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Operator m_operator;
     };
 
     class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        PostfixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableSubExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_subscript(subscript)
-            , m_operator(oper)
-        {
-        }
-
-        virtual ~PostfixBracketNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        PostfixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
-        RefPtr<ExpressionNode> m_subscript;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
+        ExpressionNode* m_subscript;
         Operator m_operator;
     };
 
     class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        PostfixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableSubExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_ident(ident)
-            , m_operator(oper)
-        {
-        }
-
-        virtual ~PostfixDotNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        PostfixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
         Identifier m_ident;
         Operator m_operator;
     };
 
     class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        PostfixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableSubExpressionData(divot, startOffset, endOffset)
-            , m_expr(expr)
-            , m_operator(oper)
-        {
-        }
-
-        virtual ~PostfixErrorNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        PostfixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
         Operator m_operator;
     };
 
     class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DeleteResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_ident(ident)
-        {
-        }
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        DeleteResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Identifier m_ident;
     };
 
     class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DeleteBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_subscript(subscript)
-        {
-        }
-
-        virtual ~DeleteBracketNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        DeleteBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
-        RefPtr<ExpressionNode> m_subscript;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
+        ExpressionNode* m_subscript;
     };
 
     class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DeleteDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_ident(ident)
-        {
-        }
-
-        virtual ~DeleteDotNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        DeleteDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
         Identifier m_ident;
     };
 
     class DeleteValueNode : public ExpressionNode {
     public:
-        DeleteValueNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_expr(expr)
-        {
-        }
-
-        virtual ~DeleteValueNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        DeleteValueNode(JSGlobalData*, ExpressionNode*);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
     };
 
     class VoidNode : public ExpressionNode {
     public:
-        VoidNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_expr(expr)
-        {
-        }
-
-        virtual ~VoidNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        VoidNode(JSGlobalData*, ExpressionNode*);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
     };
 
     class TypeOfResolveNode : public ExpressionNode {
     public:
-        TypeOfResolveNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
-            : ExpressionNode(globalData, ResultType::stringType())
-            , m_ident(ident)
-        {
-        }
+        TypeOfResolveNode(JSGlobalData*, const Identifier&);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
-        const Identifier& identifier() const JSC_FAST_CALL { return m_ident; }
+        const Identifier& identifier() const { return m_ident; }
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Identifier m_ident;
     };
 
     class TypeOfValueNode : public ExpressionNode {
     public:
-        TypeOfValueNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : ExpressionNode(globalData, ResultType::stringType())
-            , m_expr(expr)
-        {
-        }
-
-        virtual ~TypeOfValueNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        TypeOfValueNode(JSGlobalData*, ExpressionNode*);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
     };
 
     class PrefixResolveNode : public PrePostResolveNode {
     public:
-        PrefixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
-            , m_operator(oper)
-        {
-        }
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        PrefixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Operator m_operator;
     };
 
     class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
     public:
-        PrefixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_subscript(subscript)
-            , m_operator(oper)
-        {
-        }
-
-        virtual ~PrefixBracketNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        PrefixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
-        RefPtr<ExpressionNode> m_subscript;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
+        ExpressionNode* m_subscript;
         Operator m_operator;
     };
 
     class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
     public:
-        PrefixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_ident(ident)
-            , m_operator(oper)
-        {
-        }
-
-        virtual ~PrefixDotNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        PrefixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
         Identifier m_ident;
         Operator m_operator;
     };
 
     class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        PrefixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_expr(expr)
-            , m_operator(oper)
-        {
-        }
-
-        virtual ~PrefixErrorNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        PrefixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
         Operator m_operator;
     };
 
     class UnaryOpNode : public ExpressionNode {
     public:
-        UnaryOpNode(JSGlobalData* globalData, ExpressionNode* expr)
-            : ExpressionNode(globalData)
-            , m_expr(expr)
-        {
-        }
+        UnaryOpNode(JSGlobalData*, ResultType, ExpressionNode*, OpcodeID);
 
-        UnaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr)
-            : ExpressionNode(globalData, type)
-            , m_expr(expr)
-        {
-        }
+    protected:
+        ExpressionNode* expr() { return m_expr; }
 
-        virtual ~UnaryOpNode();
-        virtual void releaseNodes(NodeReleaser&);
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL = 0;
+        OpcodeID opcodeID() const { return m_opcodeID; }
 
-    protected:
-        RefPtr<ExpressionNode> m_expr;
+        ExpressionNode* m_expr;
+        OpcodeID m_opcodeID;
     };
 
     class UnaryPlusNode : public UnaryOpNode {
     public:
-        UnaryPlusNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : UnaryOpNode(globalData, ResultType::numberType(), expr)
-        {
-        }
-
-        virtual ExpressionNode* stripUnaryPlus() { return m_expr.get(); }
+        UnaryPlusNode(JSGlobalData*, ExpressionNode*);
 
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_to_jsnumber; }
+    private:
+        virtual ExpressionNode* stripUnaryPlus() { return expr(); }
     };
 
     class NegateNode : public UnaryOpNode {
     public:
-        NegateNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : UnaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_negate; }
+        NegateNode(JSGlobalData*, ExpressionNode*);
     };
 
     class BitwiseNotNode : public UnaryOpNode {
     public:
-        BitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : UnaryOpNode(globalData, ResultType::forBitOp(), expr)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitnot; }
+        BitwiseNotNode(JSGlobalData*, ExpressionNode*);
     };
 
     class LogicalNotNode : public UnaryOpNode {
     public:
-        LogicalNotNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : UnaryOpNode(globalData, ResultType::booleanType(), expr)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_not; }
+        LogicalNotNode(JSGlobalData*, ExpressionNode*);
     };
 
     class BinaryOpNode : public ExpressionNode {
     public:
-        BinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
-            : ExpressionNode(globalData)
-            , m_expr1(expr1)
-            , m_expr2(expr2)
-            , m_rightHasAssignments(rightHasAssignments)
-        {
-        }
+        BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+        BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
 
-        BinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
-            : ExpressionNode(globalData, type)
-            , m_expr1(expr1)
-            , m_expr2(expr2)
-            , m_rightHasAssignments(rightHasAssignments)
-        {
-        }
+        RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
 
-        virtual ~BinaryOpNode();
-        virtual void releaseNodes(NodeReleaser&);
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL = 0;
+    protected:
+        OpcodeID opcodeID() const { return m_opcodeID; }
 
     protected:
-        RefPtr<ExpressionNode> m_expr1;
-        RefPtr<ExpressionNode> m_expr2;
+        ExpressionNode* m_expr1;
+        ExpressionNode* m_expr2;
+    private:
+        OpcodeID m_opcodeID;
+    protected:
         bool m_rightHasAssignments;
     };
 
     class ReverseBinaryOpNode : public BinaryOpNode {
     public:
-        ReverseBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
-            : BinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
-        {
-        }
+        ReverseBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+        ReverseBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
 
-        ReverseBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
-            : BinaryOpNode(globalData, type, expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
     class MultNode : public BinaryOpNode {
     public:
-        MultNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_mul; }
+        MultNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class DivNode : public BinaryOpNode {
     public:
-        DivNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_div; }
+        DivNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class ModNode : public BinaryOpNode {
     public:
-        ModNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_mod; }
+        ModNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class AddNode : public BinaryOpNode {
     public:
-        AddNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::forAdd(expr1->resultDescriptor(), expr2->resultDescriptor()), expr1, expr2, rightHasAssignments)
-        {
-        }
+        AddNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_add; }
+        virtual bool isAdd() const { return true; }
     };
 
     class SubNode : public BinaryOpNode {
     public:
-        SubNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_sub; }
+        SubNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class LeftShiftNode : public BinaryOpNode {
     public:
-        LeftShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_lshift; }
+        LeftShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class RightShiftNode : public BinaryOpNode {
     public:
-        RightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_rshift; }
+        RightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class UnsignedRightShiftNode : public BinaryOpNode {
     public:
-        UnsignedRightShiftNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::numberTypeCanReuse(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_urshift; }
+        UnsignedRightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class LessNode : public BinaryOpNode {
     public:
-        LessNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_less; }
+        LessNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class GreaterNode : public ReverseBinaryOpNode {
     public:
-        GreaterNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_less; }
+        GreaterNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class LessEqNode : public BinaryOpNode {
     public:
-        LessEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_lesseq; }
+        LessEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class GreaterEqNode : public ReverseBinaryOpNode {
     public:
-        GreaterEqNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : ReverseBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_lesseq; }
+        GreaterEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
     public:
-        ThrowableBinaryOpNode(JSGlobalData* globalData, ResultType type, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, type, expr1, expr2, rightHasAssignments)
-        {
-        }
-        ThrowableBinaryOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
-        {
-        }
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        ThrowableBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+        ThrowableBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
     
     class InstanceOfNode : public ThrowableBinaryOpNode {
     public:
-        InstanceOfNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : ThrowableBinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_instanceof; }
+        InstanceOfNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
     class InNode : public ThrowableBinaryOpNode {
     public:
-        InNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : ThrowableBinaryOpNode(globalData, expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_in; }
+        InNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class EqualNode : public BinaryOpNode {
     public:
-        EqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
-        {
-        }
+        EqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_eq; }
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
     class NotEqualNode : public BinaryOpNode {
     public:
-        NotEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_neq; }
+        NotEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class StrictEqualNode : public BinaryOpNode {
     public:
-        StrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
-        {
-        }
+        StrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_stricteq; }
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
     class NotStrictEqualNode : public BinaryOpNode {
     public:
-        NotStrictEqualNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::booleanType(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_nstricteq; }
+        NotStrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class BitAndNode : public BinaryOpNode {
     public:
-        BitAndNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitand; }
+        BitAndNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class BitOrNode : public BinaryOpNode {
     public:
-        BitOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitor; }
+        BitOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class BitXOrNode : public BinaryOpNode {
     public:
-        BitXOrNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments) JSC_FAST_CALL
-            : BinaryOpNode(globalData, ResultType::forBitOp(), expr1, expr2, rightHasAssignments)
-        {
-        }
-
-        virtual OpcodeID opcodeID() const JSC_FAST_CALL { return op_bitxor; }
+        BitXOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
-    /**
-     * m_expr1 && m_expr2, m_expr1 || m_expr2
-     */
+    // m_expr1 && m_expr2, m_expr1 || m_expr2
     class LogicalOpNode : public ExpressionNode {
     public:
-        LogicalOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator oper) JSC_FAST_CALL
-            : ExpressionNode(globalData, ResultType::booleanType())
-            , m_expr1(expr1)
-            , m_expr2(expr2)
-            , m_operator(oper)
-        {
-        }
-
-        virtual ~LogicalOpNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        LogicalOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
 
     private:
-        RefPtr<ExpressionNode> m_expr1;
-        RefPtr<ExpressionNode> m_expr2;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr1;
+        ExpressionNode* m_expr2;
         LogicalOperator m_operator;
     };
 
-    /**
-     * The ternary operator, "m_logical ? m_expr1 : m_expr2"
-     */
+    // The ternary operator, "m_logical ? m_expr1 : m_expr2"
     class ConditionalNode : public ExpressionNode {
     public:
-        ConditionalNode(JSGlobalData* globalData, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_logical(logical)
-            , m_expr1(expr1)
-            , m_expr2(expr2)
-        {
-        }
-
-        virtual ~ConditionalNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        ConditionalNode(JSGlobalData*, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
 
     private:
-        RefPtr<ExpressionNode> m_logical;
-        RefPtr<ExpressionNode> m_expr1;
-        RefPtr<ExpressionNode> m_expr2;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_logical;
+        ExpressionNode* m_expr1;
+        ExpressionNode* m_expr2;
     };
 
     class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        ReadModifyResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, ExpressionNode*  right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_ident(ident)
-            , m_right(right)
-            , m_operator(oper)
-            , m_rightHasAssignments(rightHasAssignments)
-        {
-        }
-
-        virtual ~ReadModifyResolveNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        ReadModifyResolveNode(JSGlobalData*, const Identifier&, Operator, ExpressionNode*  right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Identifier m_ident;
-        RefPtr<ExpressionNode> m_right;
+        ExpressionNode* m_right;
         size_t m_index; // Used by ReadModifyLocalVarNode.
-        Operator m_operator : 31;
-        bool m_rightHasAssignments : 1;
+        Operator m_operator;
+        bool m_rightHasAssignments;
     };
 
     class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignResolveNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_ident(ident)
-            , m_right(right)
-            , m_rightHasAssignments(rightHasAssignments)
-        {
-        }
-
-        virtual ~AssignResolveNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        AssignResolveNode(JSGlobalData*, const Identifier&, ExpressionNode* right, bool rightHasAssignments);
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Identifier m_ident;
-        RefPtr<ExpressionNode> m_right;
+        ExpressionNode* m_right;
         size_t m_index; // Used by ReadModifyLocalVarNode.
         bool m_rightHasAssignments;
     };
 
     class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        ReadModifyBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableSubExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_subscript(subscript)
-            , m_right(right)
-            , m_operator(oper)
-            , m_subscriptHasAssignments(subscriptHasAssignments)
-            , m_rightHasAssignments(rightHasAssignments)
-        {
-        }
-
-        virtual ~ReadModifyBracketNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        ReadModifyBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
-        RefPtr<ExpressionNode> m_subscript;
-        RefPtr<ExpressionNode> m_right;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
+        ExpressionNode* m_subscript;
+        ExpressionNode* m_right;
         Operator m_operator : 30;
         bool m_subscriptHasAssignments : 1;
         bool m_rightHasAssignments : 1;
@@ -1524,168 +1038,109 @@ namespace JSC {
 
     class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_subscript(subscript)
-            , m_right(right)
-            , m_subscriptHasAssignments(subscriptHasAssignments)
-            , m_rightHasAssignments(rightHasAssignments)
-        {
-        }
-
-        virtual ~AssignBracketNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        AssignBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
-        RefPtr<ExpressionNode> m_subscript;
-        RefPtr<ExpressionNode> m_right;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
+        ExpressionNode* m_subscript;
+        ExpressionNode* m_right;
         bool m_subscriptHasAssignments : 1;
         bool m_rightHasAssignments : 1;
     };
 
     class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_ident(ident)
-            , m_right(right)
-            , m_rightHasAssignments(rightHasAssignments)
-        {
-        }
-
-        virtual ~AssignDotNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        AssignDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
         Identifier m_ident;
-        RefPtr<ExpressionNode> m_right;
+        ExpressionNode* m_right;
         bool m_rightHasAssignments;
     };
 
     class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        ReadModifyDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableSubExpressionData(divot, startOffset, endOffset)
-            , m_base(base)
-            , m_ident(ident)
-            , m_right(right)
-            , m_operator(oper)
-            , m_rightHasAssignments(rightHasAssignments)
-        {
-        }
-
-        virtual ~ReadModifyDotNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        ReadModifyDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_base;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_base;
         Identifier m_ident;
-        RefPtr<ExpressionNode> m_right;
+        ExpressionNode* m_right;
         Operator m_operator : 31;
         bool m_rightHasAssignments : 1;
     };
 
     class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignErrorNode(JSGlobalData* globalData, ExpressionNode* left, Operator oper, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , ThrowableExpressionData(divot, startOffset, endOffset)
-            , m_left(left)
-            , m_operator(oper)
-            , m_right(right)
-        {
-        }
-
-        virtual ~AssignErrorNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        AssignErrorNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset);
 
     private:
-        RefPtr<ExpressionNode> m_left;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_left;
         Operator m_operator;
-        RefPtr<ExpressionNode> m_right;
+        ExpressionNode* m_right;
     };
+    
+    typedef Vector<ExpressionNode*, 8> ExpressionVector;
 
     class CommaNode : public ExpressionNode {
     public:
-        CommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_expr1(expr1)
-            , m_expr2(expr2)
-        {
-        }
+        CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2);
 
-        virtual ~CommaNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        void append(ExpressionNode* expr) { m_expressions.append(expr); }
 
     private:
-        RefPtr<ExpressionNode> m_expr1;
-        RefPtr<ExpressionNode> m_expr2;
+        virtual bool isCommaNode() const { return true; }
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionVector m_expressions;
     };
     
-    class VarDeclCommaNode : public CommaNode {
-    public:
-        VarDeclCommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2) JSC_FAST_CALL
-            : CommaNode(globalData, expr1, expr2)
-        {
-        }
-    };
-
     class ConstDeclNode : public ExpressionNode {
     public:
-        ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in) JSC_FAST_CALL;
+        ConstDeclNode(JSGlobalData*, const Identifier&, ExpressionNode*);
+
+        bool hasInitializer() const { return m_init; }
+        const Identifier& ident() { return m_ident; }
 
-        virtual ~ConstDeclNode();
-        virtual void releaseNodes(NodeReleaser&);
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
 
         Identifier m_ident;
-        RefPtr<ConstDeclNode> m_next;
-        RefPtr<ExpressionNode> m_init;
-        
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-        virtual RegisterID* emitCodeSingle(BytecodeGenerator&) JSC_FAST_CALL;
-    };
 
-    class ConstStatementNode : public StatementNode {
     public:
-        ConstStatementNode(JSGlobalData* globalData, ConstDeclNode* next) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_next(next)
-        {
-        }
+        ConstDeclNode* m_next;
 
-        virtual ~ConstStatementNode();
-        virtual void releaseNodes(NodeReleaser&);
+    private:
+        ExpressionNode* m_init;
+    };
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    class ConstStatementNode : public StatementNode {
+    public:
+        ConstStatementNode(JSGlobalData*, ConstDeclNode* next);
 
     private:
-        RefPtr<ConstDeclNode> m_next;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ConstDeclNode* m_next;
     };
 
-    typedef Vector<RefPtr<StatementNode> > StatementVector;
+    typedef Vector<StatementNode*> StatementVector;
 
-    class SourceElements : public ParserRefCounted {
+    class SourceElements : public ParserArenaDeletable {
     public:
-        SourceElements(JSGlobalData* globalData) : ParserRefCounted(globalData) {}
+        SourceElements(JSGlobalData*);
 
-        void append(PassRefPtr<StatementNode>);
+        void append(StatementNode*);
         void releaseContentsIntoVector(StatementVector& destination)
         {
             ASSERT(destination.isEmpty());
@@ -1699,377 +1154,235 @@ namespace JSC {
 
     class BlockNode : public StatementNode {
     public:
-        BlockNode(JSGlobalData*, SourceElements* children) JSC_FAST_CALL;
-
-        virtual ~BlockNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        BlockNode(JSGlobalData*, SourceElements* children);
 
         StatementVector& children() { return m_children; }
 
-        virtual bool isBlock() const JSC_FAST_CALL { return true; }
-
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        virtual bool isBlock() const { return true; }
+
         StatementVector m_children;
     };
 
     class EmptyStatementNode : public StatementNode {
     public:
-        EmptyStatementNode(JSGlobalData* globalData) JSC_FAST_CALL // debug
-            : StatementNode(globalData)
-        {
-        }
+        EmptyStatementNode(JSGlobalData*);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual bool isEmptyStatement() const JSC_FAST_CALL { return true; }
+        virtual bool isEmptyStatement() const { return true; }
     };
     
     class DebuggerStatementNode : public StatementNode {
     public:
-        DebuggerStatementNode(JSGlobalData* globalData) JSC_FAST_CALL
-            : StatementNode(globalData)
-        {
-        }
+        DebuggerStatementNode(JSGlobalData*);
         
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
     class ExprStatementNode : public StatementNode {
     public:
-        ExprStatementNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_expr(expr)
-        {
-        }
+        ExprStatementNode(JSGlobalData*, ExpressionNode*);
 
-        virtual bool isExprStatement() const JSC_FAST_CALL { return true; }
+        ExpressionNode* expr() const { return m_expr; }
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+    private:
+        virtual bool isExprStatement() const { return true; }
 
-        ExpressionNode* expr() const { return m_expr.get(); }
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-    private:
-        RefPtr<ExpressionNode> m_expr;
+        ExpressionNode* m_expr;
     };
 
     class VarStatementNode : public StatementNode {
     public:
-        VarStatementNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_expr(expr)
-        {
-        }
-        
-        virtual ~VarStatementNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        VarStatementNode(JSGlobalData*, ExpressionNode*);        
 
     private:
-        RefPtr<ExpressionNode> m_expr;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
     };
 
     class IfNode : public StatementNode {
     public:
-        IfNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_condition(condition)
-            , m_ifBlock(ifBlock)
-        {
-        }
-
-        virtual ~IfNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        IfNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock);
 
     protected:
-        RefPtr<ExpressionNode> m_condition;
-        RefPtr<StatementNode> m_ifBlock;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_condition;
+        StatementNode* m_ifBlock;
     };
 
     class IfElseNode : public IfNode {
     public:
-        IfElseNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock) JSC_FAST_CALL
-            : IfNode(globalData, condition, ifBlock)
-            , m_elseBlock(elseBlock)
-        {
-        }
-
-        virtual ~IfElseNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        IfElseNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
 
     private:
-        RefPtr<StatementNode> m_elseBlock;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        StatementNode* m_elseBlock;
     };
 
     class DoWhileNode : public StatementNode {
     public:
-        DoWhileNode(JSGlobalData* globalData, StatementNode* statement, ExpressionNode* expr) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_statement(statement)
-            , m_expr(expr)
-        {
-        }
-
-        virtual ~DoWhileNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
-        virtual bool isLoop() const JSC_FAST_CALL { return true; }
+        DoWhileNode(JSGlobalData*, StatementNode* statement, ExpressionNode*);
 
     private:
-        RefPtr<StatementNode> m_statement;
-        RefPtr<ExpressionNode> m_expr;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        StatementNode* m_statement;
+        ExpressionNode* m_expr;
     };
 
     class WhileNode : public StatementNode {
     public:
-        WhileNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_expr(expr)
-            , m_statement(statement)
-        {
-        }
-
-        virtual ~WhileNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
-        virtual bool isLoop() const JSC_FAST_CALL { return true; }
+        WhileNode(JSGlobalData*, ExpressionNode*, StatementNode* statement);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
-        RefPtr<StatementNode> m_statement;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
+        StatementNode* m_statement;
     };
 
     class ForNode : public StatementNode {
     public:
-        ForNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_expr1(expr1)
-            , m_expr2(expr2)
-            , m_expr3(expr3)
-            , m_statement(statement)
-            , m_expr1WasVarDecl(expr1 && expr1WasVarDecl)
-        {
-            ASSERT(statement);
-        }
-
-        virtual ~ForNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
-        virtual bool isLoop() const JSC_FAST_CALL { return true; }
+        ForNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl);
 
     private:
-        RefPtr<ExpressionNode> m_expr1;
-        RefPtr<ExpressionNode> m_expr2;
-        RefPtr<ExpressionNode> m_expr3;
-        RefPtr<StatementNode> m_statement;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr1;
+        ExpressionNode* m_expr2;
+        ExpressionNode* m_expr3;
+        StatementNode* m_statement;
         bool m_expr1WasVarDecl;
     };
 
     class ForInNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*) JSC_FAST_CALL;
-        ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset) JSC_FAST_CALL;
-        
-        virtual ~ForInNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
-        virtual bool isLoop() const JSC_FAST_CALL { return true; }
+        ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*);
+        ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Identifier m_ident;
-        RefPtr<ExpressionNode> m_init;
-        RefPtr<ExpressionNode> m_lexpr;
-        RefPtr<ExpressionNode> m_expr;
-        RefPtr<StatementNode> m_statement;
+        ExpressionNode* m_init;
+        ExpressionNode* m_lexpr;
+        ExpressionNode* m_expr;
+        StatementNode* m_statement;
         bool m_identIsVarDecl;
     };
 
     class ContinueNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ContinueNode(JSGlobalData* globalData) JSC_FAST_CALL
-            : StatementNode(globalData)
-        {
-        }
-
-        ContinueNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_ident(ident)
-        {
-        }
+        ContinueNode(JSGlobalData*);
+        ContinueNode(JSGlobalData*, const Identifier&);
         
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Identifier m_ident;
     };
 
     class BreakNode : public StatementNode, public ThrowableExpressionData {
     public:
-        BreakNode(JSGlobalData* globalData) JSC_FAST_CALL
-            : StatementNode(globalData)
-        {
-        }
-
-        BreakNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_ident(ident)
-        {
-        }
+        BreakNode(JSGlobalData*);
+        BreakNode(JSGlobalData*, const Identifier&);
         
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Identifier m_ident;
     };
 
     class ReturnNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ReturnNode(JSGlobalData* globalData, ExpressionNode* value) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_value(value)
-        {
-        }
+        ReturnNode(JSGlobalData*, ExpressionNode* value);
 
-        virtual ~ReturnNode();
-        virtual void releaseNodes(NodeReleaser&);
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-        virtual bool isReturnNode() const JSC_FAST_CALL { return true; }
+        virtual bool isReturnNode() const { return true; }
 
-    private:
-        RefPtr<ExpressionNode> m_value;
+        ExpressionNode* m_value;
     };
 
     class WithNode : public StatementNode {
     public:
-        WithNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement, uint32_t divot, uint32_t expressionLength) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_expr(expr)
-            , m_statement(statement)
-            , m_divot(divot)
-            , m_expressionLength(expressionLength)
-        {
-        }
-
-        virtual ~WithNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        WithNode(JSGlobalData*, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
-        RefPtr<StatementNode> m_statement;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
+        StatementNode* m_statement;
         uint32_t m_divot;
         uint32_t m_expressionLength;
     };
 
     class LabelNode : public StatementNode, public ThrowableExpressionData {
     public:
-        LabelNode(JSGlobalData* globalData, const Identifier& name, StatementNode* statement) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_name(name)
-            , m_statement(statement)
-        {
-        }
-
-        virtual ~LabelNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        LabelNode(JSGlobalData*, const Identifier& name, StatementNode*);
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         Identifier m_name;
-        RefPtr<StatementNode> m_statement;
+        StatementNode* m_statement;
     };
 
     class ThrowNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ThrowNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_expr(expr)
-        {
-        }
-
-        virtual ~ThrowNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        ThrowNode(JSGlobalData*, ExpressionNode*);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
     };
 
     class TryNode : public StatementNode {
     public:
-        TryNode(JSGlobalData* globalData, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_tryBlock(tryBlock)
-            , m_exceptionIdent(exceptionIdent)
-            , m_catchBlock(catchBlock)
-            , m_finallyBlock(finallyBlock)
-            , m_catchHasEval(catchHasEval)
-        {
-        }
-
-        virtual ~TryNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL;
+        TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock);
 
     private:
-        RefPtr<StatementNode> m_tryBlock;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0);
+
+        StatementNode* m_tryBlock;
         Identifier m_exceptionIdent;
-        RefPtr<StatementNode> m_catchBlock;
-        RefPtr<StatementNode> m_finallyBlock;
+        StatementNode* m_catchBlock;
+        StatementNode* m_finallyBlock;
         bool m_catchHasEval;
     };
 
-    class ParameterNode : public ParserRefCounted {
+    class ParameterNode : public ParserArenaDeletable {
     public:
-        ParameterNode(JSGlobalData* globalData, const Identifier& ident) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_ident(ident)
-        {
-        }
-
-        ParameterNode(JSGlobalData* globalData, ParameterNode* l, const Identifier& ident) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_ident(ident)
-        {
-            l->m_next = this;
-        }
-
-        virtual ~ParameterNode();
-        virtual void releaseNodes(NodeReleaser&);
+        ParameterNode(JSGlobalData*, const Identifier&);
+        ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&);
 
-        const Identifier& ident() const JSC_FAST_CALL { return m_ident; }
-        ParameterNode* nextParam() const JSC_FAST_CALL { return m_next.get(); }
+        const Identifier& ident() const { return m_ident; }
+        ParameterNode* nextParam() const { return m_next; }
 
     private:
         Identifier m_ident;
-        RefPtr<ParameterNode> m_next;
+        ParameterNode* m_next;
     };
 
     struct ScopeNodeData {
         typedef DeclarationStacks::VarStack VarStack;
         typedef DeclarationStacks::FunctionStack FunctionStack;
 
-        ScopeNodeData(SourceElements*, VarStack*, FunctionStack*, int numConstants);
+        ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, int numConstants);
 
+        ParserArena m_arena;
         VarStack m_varStack;
         FunctionStack m_functionStack;
         int m_numConstants;
@@ -2078,22 +1391,25 @@ namespace JSC {
         void mark();
     };
 
-    class ScopeNode : public StatementNode {
+    class ScopeNode : public StatementNode, public ParserArenaRefCounted {
     public:
         typedef DeclarationStacks::VarStack VarStack;
         typedef DeclarationStacks::FunctionStack FunctionStack;
 
-        ScopeNode(JSGlobalData*) JSC_FAST_CALL;
-        ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
-        virtual ~ScopeNode();
-        virtual void releaseNodes(NodeReleaser&);
+        ScopeNode(JSGlobalData*);
+        ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants);
 
-        void adoptData(std::auto_ptr<ScopeNodeData> data) { m_data.adopt(data); }
+        void adoptData(std::auto_ptr<ScopeNodeData> data)
+        {
+            ASSERT(!data->m_arena.contains(this));
+            ASSERT(!m_data);
+            m_data.adopt(data);
+        }
         ScopeNodeData* data() const { return m_data.get(); }
         void destroyData() { m_data.clear(); }
 
         const SourceCode& source() const { return m_source; }
-        const UString& sourceURL() const JSC_FAST_CALL { return m_source.provider()->url(); }
+        const UString& sourceURL() const { return m_source.provider()->url(); }
         intptr_t sourceID() const { return m_source.provider()->asID(); }
 
         void setFeatures(CodeFeatures features) { m_features = features; }
@@ -2120,9 +1436,31 @@ namespace JSC {
 
         virtual void mark() { }
 
+#if ENABLE(JIT)
+        JITCode& generatedJITCode()
+        {
+            ASSERT(m_jitCode);
+            return m_jitCode;
+        }
+
+        ExecutablePool* getExecutablePool()
+        {
+            return m_jitCode.getExecutablePool();
+        }
+
+        void setJITCode(const JITCode jitCode)
+        {
+            m_jitCode = jitCode;
+        }
+#endif
+
     protected:
         void setSource(const SourceCode& source) { m_source = source; }
 
+#if ENABLE(JIT)
+        JITCode m_jitCode;
+#endif
+
     private:
         OwnPtr<ScopeNodeData> m_data;
         CodeFeatures m_features;
@@ -2131,44 +1469,70 @@ namespace JSC {
 
     class ProgramNode : public ScopeNode {
     public:
-        static ProgramNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+        static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
 
-        ProgramCodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
+        ProgramCodeBlock& bytecode(ScopeChainNode* scopeChain) 
         {
             if (!m_code)
                 generateBytecode(scopeChain);
             return *m_code;
         }
 
+#if ENABLE(JIT)
+        JITCode& jitCode(ScopeChainNode* scopeChain)
+        {
+            if (!m_jitCode)
+                generateJITCode(scopeChain);
+            return m_jitCode;
+        }
+#endif
+
     private:
-        ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+        ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
+
+        void generateBytecode(ScopeChainNode*);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+#if ENABLE(JIT)
+        void generateJITCode(ScopeChainNode*);
+#endif
 
         OwnPtr<ProgramCodeBlock> m_code;
     };
 
     class EvalNode : public ScopeNode {
     public:
-        static EvalNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+        static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
 
-        EvalCodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
+        EvalCodeBlock& bytecode(ScopeChainNode* scopeChain) 
         {
             if (!m_code)
                 generateBytecode(scopeChain);
             return *m_code;
         }
 
-        EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*) JSC_FAST_CALL;
+        EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*);
 
         virtual void mark();
 
+#if ENABLE(JIT)
+        JITCode& jitCode(ScopeChainNode* scopeChain)
+        {
+            if (!m_jitCode)
+                generateJITCode(scopeChain);
+            return m_jitCode;
+        }
+#endif
+
     private:
-        EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+        EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
 
-        void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        void generateBytecode(ScopeChainNode*);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+#if ENABLE(JIT)
+        void generateJITCode(ScopeChainNode*);
+#endif
         
         OwnPtr<EvalCodeBlock> m_code;
     };
@@ -2176,217 +1540,152 @@ namespace JSC {
     class FunctionBodyNode : public ScopeNode {
         friend class JIT;
     public:
-        static FunctionBodyNode* create(JSGlobalData*) JSC_FAST_CALL;
-        static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
+#if ENABLE(JIT)
+        static PassRefPtr<FunctionBodyNode> createNativeThunk(JSGlobalData*);
+#endif
+        static FunctionBodyNode* create(JSGlobalData*);
+        static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
         virtual ~FunctionBodyNode();
 
-        const Identifier* parameters() const JSC_FAST_CALL { return m_parameters; }
+        const Identifier* parameters() const { return m_parameters; }
         size_t parameterCount() const { return m_parameterCount; }
-        UString paramString() const JSC_FAST_CALL;
+        UString paramString() const ;
         Identifier* copyParameters();
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-        
-        CodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
-        {
-            ASSERT(scopeChain);
-            if (!m_code)
-                generateBytecode(scopeChain);
-            return *m_code;
-        }
-
-        CodeBlock& generatedBytecode() JSC_FAST_CALL
-        {
-            ASSERT(m_code);
-            return *m_code;
-        }
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        bool isGenerated() JSC_FAST_CALL
+        bool isGenerated() const
         {
             return m_code;
         }
 
+        bool isHostFunction() const;
+
         virtual void mark();
 
         void finishParsing(const SourceCode&, ParameterNode*);
         void finishParsing(Identifier* parameters, size_t parameterCount);
         
-        UString toSourceString() const JSC_FAST_CALL { return source().toString(); }
+        UString toSourceString() const { return source().toString(); }
 
-        // These objects are ref/deref'd a lot in the scope chain, so this is a faster ref/deref.
-        // If the virtual machine changes so this doesn't happen as much we can change back.
-        void ref()
+        CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*);
+#if ENABLE(JIT)
+        JITCode& jitCode(ScopeChainNode* scopeChain)
         {
-            if (++m_refCount == 1)
-                ScopeNode::ref();
+            if (!m_jitCode)
+                generateJITCode(scopeChain);
+            return m_jitCode;
         }
-        void deref()
+#endif
+
+        CodeBlock& bytecode(ScopeChainNode* scopeChain) 
         {
-            ASSERT(m_refCount);
-            if (!--m_refCount)
-                ScopeNode::deref();
+            ASSERT(scopeChain);
+            if (!m_code)
+                generateBytecode(scopeChain);
+            return *m_code;
         }
-
-        CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*) JSC_FAST_CALL;
-
+        
+        CodeBlock& generatedBytecode()
+        {
+            ASSERT(m_code);
+            return *m_code;
+        }
+        
     private:
-        FunctionBodyNode(JSGlobalData*) JSC_FAST_CALL;
-        FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
-
-        void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
+        FunctionBodyNode(JSGlobalData*);
+        FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
 
+        void generateBytecode(ScopeChainNode*);
+#if ENABLE(JIT)
+        void generateJITCode(ScopeChainNode*);
+#endif
         Identifier* m_parameters;
         size_t m_parameterCount;
         OwnPtr<CodeBlock> m_code;
-        unsigned m_refCount;
     };
 
-    class FuncExprNode : public ExpressionNode {
+    class FuncExprNode : public ExpressionNode, public ParserArenaRefCounted {
     public:
-        FuncExprNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0) JSC_FAST_CALL
-            : ExpressionNode(globalData)
-            , m_ident(ident)
-            , m_parameter(parameter)
-            , m_body(body)
-        {
-            m_body->finishParsing(source, m_parameter.get());
-        }
+        FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0);
 
-        virtual ~FuncExprNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual bool isFuncExprNode() const JSC_FAST_CALL { return true; } 
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
-        JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
+        JSFunction* makeFunction(ExecState*, ScopeChainNode*);
 
         FunctionBodyNode* body() { return m_body.get(); }
 
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        virtual bool isFuncExprNode() const { return true; } 
+
         Identifier m_ident;
-        RefPtr<ParameterNode> m_parameter;
         RefPtr<FunctionBodyNode> m_body;
     };
 
-    class FuncDeclNode : public StatementNode {
+    class FuncDeclNode : public StatementNode, public ParserArenaRefCounted {
     public:
-        FuncDeclNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_ident(ident)
-            , m_parameter(parameter)
-            , m_body(body)
-        {
-            m_body->finishParsing(source, m_parameter.get());
-        }
-
-        virtual ~FuncDeclNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
 
-        JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
+        JSFunction* makeFunction(ExecState*, ScopeChainNode*);
 
         Identifier m_ident;
 
         FunctionBodyNode* body() { return m_body.get(); }
 
     private:
-        RefPtr<ParameterNode> m_parameter;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
         RefPtr<FunctionBodyNode> m_body;
     };
 
-    class CaseClauseNode : public ParserRefCounted {
+    class CaseClauseNode : public ParserArenaDeletable {
     public:
-        CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_expr(expr)
-        {
-        }
-
-        CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr, SourceElements* children) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_expr(expr)
-        {
-            if (children)
-                children->releaseContentsIntoVector(m_children);
-        }
-
-        virtual ~CaseClauseNode();
-        virtual void releaseNodes(NodeReleaser&);
+        CaseClauseNode(JSGlobalData*, ExpressionNode*);
+        CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements*);
 
-        ExpressionNode* expr() const { return m_expr.get(); }
+        ExpressionNode* expr() const { return m_expr; }
         StatementVector& children() { return m_children; }
 
     private:
-        RefPtr<ExpressionNode> m_expr;
+        ExpressionNode* m_expr;
         StatementVector m_children;
     };
 
-    class ClauseListNode : public ParserRefCounted {
+    class ClauseListNode : public ParserArenaDeletable {
     public:
-        ClauseListNode(JSGlobalData* globalData, CaseClauseNode* clause) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_clause(clause)
-        {
-        }
-
-        ClauseListNode(JSGlobalData* globalData, ClauseListNode* clauseList, CaseClauseNode* clause) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_clause(clause)
-        {
-            clauseList->m_next = this;
-        }
+        ClauseListNode(JSGlobalData*, CaseClauseNode*);
+        ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*);
 
-        virtual ~ClauseListNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        CaseClauseNode* getClause() const JSC_FAST_CALL { return m_clause.get(); }
-        ClauseListNode* getNext() const JSC_FAST_CALL { return m_next.get(); }
+        CaseClauseNode* getClause() const { return m_clause; }
+        ClauseListNode* getNext() const { return m_next; }
 
     private:
-        RefPtr<CaseClauseNode> m_clause;
-        RefPtr<ClauseListNode> m_next;
+        CaseClauseNode* m_clause;
+        ClauseListNode* m_next;
     };
 
-    class CaseBlockNode : public ParserRefCounted {
+    class CaseBlockNode : public ParserArenaDeletable {
     public:
-        CaseBlockNode(JSGlobalData* globalData, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) JSC_FAST_CALL
-            : ParserRefCounted(globalData)
-            , m_list1(list1)
-            , m_defaultClause(defaultClause)
-            , m_list2(list2)
-        {
-        }
+        CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
 
-        virtual ~CaseBlockNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* dst = 0) JSC_FAST_CALL;
+        RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* dst = 0);
 
     private:
         SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
-        RefPtr<ClauseListNode> m_list1;
-        RefPtr<CaseClauseNode> m_defaultClause;
-        RefPtr<ClauseListNode> m_list2;
+        ClauseListNode* m_list1;
+        CaseClauseNode* m_defaultClause;
+        ClauseListNode* m_list2;
     };
 
     class SwitchNode : public StatementNode {
     public:
-        SwitchNode(JSGlobalData* globalData, ExpressionNode* expr, CaseBlockNode* block) JSC_FAST_CALL
-            : StatementNode(globalData)
-            , m_expr(expr)
-            , m_block(block)
-        {
-        }
-
-        virtual ~SwitchNode();
-        virtual void releaseNodes(NodeReleaser&);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
+        SwitchNode(JSGlobalData*, ExpressionNode*, CaseBlockNode*);
 
     private:
-        RefPtr<ExpressionNode> m_expr;
-        RefPtr<CaseBlockNode> m_block;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
+        CaseBlockNode* m_block;
     };
 
     struct ElementList {
@@ -2421,4 +1720,4 @@ namespace JSC {
 
 } // namespace JSC
 
-#endif // NODES_H_
+#endif // Nodes_h
index 886a513d2598c74a7f32fb2a2f3eb678d75272f7..96f4ae6ae2ad5c82d7bb27a42e9e3a98ba6f2c4f 100644 (file)
@@ -39,7 +39,7 @@ namespace JSC {
 
 void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
 {
-    ASSERT(!m_sourceElements);
+    m_sourceElements = 0;
 
     int defaultErrLine;
     UString defaultErrMsg;
@@ -57,14 +57,13 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
 
     int parseError = jscyyparse(globalData);
     bool lexError = lexer.sawError();
+    int lineNumber = lexer.lineNumber();
     lexer.clear();
 
-    ParserRefCounted::deleteNewObjects(globalData);
-
     if (parseError || lexError) {
-        *errLine = lexer.lineNo();
+        *errLine = lineNumber;
         *errMsg = "Parse error";
-        m_sourceElements.clear();
+        m_sourceElements = 0;
     }
 }
 
@@ -77,23 +76,26 @@ void Parser::reparseInPlace(JSGlobalData* globalData, FunctionBodyNode* function
     parse(globalData, 0, 0);
     ASSERT(m_sourceElements);
 
-    functionBodyNode->adoptData(std::auto_ptr<ScopeNodeData>(new ScopeNodeData(m_sourceElements.get(),
-                                                                               m_varDeclarations ? &m_varDeclarations->data : 0, 
-                                                                               m_funcDeclarations ? &m_funcDeclarations->data : 0,
-                                                                               m_numConstants)));
+    functionBodyNode->adoptData(std::auto_ptr<ScopeNodeData>(new ScopeNodeData(globalData->parser->arena(),
+        m_sourceElements,
+        m_varDeclarations ? &m_varDeclarations->data : 0, 
+        m_funcDeclarations ? &m_funcDeclarations->data : 0,
+        m_numConstants)));
     bool usesArguments = functionBodyNode->usesArguments();
     functionBodyNode->setFeatures(m_features);
     if (usesArguments && !functionBodyNode->usesArguments())
         functionBodyNode->setUsesArguments();
 
+    ASSERT(globalData->parser->arena().isEmpty());
+
     m_source = 0;
     m_sourceElements = 0;
     m_varDeclarations = 0;
     m_funcDeclarations = 0;
 }
 
-void Parser::didFinishParsing(SourceElements* sourceElements, ParserRefCountedData<DeclarationStacks::VarStack>* varStack, 
-                              ParserRefCountedData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants)
+void Parser::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, 
+                              ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants)
 {
     m_sourceElements = sourceElements;
     m_varDeclarations = varStack;
index 6191ccb8b40ee0423dc4e6c59669d06f2f589c83..6f4c2b7d4ee5b7969b75337c93b73eeb8b9e464e 100644 (file)
@@ -23,9 +23,9 @@
 #ifndef Parser_h
 #define Parser_h
 
-#include "SourceProvider.h"
 #include "Debugger.h"
 #include "Nodes.h"
+#include "SourceProvider.h"
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
@@ -37,15 +37,7 @@ namespace JSC {
     class ProgramNode;
     class UString;
 
-    template <typename T>
-    struct ParserRefCountedData : ParserRefCounted {
-        ParserRefCountedData(JSGlobalData* globalData)
-            : ParserRefCounted(globalData)
-        {
-        }
-
-        T data;
-    };
+    template <typename T> struct ParserArenaData : ParserArenaDeletable { T data; };
 
     class Parser : Noncopyable {
     public:
@@ -53,16 +45,19 @@ namespace JSC {
         template <class ParsedNode> PassRefPtr<ParsedNode> reparse(JSGlobalData*, ParsedNode*);
         void reparseInPlace(JSGlobalData*, FunctionBodyNode*);
 
-        void didFinishParsing(SourceElements*, ParserRefCountedData<DeclarationStacks::VarStack>*, 
-                              ParserRefCountedData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants);
+        void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, 
+                              ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants);
+
+        ParserArena& arena() { return m_arena; }
 
     private:
         void parse(JSGlobalData*, int* errLine, UString* errMsg);
 
+        ParserArena m_arena;
         const SourceCode* m_source;
-        RefPtr<SourceElements> m_sourceElements;
-        RefPtr<ParserRefCountedData<DeclarationStacks::VarStack> > m_varDeclarations;
-        RefPtr<ParserRefCountedData<DeclarationStacks::FunctionStack> > m_funcDeclarations;
+        SourceElements* m_sourceElements;
+        ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
+        ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
         CodeFeatures m_features;
         int m_lastLine;
         int m_numConstants;
@@ -75,7 +70,7 @@ namespace JSC {
         RefPtr<ParsedNode> result;
         if (m_sourceElements) {
             result = ParsedNode::create(&exec->globalData(),
-                                         m_sourceElements.get(),
+                                         m_sourceElements,
                                          m_varDeclarations ? &m_varDeclarations->data : 0, 
                                          m_funcDeclarations ? &m_funcDeclarations->data : 0,
                                          *m_source,
@@ -84,8 +79,9 @@ namespace JSC {
             result->setLoc(m_source->firstLine(), m_lastLine);
         }
 
+        m_arena.reset();
+
         m_source = 0;
-        m_sourceElements = 0;
         m_varDeclarations = 0;
         m_funcDeclarations = 0;
 
@@ -101,7 +97,7 @@ namespace JSC {
         RefPtr<ParsedNode> result;
         if (m_sourceElements) {
             result = ParsedNode::create(globalData,
-                                        m_sourceElements.get(),
+                                        m_sourceElements,
                                         m_varDeclarations ? &m_varDeclarations->data : 0, 
                                         m_funcDeclarations ? &m_funcDeclarations->data : 0,
                                         *m_source,
@@ -110,8 +106,9 @@ namespace JSC {
             result->setLoc(m_source->firstLine(), m_lastLine);
         }
 
+        m_arena.reset();
+
         m_source = 0;
-        m_sourceElements = 0;
         m_varDeclarations = 0;
         m_funcDeclarations = 0;
 
diff --git a/parser/ParserArena.cpp b/parser/ParserArena.cpp
new file mode 100644 (file)
index 0000000..2617506
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "ParserArena.h"
+
+#include "Nodes.h"
+
+namespace JSC {
+
+ParserArena::~ParserArena()
+{
+    deleteAllValues(m_deletableObjects);
+}
+
+bool ParserArena::contains(ParserArenaRefCounted* object) const
+{
+    return m_refCountedObjects.find(object) != notFound;
+}
+
+ParserArenaRefCounted* ParserArena::last() const
+{
+    return m_refCountedObjects.last().get();
+}
+
+void ParserArena::removeLast()
+{
+    m_refCountedObjects.removeLast();
+}
+
+void ParserArena::reset()
+{
+    deleteAllValues(m_deletableObjects);
+    m_deletableObjects.shrink(0);
+    m_refCountedObjects.shrink(0);
+}
+
+}
diff --git a/parser/ParserArena.h b/parser/ParserArena.h
new file mode 100644 (file)
index 0000000..66c8529
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef ParserArena_h
+#define ParserArena_h
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+    class ParserArenaDeletable;
+    class ParserArenaRefCounted;
+
+    class ParserArena {
+    public:
+        void swap(ParserArena& otherArena)
+        {
+            m_deletableObjects.swap(otherArena.m_deletableObjects);
+            m_refCountedObjects.swap(otherArena.m_refCountedObjects);
+        }
+        ~ParserArena();
+
+        void deleteWithArena(ParserArenaDeletable* object) { m_deletableObjects.append(object); }
+        void derefWithArena(PassRefPtr<ParserArenaRefCounted> object) { m_refCountedObjects.append(object); }
+
+        bool contains(ParserArenaRefCounted*) const;
+        ParserArenaRefCounted* last() const;
+        void removeLast();
+
+        bool isEmpty() const { return m_deletableObjects.isEmpty() && m_refCountedObjects.isEmpty(); }
+        void reset();
+
+    private:
+        Vector<ParserArenaDeletable*> m_deletableObjects;
+        Vector<RefPtr<ParserArenaRefCounted> > m_refCountedObjects;
+    };
+
+}
+
+#endif
index 3e7fddbb42a699e46423dbe813c53c27da5d0f07..27b8112a0e7a7da3f2ed8163bb91289b472428ee 100644 (file)
@@ -63,6 +63,11 @@ namespace JSC {
             return (m_type & TypeBits) == TypeMaybeNumber;
         }
         
+        bool definitelyIsString()
+        {
+            return (m_type & TypeBits) == TypeMaybeString;
+        }
+
         bool mightBeNumber()
         {
             return m_type & TypeMaybeNumber;
@@ -117,7 +122,7 @@ namespace JSC {
         {
             if (op1.definitelyIsNumber() && op2.definitelyIsNumber())
                 return numberTypeCanReuse();
-            if (op1.isNotNumber() || op2.isNotNumber())
+            if (op1.definitelyIsString() || op2.definitelyIsString())
                 return stringType();
             return stringOrNumberTypeCanReuse();
         }
index 07da9e043f7fb1a04c5d81788428a913bba987c3..1c59eeda406b1223be80588a5db635085d7cd6f5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
+    enum SourceBOMPresence { SourceHasNoBOMs, SourceCouldHaveBOMs };
+
     class SourceProvider : public RefCounted<SourceProvider> {
     public:
-        SourceProvider(const UString& url)
+        SourceProvider(const UString& url, SourceBOMPresence hasBOMs = SourceCouldHaveBOMs)
             : m_url(url)
+            , m_hasBOMs(hasBOMs)
         {
         }
         virtual ~SourceProvider() { }
@@ -49,8 +52,11 @@ namespace JSC {
         const UString& url() { return m_url; }
         intptr_t asID() { return reinterpret_cast<intptr_t>(this); }
 
+        SourceBOMPresence hasBOMs() const { return m_hasBOMs; }
+
     private:
         UString m_url;
+        SourceBOMPresence m_hasBOMs;
     };
 
     class UStringSourceProvider : public SourceProvider {
index de2f5bbaf2b7808e06775643c59310d67f626a6a..8a2d1401b48a7bf930220b7e10a3c800b84ae37c 100755 (executable)
@@ -244,7 +244,7 @@ sub readHeaderValues()
  
     my ($fh, $tempFile) = tempfile(
         basename($0) . "-XXXXXXXX",
-        DIR => ($ENV{'TMPDIR'} || "/tmp"),
+        DIR => File::Spec->tmpdir,
         SUFFIX => ".in",
         UNLINK => 0,
     );
index 18c54ffe669168138d20cdb549fae254b4e25071..2bedca669c0621c4e23bfb910f5dec77e5eece6c 100644 (file)
@@ -2216,7 +2216,7 @@ static int calculateCompiledPatternLength(const UChar* pattern, int patternLengt
                         
                         int d = -1;
                         if (safelyCheckNextChar(ptr, patternEnd, '-')) {
-                            UChar const *hyptr = ptr++;
+                            const UChar* hyptr = ptr++;
                             if (safelyCheckNextChar(ptr, patternEnd, '\\')) {
                                 ptr++;
                                 d = checkEscape(&ptr, patternEnd, &errorcode, cd.numCapturingBrackets, true);
index 34e27865e33922228c36b5c06abb795160803148..af770f38a983c3ccb78f00b289c7ff957ae499e3 100644 (file)
@@ -50,13 +50,13 @@ the JavaScript specification. There are also some supporting functions. */
 #include <wtf/Vector.h>
 
 #if REGEXP_HISTOGRAM
-#include <parser/DateMath.h>
+#include <wtf/DateMath.h>
 #include <runtime/UString.h>
 #endif
 
 using namespace WTF;
 
-#ifdef __GNUC__
+#if COMPILER(GCC)
 #define USE_COMPUTED_GOTO_FOR_MATCH_RECURSION
 //#define USE_COMPUTED_GOTO_FOR_MATCH_OPCODE_LOOP
 #endif
@@ -175,7 +175,7 @@ reqByte match. */
 /* The below limit restricts the number of "recursive" match calls in order to
 avoid spending exponential time on complex regular expressions. */
 
-static const unsigned matchLimit = 100000;
+static const unsigned matchLimit = 1000000;
 
 #ifdef DEBUG
 /*************************************************
@@ -447,6 +447,7 @@ static int match(const UChar* subjectPtr, const unsigned char* instructionPtr, i
     int min;
     bool minimize = false; /* Initialization not really needed, but some compilers think so. */
     unsigned remainingMatchCount = matchLimit;
+    int othercase; /* Declare here to avoid errors during jumps */
     
     MatchStack stack;
 
@@ -1186,7 +1187,7 @@ RECURSE:
                 stack.currentFrame->args.instructionPtr += stack.currentFrame->locals.length;
                 
                 if (stack.currentFrame->locals.fc <= 0xFFFF) {
-                    int othercase = md.ignoreCase ? jsc_pcre_ucp_othercase(stack.currentFrame->locals.fc) : -1;
+                    othercase = md.ignoreCase ? jsc_pcre_ucp_othercase(stack.currentFrame->locals.fc) : -1;
                     
                     for (int i = 1; i <= min; i++) {
                         if (*stack.currentFrame->args.subjectPtr != stack.currentFrame->locals.fc && *stack.currentFrame->args.subjectPtr != othercase)
index 6ceef13641db355faa1c89c437edcd6d5748857e..ba48c558a5337f08592c42be853aa4b026b77a2a 100644 (file)
 #define CallIdentifier_h
 
 #include <runtime/UString.h>
+#include "FastAllocBase.h"
 
 namespace JSC {
 
-    struct CallIdentifier {
+    struct CallIdentifier : public FastAllocBase {
         UString m_name;
         UString m_url;
         unsigned m_lineNumber;
@@ -51,32 +52,34 @@ namespace JSC {
         inline bool operator==(const CallIdentifier& ci) const { return ci.m_lineNumber == m_lineNumber && ci.m_name == m_name && ci.m_url == m_url; }
         inline bool operator!=(const CallIdentifier& ci) const { return !(*this == ci); }
 
+        struct Hash {
+            static unsigned hash(const CallIdentifier& key)
+            {
+                unsigned hashCodes[3] = {
+                    key.m_name.rep()->hash(),
+                    key.m_url.rep()->hash(),
+                    key.m_lineNumber
+                };
+                return UString::Rep::computeHash(reinterpret_cast<char*>(hashCodes), sizeof(hashCodes));
+            }
+
+            static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; }
+            static const bool safeToCompareToEmptyOrDeleted = true;
+        };
+
+        unsigned hash() const { return Hash::hash(*this); }
+
 #ifndef NDEBUG
         operator const char*() const { return c_str(); }
         const char* c_str() const { return m_name.UTF8String().c_str(); }
 #endif
     };
 
-    struct CallIdentifierHash {
-        static unsigned hash(const CallIdentifier& key)
-        {
-            unsigned hashCodes[3] = {
-                key.m_name.rep()->hash(),
-                key.m_url.rep()->hash(),
-                key.m_lineNumber
-            };
-            return UString::Rep::computeHash(reinterpret_cast<char*>(hashCodes), sizeof(hashCodes));
-        }
-
-        static bool equal(const CallIdentifier& a, const CallIdentifier& b) { return a == b; }
-        static const bool safeToCompareToEmptyOrDeleted = true;
-    };
-
 } // namespace JSC
 
 namespace WTF {
 
-    template<> struct DefaultHash<JSC::CallIdentifier> { typedef JSC::CallIdentifierHash Hash; };
+    template<> struct DefaultHash<JSC::CallIdentifier> { typedef JSC::CallIdentifier::Hash Hash; };
 
     template<> struct HashTraits<JSC::CallIdentifier> : GenericHashTraits<JSC::CallIdentifier> {
         static void constructDeletedValue(JSC::CallIdentifier& slot)
index 5ea9d3b9ede17281655f7496d0a19da1f3f5ddfa..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "HeavyProfile.h"
-
-#include "TreeProfile.h"
-
-namespace JSC {
-
-HeavyProfile::HeavyProfile(TreeProfile* treeProfile)
-    : Profile(treeProfile->title(), treeProfile->uid())
-{
-    m_treeProfile = treeProfile;
-    head()->setTotalTime(m_treeProfile->head()->actualTotalTime());
-    head()->setSelfTime(m_treeProfile->head()->actualSelfTime());
-    generateHeavyStructure();
-}
-
-void HeavyProfile::generateHeavyStructure()
-{
-    ProfileNode* treeHead = m_treeProfile->head();
-    ProfileNode* currentNode = treeHead->firstChild();
-    for (ProfileNode* nextNode = currentNode; nextNode; nextNode = nextNode->firstChild())
-        currentNode = nextNode;
-
-    // For each node
-    HashMap<CallIdentifier, ProfileNode*> foundChildren;
-    while (currentNode && currentNode != treeHead) {
-        ProfileNode* child = foundChildren.get(currentNode->callIdentifier());
-        if (child) // currentNode is in the set already
-            mergeProfiles(child, currentNode);
-        else { // currentNode is not in the set
-            child = addNode(currentNode);
-            foundChildren.set(currentNode->callIdentifier(), child);
-        }
-
-        currentNode = currentNode->traverseNextNodePostOrder();
-    }
-}
-
-ProfileNode* HeavyProfile::addNode(ProfileNode* currentNode)
-{
-    RefPtr<ProfileNode> node = ProfileNode::create(head(), currentNode);
-    head()->addChild(node);
-
-    addAncestorsAsChildren(currentNode->parent(), node.get());
-    return node.get();
-}
-
-void HeavyProfile::mergeProfiles(ProfileNode* heavyProfileHead, ProfileNode* treeProfileHead)
-{
-    ASSERT_ARG(heavyProfileHead, heavyProfileHead);
-    ASSERT_ARG(treeProfileHead, treeProfileHead);
-
-    ProfileNode* currentTreeNode = treeProfileHead;
-    ProfileNode* currentHeavyNode = heavyProfileHead;
-    ProfileNode* previousHeavyNode = 0;
-    
-    while (currentHeavyNode) {
-        previousHeavyNode = currentHeavyNode;
-
-        currentHeavyNode->setTotalTime(currentHeavyNode->actualTotalTime() + currentTreeNode->actualTotalTime());
-        currentHeavyNode->setSelfTime(currentHeavyNode->actualSelfTime() + currentTreeNode->actualSelfTime());
-        currentHeavyNode->setNumberOfCalls(currentHeavyNode->numberOfCalls() + currentTreeNode->numberOfCalls());
-
-        currentTreeNode = currentTreeNode->parent();
-        currentHeavyNode = currentHeavyNode->findChild(currentTreeNode);
-    }
-
-    // If currentTreeNode is null then we already have the whole tree we wanted to copy.
-    // If not we need to copy the subset of the tree that remains different between the two.
-    if (currentTreeNode)
-        addAncestorsAsChildren(currentTreeNode, previousHeavyNode);
-}
-
-void HeavyProfile::addAncestorsAsChildren(ProfileNode* getFrom, ProfileNode* addTo)
-{
-    ASSERT_ARG(getFrom, getFrom);
-    ASSERT_ARG(addTo, addTo);
-
-    if (!getFrom->head())
-        return;
-
-    RefPtr<ProfileNode> currentNode = addTo;
-    for (ProfileNode* treeAncestor = getFrom; treeAncestor && treeAncestor != getFrom->head(); treeAncestor = treeAncestor->parent()) {
-        RefPtr<ProfileNode> newChild = ProfileNode::create(currentNode->head(), treeAncestor);
-        currentNode->addChild(newChild);
-        currentNode = newChild.release();
-    }
-}
-
-}   // namespace JSC
index 903d091cc2bd293a47d54f2f6ef6f7363bbe43d4..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef HeavyProfile_h
-#define HeavyProfile_h
-
-#include "Profile.h"
-#include "ProfileNode.h"
-#include "TreeProfile.h"
-
-namespace JSC {
-
-    class UString;
-
-    class HeavyProfile : public Profile {
-    public:
-        static PassRefPtr<HeavyProfile> create(TreeProfile* treeProfile)
-        {
-            return adoptRef(new HeavyProfile(treeProfile));
-        }
-
-        virtual Profile* heavyProfile() { return this; }
-        virtual Profile* treeProfile()
-        {
-            return m_treeProfile;
-        }
-
-
-    private:
-        HeavyProfile(TreeProfile*);
-        void generateHeavyStructure();
-        ProfileNode* addNode(ProfileNode*);
-        void mergeProfiles(ProfileNode* heavyProfileHead, ProfileNode* treeProfileHead);
-        void addAncestorsAsChildren(ProfileNode* getFrom, ProfileNode* addTo);
-
-        TreeProfile* m_treeProfile;
-    };
-
-} // namespace JSC
-
-#endif // HeavyProfile_h
index 72e6d21a0b0271e381755a537f24b6f569eeef11..de75e71c614e48507af6ce8a0c065e6c55badfc8 100644 (file)
 #include "Profile.h"
 
 #include "ProfileNode.h"
-#include "TreeProfile.h"
 #include <stdio.h>
 
 namespace JSC {
 
 PassRefPtr<Profile> Profile::create(const UString& title, unsigned uid)
 {
-    return TreeProfile::create(title, uid);
+    return adoptRef(new Profile(title, uid));
 }
 
 Profile::Profile(const UString& title, unsigned uid)
index dd96f77fc5c18769377fa700f81cf0850aa34a00..6bf29f7a6f88b9ae4eee3ed67976020f1eb27f0f 100644 (file)
@@ -45,22 +45,11 @@ namespace JSC {
         unsigned int uid() const { return m_uid; }
 
         void forEach(void (ProfileNode::*)());
-        void sortTotalTimeDescending() { forEach(&ProfileNode::sortTotalTimeDescending); }
-        void sortTotalTimeAscending() { forEach(&ProfileNode::sortTotalTimeAscending); }
-        void sortSelfTimeDescending() { forEach(&ProfileNode::sortSelfTimeDescending); }
-        void sortSelfTimeAscending() { forEach(&ProfileNode::sortSelfTimeAscending); }
-        void sortCallsDescending() { forEach(&ProfileNode::sortCallsDescending); }
-        void sortCallsAscending() { forEach(&ProfileNode::sortCallsAscending); }
-        void sortFunctionNameDescending() { forEach(&ProfileNode::sortFunctionNameDescending); }
-        void sortFunctionNameAscending() { forEach(&ProfileNode::sortFunctionNameAscending); }
 
         void focus(const ProfileNode*);
         void exclude(const ProfileNode*);
         void restoreAll();
 
-        virtual Profile* heavyProfile() = 0;
-        virtual Profile* treeProfile() = 0; 
-
 #ifndef NDEBUG
         void debugPrintData() const;
         void debugPrintDataSampleStyle() const;
index b1d5d48428ac4ab7c64c25982515d7399af46012..1a061cb9cb699ea4fb677456c22c15bb00d5eae5 100644 (file)
@@ -59,7 +59,7 @@ void ProfileGenerator::addParentForConsoleStart(ExecState* exec)
     int lineNumber;
     intptr_t sourceID;
     UString sourceURL;
-    JSValuePtr function;
+    JSValue function;
 
     exec->interpreter()->retrieveLastCaller(exec, lineNumber, sourceID, sourceURL, function);
     m_currentNode = ProfileNode::create(Profiler::createCallIdentifier(&exec->globalData(), function ? function.toThisObject(exec) : 0, sourceURL, lineNumber), m_head.get(), m_head.get());
index 54d45658ef3e425b7929141d3a754fd024adaf3e..cccb502d43d2ae28ce2e366a2c1af86b4dae3cd4 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef ProfileGenerator_h
 #define ProfileGenerator_h
 
+#include "Profile.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
index 3458902d170953aaec822df4c0842b12daedb0d1..19050aa0c60a6f39e5073c1caa43d43d3af15df0 100644 (file)
@@ -29,9 +29,9 @@
 #include "config.h"
 #include "ProfileNode.h"
 
-#include "DateMath.h"
 #include "Profiler.h"
 #include <stdio.h>
+#include <wtf/DateMath.h>
 
 #if PLATFORM(WIN_OS)
 #include <windows.h>
@@ -49,7 +49,7 @@ static double getCount()
     QueryPerformanceCounter(&counter);
     return static_cast<double>(counter.QuadPart) / frequency.QuadPart;
 #else
-    return getCurrentUTCTimeWithMicroseconds();
+    return WTF::getCurrentUTCTimeWithMicroseconds();
 #endif
 }
 
@@ -204,12 +204,6 @@ ProfileNode* ProfileNode::traverseNextNodePreOrder(bool processChildren) const
     return next;
 }
 
-void ProfileNode::sort(bool comparator(const RefPtr<ProfileNode>& , const RefPtr<ProfileNode>& ))
-{
-    std::sort(childrenBegin(), childrenEnd(), comparator);    
-    resetChildrensSiblings();
-}
-
 void ProfileNode::setTreeVisible(ProfileNode* node, bool visible)
 {
     ProfileNode* nodeParent = node->parent();
index b41601128eccd8d51ed05c92ad4782b9c8130d9c..2b5a93602f4318623e0f12efd7aeb7363e87b8b6 100644 (file)
@@ -112,16 +112,6 @@ namespace JSC {
         ProfileNode* traverseNextNodePostOrder() const;
         ProfileNode* traverseNextNodePreOrder(bool processChildren = true) const;
 
-        void sort(bool (*)(const RefPtr<ProfileNode>&, const RefPtr<ProfileNode>&));
-        void sortTotalTimeDescending() { sort(totalTimeDescendingComparator); }
-        void sortTotalTimeAscending() { sort(totalTimeAscendingComparator); }
-        void sortSelfTimeDescending() { sort(selfTimeDescendingComparator); }
-        void sortSelfTimeAscending() { sort(selfTimeAscendingComparator); }
-        void sortCallsDescending() { sort(callsDescendingComparator); }
-        void sortCallsAscending() { sort(callsAscendingComparator); }
-        void sortFunctionNameDescending() { sort(functionNameDescendingComparator); }
-        void sortFunctionNameAscending() { sort(functionNameAscendingComparator); }
-
         // Views
         void calculateVisibleTotalTime();
         bool focus(const CallIdentifier&);
index 2de8f84e5af0032f57358bfc4cf9c6b5b971d8a9..e103fd19fb9f0ea1edae8b5def6097a7c415a372 100644 (file)
@@ -33,6 +33,7 @@
 #include "CallFrame.h"
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
+#include "Nodes.h"
 #include "Profile.h"
 #include "ProfileGenerator.h"
 #include "ProfileNode.h"
@@ -58,6 +59,8 @@ Profiler* Profiler::profiler()
 
 void Profiler::startProfiling(ExecState* exec, const UString& title)
 {
+    ASSERT_ARG(title, !title.isNull());
+
     // Check if we currently have a Profile for this global ExecState and title.
     // If so return early and don't create a new Profile.
     ExecState* globalExec = exec ? exec->lexicalGlobalObject()->globalExec() : 0;
@@ -101,7 +104,7 @@ static inline void dispatchFunctionToProfiles(const Vector<RefPtr<ProfileGenerat
     }
 }
 
-void Profiler::willExecute(ExecState* exec, JSValuePtr function)
+void Profiler::willExecute(ExecState* exec, JSValue function)
 {
     ASSERT(!m_currentProfiles.isEmpty());
 
@@ -112,12 +115,12 @@ void Profiler::willExecute(ExecState* exec, const UString& sourceURL, int starti
 {
     ASSERT(!m_currentProfiles.isEmpty());
 
-    CallIdentifier callIdentifier = createCallIdentifier(&exec->globalData(), noValue(), sourceURL, startingLineNumber);
+    CallIdentifier callIdentifier = createCallIdentifier(&exec->globalData(), JSValue(), sourceURL, startingLineNumber);
 
     dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::willExecute, callIdentifier, exec->lexicalGlobalObject()->profileGroup());
 }
 
-void Profiler::didExecute(ExecState* exec, JSValuePtr function)
+void Profiler::didExecute(ExecState* exec, JSValue function)
 {
     ASSERT(!m_currentProfiles.isEmpty());
 
@@ -128,17 +131,20 @@ void Profiler::didExecute(ExecState* exec, const UString& sourceURL, int startin
 {
     ASSERT(!m_currentProfiles.isEmpty());
 
-    dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(&exec->globalData(), noValue(), sourceURL, startingLineNumber), exec->lexicalGlobalObject()->profileGroup());
+    dispatchFunctionToProfiles(m_currentProfiles, &ProfileGenerator::didExecute, createCallIdentifier(&exec->globalData(), JSValue(), sourceURL, startingLineNumber), exec->lexicalGlobalObject()->profileGroup());
 }
 
-CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValuePtr function, const UString& defaultSourceURL, int defaultLineNumber)
+CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValue function, const UString& defaultSourceURL, int defaultLineNumber)
 {
     if (!function)
         return CallIdentifier(GlobalCodeExecution, defaultSourceURL, defaultLineNumber);
     if (!function.isObject())
         return CallIdentifier("(unknown)", defaultSourceURL, defaultLineNumber);
-    if (asObject(function)->inherits(&JSFunction::info))
-        return createCallIdentifierFromFunctionImp(globalData, asFunction(function));
+    if (asObject(function)->inherits(&JSFunction::info)) {
+        JSFunction* func = asFunction(function);
+        if (!func->isHostFunction())
+            return createCallIdentifierFromFunctionImp(globalData, func);
+    }
     if (asObject(function)->inherits(&InternalFunction::info))
         return CallIdentifier(static_cast<InternalFunction*>(asObject(function))->name(globalData), defaultSourceURL, defaultLineNumber);
     return CallIdentifier("(" + asObject(function)->className() + " object)", defaultSourceURL, defaultLineNumber);
@@ -146,7 +152,7 @@ CallIdentifier Profiler::createCallIdentifier(JSGlobalData* globalData, JSValueP
 
 CallIdentifier createCallIdentifierFromFunctionImp(JSGlobalData* globalData, JSFunction* function)
 {
-    const UString& name = function->name(globalData);
+    const UString& name = function->calculatedDisplayName(globalData);
     return CallIdentifier(name.isEmpty() ? AnonymousFunction : name, function->body()->sourceURL(), function->body()->lineNo());
 }
 
index d00bccf8811ffd1f8848e417504a0e1b782b3091..b37f6135619bd3c3baf947b1c2279fc17a90b862 100644 (file)
@@ -40,7 +40,7 @@ namespace JSC {
     class ExecState;
     class JSGlobalData;
     class JSObject;
-    class JSValuePtr;
+    class JSValue;
     class ProfileGenerator;
     class UString;
 
@@ -52,14 +52,14 @@ namespace JSC {
         }
 
         static Profiler* profiler(); 
-        static CallIdentifier createCallIdentifier(JSGlobalData*, JSValuePtr, const UString& sourceURL, int lineNumber);
+        static CallIdentifier createCallIdentifier(JSGlobalData*, JSValue, const UString& sourceURL, int lineNumber);
 
         void startProfiling(ExecState*, const UString& title);
         PassRefPtr<Profile> stopProfiling(ExecState*, const UString& title);
 
-        void willExecute(ExecState*, JSValuePtr function);
+        void willExecute(ExecState*, JSValue function);
         void willExecute(ExecState*, const UString& sourceURL, int startingLineNumber);
-        void didExecute(ExecState*, JSValuePtr function);
+        void didExecute(ExecState*, JSValue function);
         void didExecute(ExecState*, const UString& sourceURL, int startingLineNumber);
 
         const Vector<RefPtr<ProfileGenerator> >& currentProfiles() { return m_currentProfiles; };
index 19cb6f0cecf36cefa00939a046f4f9894e8f1dd3..251c2e3eb1b8b96041e48b0ff532c113f00a1e54 100644 (file)
 
 #import "JSProfilerPrivate.h"
 #import "JSRetainPtr.h"
-
 #import <Foundation/Foundation.h>
 #if PLATFORM(IPHONE_SIMULATOR)
 #import <Foundation/NSDistributedNotificationCenter.h>
 #endif
 
+
 @interface ProfilerServer : NSObject {
 @private
     NSString *_serverName;
index 0c7fedb7d9814a2aae4b15cdf51f229aac76fbd4..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "TreeProfile.h"
-
-#include "HeavyProfile.h"
-
-namespace JSC {
-
-PassRefPtr<TreeProfile> TreeProfile::create(const UString& title, unsigned uid)
-{
-    return adoptRef(new TreeProfile(title, uid));
-}
-
-TreeProfile::TreeProfile(const UString& title, unsigned uid)
-    : Profile(title, uid)
-{
-}
-
-Profile* TreeProfile::heavyProfile()
-{
-    if (!m_heavyProfile)
-        m_heavyProfile = HeavyProfile::create(this);
-
-    return m_heavyProfile.get();
-}
-
-} // namespace JSC
index ebef4d8b2a4f4e942d94981c7c54b20496e24b4f..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#ifndef TreeProfile_h
-#define TreeProfile_h
-
-#include "Profile.h"
-
-namespace JSC {
-
-    class ExecState;
-    class HeavyProfile;
-    class UString;
-
-    class TreeProfile : public Profile {
-    public:
-        static PassRefPtr<TreeProfile> create(const UString& title, unsigned uid);
-
-        virtual Profile* heavyProfile();
-        virtual Profile* treeProfile() { return this; }
-
-    private:
-        TreeProfile(const UString& title, unsigned uid);
-        RefPtr<HeavyProfile> m_heavyProfile;
-    };
-
-} // namespace JSC
-
-#endif // TreeProfiler_h
index 5ead73360fe9c782d5f7b43a4c43e2bd8d16f048..0b5d958b6aaa35f61ec0517f50e20d57ea93cd53 100644 (file)
@@ -30,19 +30,18 @@ namespace JSC {
 
 void ArgList::getSlice(int startIndex, ArgList& result) const
 {
-    ASSERT(!result.m_isReadOnly);
-
-    const_iterator start = min(begin() + startIndex, end());
-    result.m_vector.appendRange(start, end());
-    result.m_size = result.m_vector.size();
-    result.m_buffer = result.m_vector.data();
+    if (startIndex <= 0 || static_cast<unsigned>(startIndex) >= m_argCount) {
+        result = ArgList(m_args, 0);
+        return;
+    }
+    result = ArgList(m_args + startIndex, m_argCount - startIndex);
 }
 
-void ArgList::markLists(ListSet& markSet)
+void MarkedArgumentBuffer::markLists(ListSet& markSet)
 {
     ListSet::iterator end = markSet.end();
     for (ListSet::iterator it = markSet.begin(); it != end; ++it) {
-        ArgList* list = *it;
+        MarkedArgumentBuffer* list = *it;
 
         iterator end2 = list->end();
         for (iterator it2 = list->begin(); it2 != end2; ++it2)
@@ -51,7 +50,7 @@ void ArgList::markLists(ListSet& markSet)
     }
 }
 
-void ArgList::slowAppend(JSValuePtr v)
+void MarkedArgumentBuffer::slowAppend(JSValue v)
 {
     // As long as our size stays within our Vector's inline 
     // capacity, all our values are allocated on the stack, and 
index a1763e0a6e63da66ecdcf4c639330742b5f76133..3c8256188e7fe6375a19463a03534549500f2684 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2007, 2008 Apple Computer, Inc.
+ *  Copyright (C) 2003, 2007, 2008, 2009 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,6 @@
 #ifndef ArgList_h
 #define ArgList_h
 
-#include "JSImmediate.h"
 #include "Register.h"
 
 #include <wtf/HashSet.h>
 
 namespace JSC {
     
-    class ArgList : Noncopyable {
+    class MarkedArgumentBuffer : Noncopyable {
     private:
         static const unsigned inlineCapacity = 8;
         typedef Vector<Register, inlineCapacity> VectorType;
-        typedef HashSet<ArgList*> ListSet;
+        typedef HashSet<MarkedArgumentBuffer*> ListSet;
 
     public:
         typedef VectorType::iterator iterator;
@@ -43,8 +42,9 @@ namespace JSC {
 
         // Constructor for a read-write list, to which you may append values.
         // FIXME: Remove all clients of this API, then remove this API.
-        ArgList()
-            : m_markSet(0)
+        MarkedArgumentBuffer()
+            : m_isUsingInlineBuffer(true)
+            , m_markSet(0)
 #ifndef NDEBUG
             , m_isReadOnly(false)
 #endif
@@ -54,9 +54,10 @@ namespace JSC {
         }
 
         // Constructor for a read-only list whose data has already been allocated elsewhere.
-        ArgList(Register* buffer, size_t size)
+        MarkedArgumentBuffer(Register* buffer, size_t size)
             : m_buffer(buffer)
             , m_size(size)
+            , m_isUsingInlineBuffer(true)
             , m_markSet(0)
 #ifndef NDEBUG
             , m_isReadOnly(true)
@@ -76,7 +77,7 @@ namespace JSC {
 #endif
         }
 
-        ~ArgList()
+        ~MarkedArgumentBuffer()
         {
             if (m_markSet)
                 m_markSet->remove(this);
@@ -85,10 +86,10 @@ namespace JSC {
         size_t size() const { return m_size; }
         bool isEmpty() const { return !m_size; }
 
-        JSValuePtr at(ExecState* exec, size_t i) const
+        JSValue at(size_t i) const
         {
             if (i < m_size)
-                return m_buffer[i].jsValue(exec);
+                return m_buffer[i].jsValue();
             return jsUndefined();
         }
 
@@ -99,11 +100,11 @@ namespace JSC {
             m_size = 0;
         }
 
-        void append(JSValuePtr v)
+        void append(JSValue v)
         {
             ASSERT(!m_isReadOnly);
             
-            if (m_size < inlineCapacity) {
+            if (m_isUsingInlineBuffer && m_size < inlineCapacity) {
                 m_vector.uncheckedAppend(v);
                 ++m_size;
             } else {
@@ -111,11 +112,23 @@ namespace JSC {
                 // the performance of the fast "just append to inline buffer" case.
                 slowAppend(v);
                 ++m_size;
+                m_isUsingInlineBuffer = false;
             }
         }
 
-        void getSlice(int startIndex, ArgList& result) const;
+        void removeLast()
+        { 
+            ASSERT(m_size);
+            m_size--;
+            m_vector.removeLast();
+        }
 
+        JSValue last() 
+        {
+            ASSERT(m_size);
+            return m_buffer[m_size - 1].jsValue();
+        }
+        
         iterator begin() { return m_buffer; }
         iterator end() { return m_buffer + m_size; }
 
@@ -125,10 +138,11 @@ namespace JSC {
         static void markLists(ListSet&);
 
     private:
-        void slowAppend(JSValuePtr);
+        void slowAppend(JSValue);
         
         Register* m_buffer;
         size_t m_size;
+        bool m_isUsingInlineBuffer;
 
         VectorType m_vector;
         ListSet* m_markSet;
@@ -156,6 +170,60 @@ namespace JSC {
         void operator delete(void*, size_t);
     };
 
+    class ArgList {
+        friend class JIT;
+    public:
+        typedef JSValue* iterator;
+        typedef const JSValue* const_iterator;
+
+        ArgList()
+            : m_args(0)
+            , m_argCount(0)
+        {
+        }
+        
+        ArgList(JSValue* args, unsigned argCount)
+            : m_args(args)
+            , m_argCount(argCount)
+        {
+        }
+        
+        ArgList(Register* args, int argCount)
+            : m_args(reinterpret_cast<JSValue*>(args))
+            , m_argCount(argCount)
+        {
+            ASSERT(argCount >= 0);
+        }
+
+        ArgList(const MarkedArgumentBuffer& args)
+            : m_args(reinterpret_cast<JSValue*>(const_cast<Register*>(args.begin())))
+            , m_argCount(args.size())
+        {
+        }
+
+        JSValue at(size_t idx) const
+        {
+            if (idx < m_argCount)
+                return m_args[idx];
+            return jsUndefined();
+        }
+
+        bool isEmpty() const { return !m_argCount; }
+
+        size_t size() const { return m_argCount; }
+        
+        iterator begin() { return m_args; }
+        iterator end() { return m_args + m_argCount; }
+        
+        const_iterator begin() const { return m_args; }
+        const_iterator end() const { return m_args + m_argCount; }
+
+        void getSlice(int startIndex, ArgList& result) const;
+    private:
+        JSValue* m_args;
+        size_t m_argCount;
+    };
+
 } // namespace JSC
 
 #endif // ArgList_h
index b0429a9f799d6ae27c98a3d576e80c42b3897774..f867fe81f15fb5edcee66c404efbbe9d5896f724 100644 (file)
@@ -69,8 +69,50 @@ void Arguments::mark()
         d->activation->mark();
 }
 
-void Arguments::fillArgList(ExecState* exec, ArgList& args)
+void Arguments::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize)
 {
+    if (UNLIKELY(d->overrodeLength)) {
+        unsigned length = min(get(exec, exec->propertyNames().length).toUInt32(exec), maxSize);
+        for (unsigned i = 0; i < length; i++)
+            buffer[i] = get(exec, i);
+        return;
+    }
+
+    if (LIKELY(!d->deletedArguments)) {
+        unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
+        unsigned i = 0;
+        for (; i < parametersLength; ++i)
+            buffer[i] = d->registers[d->firstParameterIndex + i].jsValue();
+        for (; i < d->numArguments; ++i)
+            buffer[i] = d->extraArguments[i - d->numParameters].jsValue();
+        return;
+    }
+    
+    unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
+    unsigned i = 0;
+    for (; i < parametersLength; ++i) {
+        if (!d->deletedArguments[i])
+            buffer[i] = d->registers[d->firstParameterIndex + i].jsValue();
+        else
+            buffer[i] = get(exec, i);
+    }
+    for (; i < d->numArguments; ++i) {
+        if (!d->deletedArguments[i])
+            buffer[i] = d->extraArguments[i - d->numParameters].jsValue();
+        else
+            buffer[i] = get(exec, i);
+    }
+}
+
+void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
+{
+    if (UNLIKELY(d->overrodeLength)) {
+        unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec); 
+        for (unsigned i = 0; i < length; i++) 
+            args.append(get(exec, i)); 
+        return;
+    }
+
     if (LIKELY(!d->deletedArguments)) {
         if (LIKELY(!d->numParameters)) {
             args.initialize(d->extraArguments, d->numArguments);
@@ -85,9 +127,9 @@ void Arguments::fillArgList(ExecState* exec, ArgList& args)
         unsigned parametersLength = min(d->numParameters, d->numArguments);
         unsigned i = 0;
         for (; i < parametersLength; ++i)
-            args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
+            args.append(d->registers[d->firstParameterIndex + i].jsValue());
         for (; i < d->numArguments; ++i)
-            args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
+            args.append(d->extraArguments[i - d->numParameters].jsValue());
         return;
     }
 
@@ -95,13 +137,13 @@ void Arguments::fillArgList(ExecState* exec, ArgList& args)
     unsigned i = 0;
     for (; i < parametersLength; ++i) {
         if (!d->deletedArguments[i])
-            args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
+            args.append(d->registers[d->firstParameterIndex + i].jsValue());
         else
             args.append(get(exec, i));
     }
     for (; i < d->numArguments; ++i) {
         if (!d->deletedArguments[i])
-            args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
+            args.append(d->extraArguments[i - d->numParameters].jsValue());
         else
             args.append(get(exec, i));
     }
@@ -113,7 +155,7 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& sl
         if (i < d->numParameters) {
             slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
         } else
-            slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
+            slot.setValue(d->extraArguments[i - d->numParameters].jsValue());
         return true;
     }
 
@@ -128,7 +170,7 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
         if (i < d->numParameters) {
             slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
         } else
-            slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
+            slot.setValue(d->extraArguments[i - d->numParameters].jsValue());
         return true;
     }
 
@@ -145,28 +187,28 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
     return JSObject::getOwnPropertySlot(exec, propertyName, slot);
 }
 
-void Arguments::put(ExecState* exec, unsigned i, JSValuePtr value, PutPropertySlot& slot)
+void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& slot)
 {
     if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
         if (i < d->numParameters)
-            d->registers[d->firstParameterIndex + i] = JSValuePtr(value);
+            d->registers[d->firstParameterIndex + i] = JSValue(value);
         else
-            d->extraArguments[i - d->numParameters] = JSValuePtr(value);
+            d->extraArguments[i - d->numParameters] = JSValue(value);
         return;
     }
 
     JSObject::put(exec, Identifier(exec, UString::from(i)), value, slot);
 }
 
-void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     bool isArrayIndex;
     unsigned i = propertyName.toArrayIndex(&isArrayIndex);
     if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
         if (i < d->numParameters)
-            d->registers[d->firstParameterIndex + i] = JSValuePtr(value);
+            d->registers[d->firstParameterIndex + i] = JSValue(value);
         else
-            d->extraArguments[i - d->numParameters] = JSValuePtr(value);
+            d->extraArguments[i - d->numParameters] = JSValue(value);
         return;
     }
 
index ebea6ad1556364cf5b46cb48261eaf5480b7a01a..74bb6ad8eede9223dabc0f10c0fe202d31c61d7b 100644 (file)
@@ -63,8 +63,16 @@ namespace JSC {
 
         virtual void mark();
 
-        void fillArgList(ExecState*, ArgList&);
+        void fillArgList(ExecState*, MarkedArgumentBuffer&);
 
+        uint32_t numProvidedArguments(ExecState* exec) const 
+        {
+            if (UNLIKELY(d->overrodeLength))
+                return get(exec, exec->propertyNames().length).toUInt32(exec);
+            return d->numArguments; 
+        }
+        
+        void copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize);
         void copyRegisters();
         bool isTornOff() const { return d->registerArray; }
         void setActivation(JSActivation* activation)
@@ -73,7 +81,7 @@ namespace JSC {
             d->registers = &activation->registerAt(0);
         }
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype) 
+        static PassRefPtr<Structure> createStructure(JSValue prototype) 
         { 
             return Structure::create(prototype, TypeInfo(ObjectType)); 
         }
@@ -82,8 +90,8 @@ namespace JSC {
         void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
-        virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
-        virtual void put(ExecState*, unsigned propertyName, JSValuePtr, PutPropertySlot&);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+        virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
 
@@ -94,9 +102,9 @@ namespace JSC {
         OwnPtr<ArgumentsData> d;
     };
 
-    Arguments* asArguments(JSValuePtr);
+    Arguments* asArguments(JSValue);
 
-    inline Arguments* asArguments(JSValuePtr value)
+    inline Arguments* asArguments(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&Arguments::info));
         return static_cast<Arguments*>(asObject(value));
@@ -106,17 +114,16 @@ namespace JSC {
     {
         function = callFrame->callee();
     
-        CodeBlock* codeBlock = &function->body()->generatedBytecode();
-        int numParameters = codeBlock->m_numParameters;
+        int numParameters = function->body()->parameterCount();
         argc = callFrame->argumentCount();
 
         if (argc <= numParameters)
-            argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this"
+            argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters;
         else
-            argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters - argc + 1; // + 1 to skip "this"
+            argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters - argc;
 
         argc -= 1; // - 1 to skip "this"
-        firstParameterIndex = -RegisterFile::CallFrameHeaderSize - numParameters + 1; // + 1 to skip "this"
+        firstParameterIndex = -RegisterFile::CallFrameHeaderSize - numParameters;
     }
 
     inline Arguments::Arguments(CallFrame* callFrame)
@@ -222,6 +229,14 @@ namespace JSC {
             static_cast<Arguments*>(arguments)->setActivation(this);
     }
 
+    ALWAYS_INLINE Arguments* Register::arguments() const
+    {
+        if (jsValue() == JSValue())
+            return 0;
+        return asArguments(jsValue());
+    }
+    
+
 } // namespace JSC
 
 #endif // Arguments_h
index dd3ff4bc605a5d491fc65a1513686f2fc6396559..e96bdfc7bd2d9411d1e820ef2eb942f10a7d02ed 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "ArrayPrototype.h"
 #include "JSArray.h"
+#include "JSFunction.h"
 #include "Lookup.h"
 
 namespace JSC {
@@ -45,15 +46,15 @@ ArrayConstructor::ArrayConstructor(ExecState* exec, PassRefPtr<Structure> struct
 static JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgList& args)
 {
     // a single numeric argument denotes the array size (!)
-    if (args.size() == 1 && args.at(exec, 0).isNumber()) {
-        uint32_t n = args.at(exec, 0).toUInt32(exec);
-        if (n != args.at(exec, 0).toNumber(exec))
+    if (args.size() == 1 && args.at(0).isNumber()) {
+        uint32_t n = args.at(0).toUInt32(exec);
+        if (n != args.at(0).toNumber(exec))
             return throwError(exec, RangeError, "Array size is not a small enough positive integer.");
         return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), n);
     }
 
     // otherwise the array is constructed with the arguments in it
-    return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), args);
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), args);
 }
 
 static JSObject* constructWithArrayConstructor(ExecState* exec, JSObject*, const ArgList& args)
@@ -68,7 +69,7 @@ ConstructType ArrayConstructor::getConstructData(ConstructData& constructData)
     return ConstructTypeHost;
 }
 
-static JSValuePtr callArrayConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callArrayConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     return constructArrayWithSizeQuirk(exec, args);
 }
index 4cd229aab9048d21c833cc807f11bee6c3c3f70e..807e59a67173732621ed21d7703f153ee4e16ecd 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *  Copyright (C) 2003 Peter Kelly (pmk@post.com)
  *  Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
  *
@@ -25,7 +25,9 @@
 #include "ArrayPrototype.h"
 
 #include "CodeBlock.h"
+#include "CachedCall.h"
 #include "Interpreter.h"
+#include "JIT.h"
 #include "ObjectPrototype.h"
 #include "Lookup.h"
 #include "Operations.h"
@@ -37,25 +39,27 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(ArrayPrototype);
 
-static JSValuePtr arrayProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncConcat(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncJoin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncPop(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncPush(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncReverse(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncShift(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncSlice(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncSort(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncSplice(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncUnShift(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncEvery(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncForEach(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncSome(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncFilter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncMap(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue, const ArgList&);
 
 }
 
@@ -67,8 +71,17 @@ static inline bool isNumericCompareFunction(CallType callType, const CallData& c
 {
     if (callType != CallTypeJS)
         return false;
-    
-    return callData.js.functionBody->bytecode(callData.js.scopeChain).isNumericCompareFunction();
+
+#if ENABLE(JIT)
+    // If the JIT is enabled then we need to preserve the invariant that every
+    // function with a CodeBlock also has JIT code.
+    callData.js.functionBody->jitCode(callData.js.scopeChain);
+    CodeBlock& codeBlock = callData.js.functionBody->generatedBytecode();
+#else
+    CodeBlock& codeBlock = callData.js.functionBody->bytecode(callData.js.scopeChain);
+#endif
+
+    return codeBlock.isNumericCompareFunction();
 }
 
 // ------------------------------ ArrayPrototype ----------------------------
@@ -95,6 +108,8 @@ const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::a
   indexOf        arrayProtoFuncIndexOf        DontEnum|Function 1
   lastIndexOf    arrayProtoFuncLastIndexOf    DontEnum|Function 1
   filter         arrayProtoFuncFilter         DontEnum|Function 1
+  reduce         arrayProtoFuncReduce         DontEnum|Function 1
+  reduceRight    arrayProtoFuncReduceRight    DontEnum|Function 1
   map            arrayProtoFuncMap            DontEnum|Function 1
 @end
 */
@@ -113,29 +128,31 @@ bool ArrayPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& prope
 // ------------------------------ Array Functions ----------------------------
 
 // Helper function
-static JSValuePtr getProperty(ExecState* exec, JSObject* obj, unsigned index)
+static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
 {
     PropertySlot slot(obj);
     if (!obj->getPropertySlot(exec, index, slot))
-        return noValue();
+        return JSValue();
     return slot.getValue(exec, index);
 }
 
-static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValuePtr value)
+static void putProperty(ExecState* exec, JSObject* obj, const Identifier& propertyName, JSValue value)
 {
     PutPropertySlot slot;
     obj->put(exec, propertyName, value, slot);
 }
 
-JSValuePtr arrayProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&JSArray::info))
         return throwError(exec, TypeError);
     JSObject* thisObj = asArray(thisValue);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
-    if (arrayVisitedElements.size() > MaxReentryDepth)
-        return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+    if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) {
+        if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth)
+            return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+    }
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     if (alreadyVisited)
@@ -152,7 +169,7 @@ JSValuePtr arrayProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVal
             break;
         }
 
-        JSValuePtr element = thisObj->get(exec, k);
+        JSValue element = thisObj->get(exec, k);
         if (element.isUndefinedOrNull())
             continue;
 
@@ -171,15 +188,17 @@ JSValuePtr arrayProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVal
     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
-JSValuePtr arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&JSArray::info))
         return throwError(exec, TypeError);
     JSObject* thisObj = asArray(thisValue);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
-    if (arrayVisitedElements.size() > MaxReentryDepth)
-        return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+    if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) {
+        if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth)
+            return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+    }
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     if (alreadyVisited)
@@ -196,12 +215,12 @@ JSValuePtr arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr t
             break;
         }
 
-        JSValuePtr element = thisObj->get(exec, k);
+        JSValue element = thisObj->get(exec, k);
         if (element.isUndefinedOrNull())
             continue;
 
         JSObject* o = element.toObject(exec);
-        JSValuePtr conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
+        JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
         UString str;
         CallData callData;
         CallType callType = conversionFunction.getCallData(callData);
@@ -223,13 +242,15 @@ JSValuePtr arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr t
     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
-JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
-    if (arrayVisitedElements.size() > MaxReentryDepth)
-        return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+    if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) {
+        if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth)
+            return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+    }
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     if (alreadyVisited)
@@ -238,7 +259,7 @@ JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue,
     Vector<UChar, 256> strBuffer;
 
     UChar comma = ',';
-    UString separator = args.at(exec, 0).isUndefined() ? UString(&comma, 1) : args.at(exec, 0).toString(exec);
+    UString separator = args.at(0).isUndefined() ? UString(&comma, 1) : args.at(0).toString(exec);
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     for (unsigned k = 0; k < length; k++) {
@@ -250,7 +271,7 @@ JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue,
             break;
         }
 
-        JSValuePtr element = thisObj->get(exec, k);
+        JSValue element = thisObj->get(exec, k);
         if (element.isUndefinedOrNull())
             continue;
 
@@ -269,19 +290,19 @@ JSValuePtr arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValuePtr thisValue,
     return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
 }
 
-JSValuePtr arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSArray* arr = constructEmptyArray(exec);
     int n = 0;
-    JSValuePtr curArg = thisValue.toThisObject(exec);
+    JSValue curArg = thisValue.toThisObject(exec);
     ArgList::const_iterator it = args.begin();
     ArgList::const_iterator end = args.end();
     while (1) {
         if (curArg.isObject(&JSArray::info)) {
-            JSArray* curArray = asArray(curArg);
-            unsigned length = curArray->length();
+            unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec);
+            JSObject* curObject = curArg.toObject(exec);
             for (unsigned k = 0; k < length; ++k) {
-                if (JSValuePtr v = getProperty(exec, curArray, k))
+                if (JSValue v = getProperty(exec, curObject, k))
                     arr->put(exec, n, v);
                 n++;
             }
@@ -291,20 +312,20 @@ JSValuePtr arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue
         }
         if (it == end)
             break;
-        curArg = (*it).jsValue(exec);
+        curArg = (*it);
         ++it;
     }
     arr->setLength(n);
     return arr;
 }
 
-JSValuePtr arrayProtoFuncPop(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
-    if (exec->interpreter()->isJSArray(thisValue))
+    if (isJSArray(&exec->globalData(), thisValue))
         return asArray(thisValue)->pop();
 
     JSObject* thisObj = thisValue.toThisObject(exec);
-    JSValuePtr result;
+    JSValue result;
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     if (length == 0) {
         putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
@@ -317,24 +338,24 @@ JSValuePtr arrayProtoFuncPop(ExecState* exec, JSObject*, JSValuePtr thisValue, c
     return result;
 }
 
-JSValuePtr arrayProtoFuncPush(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
-    if (exec->interpreter()->isJSArray(thisValue) && args.size() == 1) {
+    if (isJSArray(&exec->globalData(), thisValue) && args.size() == 1) {
         JSArray* array = asArray(thisValue);
-        array->push(exec, args.begin()->jsValue(exec));
+        array->push(exec, *args.begin());
         return jsNumber(exec, array->length());
     }
 
     JSObject* thisObj = thisValue.toThisObject(exec);
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     for (unsigned n = 0; n < args.size(); n++)
-        thisObj->put(exec, length + n, args.at(exec, n));
+        thisObj->put(exec, length + n, args.at(n));
     length += args.size();
     putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length));
     return jsNumber(exec, length);
 }
 
-JSValuePtr arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
@@ -342,8 +363,8 @@ JSValuePtr arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValuePtr thisValu
 
     for (unsigned k = 0; k < middle; k++) {
         unsigned lk1 = length - k - 1;
-        JSValuePtr obj2 = getProperty(exec, thisObj, lk1);
-        JSValuePtr obj = getProperty(exec, thisObj, k);
+        JSValue obj2 = getProperty(exec, thisObj, lk1);
+        JSValue obj = getProperty(exec, thisObj, k);
 
         if (obj2)
             thisObj->put(exec, k, obj2);
@@ -358,10 +379,10 @@ JSValuePtr arrayProtoFuncReverse(ExecState* exec, JSObject*, JSValuePtr thisValu
     return thisObj;
 }
 
-JSValuePtr arrayProtoFuncShift(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL arrayProtoFuncShift(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
-    JSValuePtr result;
+    JSValue result;
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     if (length == 0) {
@@ -370,7 +391,7 @@ JSValuePtr arrayProtoFuncShift(ExecState* exec, JSObject*, JSValuePtr thisValue,
     } else {
         result = thisObj->get(exec, 0);
         for (unsigned k = 1; k < length; k++) {
-            if (JSValuePtr obj = getProperty(exec, thisObj, k))
+            if (JSValue obj = getProperty(exec, thisObj, k))
                 thisObj->put(exec, k - 1, obj);
             else
                 thisObj->deleteProperty(exec, k - 1);
@@ -381,7 +402,7 @@ JSValuePtr arrayProtoFuncShift(ExecState* exec, JSObject*, JSValuePtr thisValue,
     return result;
 }
 
-JSValuePtr arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     // http://developer.netscape.com/docs/manuals/js/client/jsref/array.htm#1193713 or 15.4.4.10
 
@@ -389,8 +410,8 @@ JSValuePtr arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue,
 
     // We return a new array
     JSArray* resObj = constructEmptyArray(exec);
-    JSValuePtr result = resObj;
-    double begin = args.at(exec, 0).toInteger(exec);
+    JSValue result = resObj;
+    double begin = args.at(0).toInteger(exec);
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     if (begin >= 0) {
         if (begin > length)
@@ -401,10 +422,10 @@ JSValuePtr arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue,
             begin = 0;
     }
     double end;
-    if (args.at(exec, 1).isUndefined())
+    if (args.at(1).isUndefined())
         end = length;
     else {
-        end = args.at(exec, 1).toInteger(exec);
+        end = args.at(1).toInteger(exec);
         if (end < 0) {
             end += length;
             if (end < 0)
@@ -419,18 +440,18 @@ JSValuePtr arrayProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue,
     int b = static_cast<int>(begin);
     int e = static_cast<int>(end);
     for (int k = b; k < e; k++, n++) {
-        if (JSValuePtr v = getProperty(exec, thisObj, k))
+        if (JSValue v = getProperty(exec, thisObj, k))
             resObj->put(exec, n, v);
     }
     resObj->setLength(n);
     return result;
 }
 
-JSValuePtr arrayProtoFuncSort(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
-    JSValuePtr function = args.at(exec, 0);
+    JSValue function = args.at(0);
     CallData callData;
     CallType callType = function.getCallData(callData);
 
@@ -452,18 +473,18 @@ JSValuePtr arrayProtoFuncSort(ExecState* exec, JSObject*, JSValuePtr thisValue,
     // "Min" sort. Not the fastest, but definitely less code than heapsort
     // or quicksort, and much less swapping than bubblesort/insertionsort.
     for (unsigned i = 0; i < length - 1; ++i) {
-        JSValuePtr iObj = thisObj->get(exec, i);
+        JSValue iObj = thisObj->get(exec, i);
         unsigned themin = i;
-        JSValuePtr minObj = iObj;
+        JSValue minObj = iObj;
         for (unsigned j = i + 1; j < length; ++j) {
-            JSValuePtr jObj = thisObj->get(exec, j);
+            JSValue jObj = thisObj->get(exec, j);
             double compareResult;
             if (jObj.isUndefined())
                 compareResult = 1; // don't check minObj because there's no need to differentiate == (0) from > (1)
             else if (minObj.isUndefined())
                 compareResult = -1;
             else if (callType != CallTypeNone) {
-                ArgList l;
+                MarkedArgumentBuffer l;
                 l.append(jObj);
                 l.append(minObj);
                 compareResult = call(exec, function, callType, callData, exec->globalThisValue(), l).toNumber(exec);
@@ -484,17 +505,17 @@ JSValuePtr arrayProtoFuncSort(ExecState* exec, JSObject*, JSValuePtr thisValue,
     return thisObj;
 }
 
-JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
     // 15.4.4.12
     JSArray* resObj = constructEmptyArray(exec);
-    JSValuePtr result = resObj;
+    JSValue result = resObj;
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     if (!args.size())
         return jsUndefined();
-    int begin = args.at(exec, 0).toUInt32(exec);
+    int begin = args.at(0).toUInt32(exec);
     if (begin < 0)
         begin = std::max<int>(begin + length, 0);
     else
@@ -502,12 +523,12 @@ JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue
 
     unsigned deleteCount;
     if (args.size() > 1)
-        deleteCount = std::min<int>(std::max<int>(args.at(exec, 1).toUInt32(exec), 0), length - begin);
+        deleteCount = std::min<int>(std::max<int>(args.at(1).toUInt32(exec), 0), length - begin);
     else
         deleteCount = length - begin;
 
     for (unsigned k = 0; k < deleteCount; k++) {
-        if (JSValuePtr v = getProperty(exec, thisObj, k + begin))
+        if (JSValue v = getProperty(exec, thisObj, k + begin))
             resObj->put(exec, k, v);
     }
     resObj->setLength(deleteCount);
@@ -516,7 +537,7 @@ JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue
     if (additionalArgs != deleteCount) {
         if (additionalArgs < deleteCount) {
             for (unsigned k = begin; k < length - deleteCount; ++k) {
-                if (JSValuePtr v = getProperty(exec, thisObj, k + deleteCount))
+                if (JSValue v = getProperty(exec, thisObj, k + deleteCount))
                     thisObj->put(exec, k + additionalArgs, v);
                 else
                     thisObj->deleteProperty(exec, k + additionalArgs);
@@ -525,7 +546,7 @@ JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue
                 thisObj->deleteProperty(exec, k - 1);
         } else {
             for (unsigned k = length - deleteCount; (int)k > begin; --k) {
-                if (JSValuePtr obj = getProperty(exec, thisObj, k + deleteCount - 1))
+                if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1))
                     thisObj->put(exec, k + additionalArgs - 1, obj);
                 else
                     thisObj->deleteProperty(exec, k + additionalArgs - 1);
@@ -533,13 +554,13 @@ JSValuePtr arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValuePtr thisValue
         }
     }
     for (unsigned k = 0; k < additionalArgs; ++k)
-        thisObj->put(exec, k + begin, args.at(exec, k + 2));
+        thisObj->put(exec, k + begin, args.at(k + 2));
 
     putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(exec, length - deleteCount + additionalArgs));
     return result;
 }
 
-JSValuePtr arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
@@ -548,49 +569,70 @@ JSValuePtr arrayProtoFuncUnShift(ExecState* exec, JSObject*, JSValuePtr thisValu
     unsigned nrArgs = args.size();
     if (nrArgs) {
         for (unsigned k = length; k > 0; --k) {
-            if (JSValuePtr v = getProperty(exec, thisObj, k - 1))
+            if (JSValue v = getProperty(exec, thisObj, k - 1))
                 thisObj->put(exec, k + nrArgs - 1, v);
             else
                 thisObj->deleteProperty(exec, k + nrArgs - 1);
         }
     }
     for (unsigned k = 0; k < nrArgs; ++k)
-        thisObj->put(exec, k, args.at(exec, k));
-    JSValuePtr result = jsNumber(exec, length + nrArgs);
+        thisObj->put(exec, k, args.at(k));
+    JSValue result = jsNumber(exec, length + nrArgs);
     putProperty(exec, thisObj, exec->propertyNames().length, result);
     return result;
 }
 
-JSValuePtr arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
-    JSValuePtr function = args.at(exec, 0);
+    JSValue function = args.at(0);
     CallData callData;
     CallType callType = function.getCallData(callData);
     if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
+    JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
     JSArray* resultArray = constructEmptyArray(exec);
 
     unsigned filterIndex = 0;
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+    unsigned k = 0;
+    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+        JSFunction* f = asFunction(function);
+        JSArray* array = asArray(thisObj);
+        CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+        for (; k < length && !exec->hadException(); ++k) {
+            if (!array->canGetIndex(k))
+                break;
+            JSValue v = array->getIndex(k);
+            cachedCall.setThis(applyThis);
+            cachedCall.setArgument(0, v);
+            cachedCall.setArgument(1, jsNumber(exec, k));
+            cachedCall.setArgument(2, thisObj);
+            
+            JSValue result = cachedCall.call();
+            if (result.toBoolean(exec))
+                resultArray->put(exec, filterIndex++, v);
+        }
+        if (k == length)
+            return resultArray;
+    }
+    for (; k < length && !exec->hadException(); ++k) {
         PropertySlot slot(thisObj);
 
         if (!thisObj->getPropertySlot(exec, k, slot))
             continue;
 
-        JSValuePtr v = slot.getValue(exec, k);
+        JSValue v = slot.getValue(exec, k);
 
-        ArgList eachArguments;
+        MarkedArgumentBuffer eachArguments;
 
         eachArguments.append(v);
         eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
-        JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments);
+        JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
 
         if (result.toBoolean(exec))
             resultArray->put(exec, filterIndex++, v);
@@ -598,36 +640,52 @@ JSValuePtr arrayProtoFuncFilter(ExecState* exec, JSObject*, JSValuePtr thisValue
     return resultArray;
 }
 
-JSValuePtr arrayProtoFuncMap(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncMap(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
-    JSValuePtr function = args.at(exec, 0);
+    JSValue function = args.at(0);
     CallData callData;
     CallType callType = function.getCallData(callData);
     if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
+    JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
 
     JSArray* resultArray = constructEmptyArray(exec, length);
-
-    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+    unsigned k = 0;
+    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+        JSFunction* f = asFunction(function);
+        JSArray* array = asArray(thisObj);
+        CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+        for (; k < length && !exec->hadException(); ++k) {
+            if (UNLIKELY(!array->canGetIndex(k)))
+                break;
+
+            cachedCall.setThis(applyThis);
+            cachedCall.setArgument(0, array->getIndex(k));
+            cachedCall.setArgument(1, jsNumber(exec, k));
+            cachedCall.setArgument(2, thisObj);
+
+            resultArray->JSArray::put(exec, k, cachedCall.call());
+        }
+    }
+    for (; k < length && !exec->hadException(); ++k) {
         PropertySlot slot(thisObj);
         if (!thisObj->getPropertySlot(exec, k, slot))
             continue;
 
-        JSValuePtr v = slot.getValue(exec, k);
+        JSValue v = slot.getValue(exec, k);
 
-        ArgList eachArguments;
+        MarkedArgumentBuffer eachArguments;
 
         eachArguments.append(v);
         eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
 
-        JSValuePtr result = call(exec, function, callType, callData, applyThis, eachArguments);
+        JSValue result = call(exec, function, callType, callData, applyThis, eachArguments);
         resultArray->put(exec, k, result);
     }
 
@@ -639,28 +697,46 @@ JSValuePtr arrayProtoFuncMap(ExecState* exec, JSObject*, JSValuePtr thisValue, c
 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach
 // http://developer-test.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some
 
-JSValuePtr arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
-    JSValuePtr function = args.at(exec, 0);
+    JSValue function = args.at(0);
     CallData callData;
     CallType callType = function.getCallData(callData);
     if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
+    JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
 
-    JSValuePtr result = jsBoolean(true);
+    JSValue result = jsBoolean(true);
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+    unsigned k = 0;
+    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+        JSFunction* f = asFunction(function);
+        JSArray* array = asArray(thisObj);
+        CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+        for (; k < length && !exec->hadException(); ++k) {
+            if (UNLIKELY(!array->canGetIndex(k)))
+                break;
+            
+            cachedCall.setThis(applyThis);
+            cachedCall.setArgument(0, array->getIndex(k));
+            cachedCall.setArgument(1, jsNumber(exec, k));
+            cachedCall.setArgument(2, thisObj);
+            
+            if (!cachedCall.call().toBoolean(exec))
+                return jsBoolean(false);
+        }
+    }
+    for (; k < length && !exec->hadException(); ++k) {
         PropertySlot slot(thisObj);
 
         if (!thisObj->getPropertySlot(exec, k, slot))
             continue;
 
-        ArgList eachArguments;
+        MarkedArgumentBuffer eachArguments;
 
         eachArguments.append(slot.getValue(exec, k));
         eachArguments.append(jsNumber(exec, k));
@@ -677,25 +753,42 @@ JSValuePtr arrayProtoFuncEvery(ExecState* exec, JSObject*, JSValuePtr thisValue,
     return result;
 }
 
-JSValuePtr arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
-    JSValuePtr function = args.at(exec, 0);
+    JSValue function = args.at(0);
     CallData callData;
     CallType callType = function.getCallData(callData);
     if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
+    JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+    unsigned k = 0;
+    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+        JSFunction* f = asFunction(function);
+        JSArray* array = asArray(thisObj);
+        CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+        for (; k < length && !exec->hadException(); ++k) {
+            if (UNLIKELY(!array->canGetIndex(k)))
+                break;
+
+            cachedCall.setThis(applyThis);
+            cachedCall.setArgument(0, array->getIndex(k));
+            cachedCall.setArgument(1, jsNumber(exec, k));
+            cachedCall.setArgument(2, thisObj);
+
+            cachedCall.call();
+        }
+    }
+    for (; k < length && !exec->hadException(); ++k) {
         PropertySlot slot(thisObj);
         if (!thisObj->getPropertySlot(exec, k, slot))
             continue;
 
-        ArgList eachArguments;
+        MarkedArgumentBuffer eachArguments;
         eachArguments.append(slot.getValue(exec, k));
         eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
@@ -705,27 +798,45 @@ JSValuePtr arrayProtoFuncForEach(ExecState* exec, JSObject*, JSValuePtr thisValu
     return jsUndefined();
 }
 
-JSValuePtr arrayProtoFuncSome(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncSome(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
-    JSValuePtr function = args.at(exec, 0);
+    JSValue function = args.at(0);
     CallData callData;
     CallType callType = function.getCallData(callData);
     if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSObject* applyThis = args.at(exec, 1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(exec, 1).toObject(exec);
+    JSObject* applyThis = args.at(1).isUndefinedOrNull() ? exec->globalThisValue() : args.at(1).toObject(exec);
 
-    JSValuePtr result = jsBoolean(false);
+    JSValue result = jsBoolean(false);
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-    for (unsigned k = 0; k < length && !exec->hadException(); ++k) {
+    unsigned k = 0;
+    if (callType == CallTypeJS && isJSArray(&exec->globalData(), thisObj)) {
+        JSFunction* f = asFunction(function);
+        JSArray* array = asArray(thisObj);
+        CachedCall cachedCall(exec, f, 3, exec->exceptionSlot());
+        for (; k < length && !exec->hadException(); ++k) {
+            if (UNLIKELY(!array->canGetIndex(k)))
+                break;
+            
+            cachedCall.setThis(applyThis);
+            cachedCall.setArgument(0, array->getIndex(k));
+            cachedCall.setArgument(1, jsNumber(exec, k));
+            cachedCall.setArgument(2, thisObj);
+            
+            if (cachedCall.call().toBoolean(exec))
+                return jsBoolean(true);
+        }
+    }
+    for (; k < length && !exec->hadException(); ++k) {
         PropertySlot slot(thisObj);
         if (!thisObj->getPropertySlot(exec, k, slot))
             continue;
 
-        ArgList eachArguments;
+        MarkedArgumentBuffer eachArguments;
         eachArguments.append(slot.getValue(exec, k));
         eachArguments.append(jsNumber(exec, k));
         eachArguments.append(thisObj);
@@ -740,7 +851,146 @@ JSValuePtr arrayProtoFuncSome(ExecState* exec, JSObject*, JSValuePtr thisValue,
     return result;
 }
 
-JSValuePtr arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncReduce(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue.toThisObject(exec);
+    
+    JSValue function = args.at(0);
+    CallData callData;
+    CallType callType = function.getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError);
+
+    unsigned i = 0;
+    JSValue rv;
+    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+    if (!length && args.size() == 1)
+        return throwError(exec, TypeError);
+    JSArray* array = 0;
+    if (isJSArray(&exec->globalData(), thisObj))
+        array = asArray(thisObj);
+
+    if (args.size() >= 2)
+        rv = args.at(1);
+    else if (array && array->canGetIndex(0)){
+        rv = array->getIndex(0);
+        i = 1;
+    } else {
+        for (i = 0; i < length; i++) {
+            rv = getProperty(exec, thisObj, i);
+            if (rv)
+                break;
+        }
+        if (!rv)
+            return throwError(exec, TypeError);
+        i++;
+    }
+
+    if (callType == CallTypeJS && array) {
+        CachedCall cachedCall(exec, asFunction(function), 4, exec->exceptionSlot());
+        for (; i < length && !exec->hadException(); ++i) {
+            cachedCall.setThis(jsNull());
+            cachedCall.setArgument(0, rv);
+            JSValue v;
+            if (LIKELY(array->canGetIndex(i)))
+                v = array->getIndex(i);
+            else
+                break; // length has been made unsafe while we enumerate fallback to slow path
+            cachedCall.setArgument(1, v);
+            cachedCall.setArgument(2, jsNumber(exec, i));
+            cachedCall.setArgument(3, array);
+            rv = cachedCall.call();
+        }
+        if (i == length) // only return if we reached the end of the array
+            return rv;
+    }
+
+    for (; i < length && !exec->hadException(); ++i) {
+        JSValue prop = getProperty(exec, thisObj, i);
+        if (!prop)
+            continue;
+        
+        MarkedArgumentBuffer eachArguments;
+        eachArguments.append(rv);
+        eachArguments.append(prop);
+        eachArguments.append(jsNumber(exec, i));
+        eachArguments.append(thisObj);
+        
+        rv = call(exec, function, callType, callData, jsNull(), eachArguments);
+    }
+    return rv;
+}
+
+JSValue JSC_HOST_CALL arrayProtoFuncReduceRight(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
+{
+    JSObject* thisObj = thisValue.toThisObject(exec);
+    
+    JSValue function = args.at(0);
+    CallData callData;
+    CallType callType = function.getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError);
+    
+    unsigned i = 0;
+    JSValue rv;
+    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+    if (!length && args.size() == 1)
+        return throwError(exec, TypeError);
+    JSArray* array = 0;
+    if (isJSArray(&exec->globalData(), thisObj))
+        array = asArray(thisObj);
+    
+    if (args.size() >= 2)
+        rv = args.at(1);
+    else if (array && array->canGetIndex(length - 1)){
+        rv = array->getIndex(length - 1);
+        i = 1;
+    } else {
+        for (i = 0; i < length; i++) {
+            rv = getProperty(exec, thisObj, length - i - 1);
+            if (rv)
+                break;
+        }
+        if (!rv)
+            return throwError(exec, TypeError);
+        i++;
+    }
+    
+    if (callType == CallTypeJS && array) {
+        CachedCall cachedCall(exec, asFunction(function), 4, exec->exceptionSlot());
+        for (; i < length && !exec->hadException(); ++i) {
+            unsigned idx = length - i - 1;
+            cachedCall.setThis(jsNull());
+            cachedCall.setArgument(0, rv);
+            if (UNLIKELY(!array->canGetIndex(idx)))
+                break; // length has been made unsafe while we enumerate fallback to slow path
+            cachedCall.setArgument(1, array->getIndex(idx));
+            cachedCall.setArgument(2, jsNumber(exec, idx));
+            cachedCall.setArgument(3, array);
+            rv = cachedCall.call();
+        }
+        if (i == length) // only return if we reached the end of the array
+            return rv;
+    }
+    
+    for (; i < length && !exec->hadException(); ++i) {
+        unsigned idx = length - i - 1;
+        JSValue prop = getProperty(exec, thisObj, idx);
+        if (!prop)
+            continue;
+        
+        MarkedArgumentBuffer eachArguments;
+        eachArguments.append(rv);
+        eachArguments.append(prop);
+        eachArguments.append(jsNumber(exec, idx));
+        eachArguments.append(thisObj);
+        
+        rv = call(exec, function, callType, callData, jsNull(), eachArguments);
+    }
+    return rv;        
+}
+
+JSValue JSC_HOST_CALL arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     // JavaScript 1.5 Extension by Mozilla
     // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
@@ -748,7 +998,7 @@ JSValuePtr arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValu
     JSObject* thisObj = thisValue.toThisObject(exec);
 
     unsigned index = 0;
-    double d = args.at(exec, 1).toInteger(exec);
+    double d = args.at(1).toInteger(exec);
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     if (d < 0)
         d += length;
@@ -759,19 +1009,19 @@ JSValuePtr arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValu
             index = static_cast<unsigned>(d);
     }
 
-    JSValuePtr searchElement = args.at(exec, 0);
+    JSValue searchElement = args.at(0);
     for (; index < length; ++index) {
-        JSValuePtr e = getProperty(exec, thisObj, index);
+        JSValue e = getProperty(exec, thisObj, index);
         if (!e)
             continue;
-        if (JSValuePtr::strictEqual(searchElement, e))
+        if (JSValue::strictEqual(searchElement, e))
             return jsNumber(exec, index);
     }
 
     return jsNumber(exec, -1);
 }
 
-JSValuePtr arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     // JavaScript 1.6 Extension by Mozilla
     // Documentation: http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
@@ -780,7 +1030,7 @@ JSValuePtr arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr this
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     int index = length - 1;
-    double d = args.at(exec, 1).toIntegerPreserveNaN(exec);
+    double d = args.at(1).toIntegerPreserveNaN(exec);
 
     if (d < 0) {
         d += length;
@@ -790,12 +1040,12 @@ JSValuePtr arrayProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr this
     if (d < length)
         index = static_cast<int>(d);
 
-    JSValuePtr searchElement = args.at(exec, 0);
+    JSValue searchElement = args.at(0);
     for (; index >= 0; --index) {
-        JSValuePtr e = getProperty(exec, thisObj, index);
+        JSValue e = getProperty(exec, thisObj, index);
         if (!e)
             continue;
-        if (JSValuePtr::strictEqual(searchElement, e))
+        if (JSValue::strictEqual(searchElement, e))
             return jsNumber(exec, index);
     }
 
index 13dd95c2e51293591cade73a27147b251405f7ae..8a954af1dbfafc4b01317635c35208868631a2bc 100644 (file)
@@ -38,12 +38,12 @@ namespace JSC {
             : m_object(object)
         {
             if (!m_object->structure()->isDictionary())
-                m_object->setStructure(Structure::toDictionaryTransition(m_object->structure()));
+                m_object->setStructure(Structure::toCacheableDictionaryTransition(m_object->structure()));
         }
 
         ~BatchedTransitionOptimizer()
         {
-            m_object->setStructure(Structure::fromDictionaryTransition(m_object->structure()));
+            m_object->flattenDictionaryObject();
         }
 
     private:
index bdf332246be2fa79e1d2394746a8312e952145c4..9fcba374c06d0eb30676497ff52372227f6f6852 100644 (file)
@@ -41,7 +41,7 @@ BooleanConstructor::BooleanConstructor(ExecState* exec, PassRefPtr<Structure> st
 JSObject* constructBoolean(ExecState* exec, const ArgList& args)
 {
     BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
-    obj->setInternalValue(jsBoolean(args.at(exec, 0).toBoolean(exec)));
+    obj->setInternalValue(jsBoolean(args.at(0).toBoolean(exec)));
     return obj;
 }
 
@@ -57,9 +57,9 @@ ConstructType BooleanConstructor::getConstructData(ConstructData& constructData)
 }
 
 // ECMA 15.6.1
-static JSValuePtr callBooleanConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callBooleanConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsBoolean(args.at(exec, 0).toBoolean(exec));
+    return jsBoolean(args.at(0).toBoolean(exec));
 }
 
 CallType BooleanConstructor::getCallData(CallData& callData)
@@ -68,7 +68,7 @@ CallType BooleanConstructor::getCallData(CallData& callData)
     return CallTypeHost;
 }
 
-JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValuePtr immediateBooleanValue)
+JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSValue immediateBooleanValue)
 {
     BooleanObject* obj = new (exec) BooleanObject(exec->lexicalGlobalObject()->booleanObjectStructure());
     obj->setInternalValue(immediateBooleanValue);
index db4e8e2a41553ed615bd0b846ed73946c09da0ec..d9f51ab52840e6665cccfac63d8a559517b608f0 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC {
         virtual CallType getCallData(CallData&);
     };
 
-    JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValuePtr);
+    JSObject* constructBooleanFromImmediateBoolean(ExecState*, JSValue);
     JSObject* constructBoolean(ExecState*, const ArgList&);
 
 } // namespace JSC
index 68941e30cfbc5f6ce09425276a6b0919f6a70328..cfd55fe4da5c55746d528b164b36de09a1f31ed2 100644 (file)
@@ -33,9 +33,9 @@ namespace JSC {
         static const ClassInfo info;
     };
 
-    BooleanObject* asBooleanObject(JSValuePtr);
+    BooleanObject* asBooleanObject(JSValue);
 
-    inline BooleanObject* asBooleanObject(JSValuePtr value)
+    inline BooleanObject* asBooleanObject(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&BooleanObject::info));
         return static_cast<BooleanObject*>(asObject(value));
index 9eb52d1e99686da2f9b433431398146d3c0f6ccf..703a56851dff81b5699e442ac6b6647b614b7372 100644 (file)
@@ -22,6 +22,7 @@
 #include "BooleanPrototype.h"
 
 #include "Error.h"
+#include "JSFunction.h"
 #include "JSString.h"
 #include "ObjectPrototype.h"
 #include "PrototypeFunction.h"
@@ -31,8 +32,8 @@ namespace JSC {
 ASSERT_CLASS_FITS_IN_CELL(BooleanPrototype);
 
 // Functions
-static JSValuePtr booleanProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr booleanProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState*, JSObject*, JSValue, const ArgList&);
 
 // ECMA 15.6.4
 
@@ -41,8 +42,8 @@ BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<Structure> struct
 {
     setInternalValue(jsBoolean(false));
 
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, booleanProtoFuncToString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, booleanProtoFuncValueOf), DontEnum);
 }
 
 
@@ -50,7 +51,7 @@ BooleanPrototype::BooleanPrototype(ExecState* exec, PassRefPtr<Structure> struct
 
 // ECMA 15.6.4.2 + 15.6.4.3
 
-JSValuePtr booleanProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (thisValue == jsBoolean(false))
         return jsNontrivialString(exec, "false");
@@ -68,7 +69,7 @@ JSValuePtr booleanProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisV
     return jsNontrivialString(exec, "true");
 }
 
-JSValuePtr booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (thisValue.isBoolean())
         return thisValue;
index fbb6392cc217965d9f199543791f1865968e6aa2..62e42fef5ca59d78190167382c42109179b26900 100644 (file)
@@ -30,7 +30,7 @@
 
 namespace JSC {
 
-JSValuePtr call(ExecState* exec, JSValuePtr functionObject, CallType callType, const CallData& callData, JSValuePtr thisValue, const ArgList& args)
+JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
 {
     if (callType == CallTypeHost)
         return callData.native.function(exec, asObject(functionObject), thisValue, args);
index b8d84cd5f6ab8f9b318a213e7cbb5b2f52748166..d5b0172d8fdf804c44e30ab48e204cd5911628e7 100644 (file)
 #ifndef CallData_h
 #define CallData_h
 
+#include "NativeFunctionWrapper.h"
+
 namespace JSC {
 
     class ArgList;
     class ExecState;
     class FunctionBodyNode;
     class JSObject;
-    class JSValuePtr;
+    class JSValue;
     class ScopeChainNode;
 
     enum CallType {
@@ -44,7 +46,7 @@ namespace JSC {
         CallTypeJS
     };
 
-    typedef JSValuePtr (*NativeFunction)(ExecState*, JSObject*, JSValuePtr thisValue, const ArgList&);
+    typedef JSValue (JSC_HOST_CALL *NativeFunction)(ExecState*, JSObject*, JSValue thisValue, const ArgList&);
 
     union CallData {
         struct {
@@ -56,7 +58,7 @@ namespace JSC {
         } js;
     };
 
-    JSValuePtr call(ExecState*, JSValuePtr functionObject, CallType, const CallData&, JSValuePtr thisValue, const ArgList&);
+    JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&);
 
 } // namespace JSC
 
index a4fea7d628ff8eb13072ee49653321b78c17c07f..3d42bad860830858455bb719f23c2492c0dd8956 100644 (file)
 #include "Interpreter.h"
 #include "JSGlobalObject.h"
 #include "JSLock.h"
+#include "JSONObject.h"
 #include "JSString.h"
 #include "JSValue.h"
 #include "Nodes.h"
 #include "Tracing.h"
 #include <algorithm>
+#include <limits.h>
 #include <setjmp.h>
 #include <stdlib.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/HashCountedSet.h>
 #include <wtf/UnusedParam.h>
+#include <wtf/VMTags.h>
 
 #if PLATFORM(DARWIN)
 
-#include <mach/mach_port.h>
 #include <mach/mach_init.h>
+#include <mach/mach_port.h>
 #include <mach/task.h>
 #include <mach/thread_act.h>
 #include <mach/vm_map.h>
@@ -58,9 +61,7 @@
 
 #if PLATFORM(SOLARIS)
 #include <thread.h>
-#endif
-
-#if PLATFORM(OPENBSD)
+#else
 #include <pthread.h>
 #endif
 
@@ -183,7 +184,7 @@ static NEVER_INLINE CollectorBlock* allocateBlock()
 #if PLATFORM(DARWIN)
     vm_address_t address = 0;
     // FIXME: tag the region as a JavaScriptCore heap when we get a registered VM tag: <rdar://problem/6054788>.
-    vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
+    vm_map(current_task(), &address, BLOCK_SIZE, BLOCK_OFFSET_MASK, VM_FLAGS_ANYWHERE | VM_TAG_FOR_COLLECTOR_MEMORY, MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_DEFAULT, VM_INHERIT_DEFAULT);
 #elif PLATFORM(SYMBIAN)
     // no memory map in symbian, need to hack with fastMalloc
     void* address = fastMalloc(BLOCK_SIZE);
@@ -393,6 +394,63 @@ void* Heap::allocateNumber(size_t s)
     return heapAllocate<NumberHeap>(s);
 }
 
+#if PLATFORM(WINCE)
+void* g_stackBase = 0;
+
+inline bool isPageWritable(void* page)
+{
+    MEMORY_BASIC_INFORMATION memoryInformation;
+    DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation));
+
+    // return false on error, including ptr outside memory
+    if (result != sizeof(memoryInformation))
+        return false;
+
+    DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE);
+    return protect == PAGE_READWRITE
+        || protect == PAGE_WRITECOPY
+        || protect == PAGE_EXECUTE_READWRITE
+        || protect == PAGE_EXECUTE_WRITECOPY;
+}
+
+static void* getStackBase(void* previousFrame)
+{
+    // find the address of this stack frame by taking the address of a local variable
+    bool isGrowingDownward;
+    void* thisFrame = (void*)(&isGrowingDownward);
+
+    isGrowingDownward = previousFrame < &thisFrame;
+    static DWORD pageSize = 0;
+    if (!pageSize) {
+        SYSTEM_INFO systemInfo;
+        GetSystemInfo(&systemInfo);
+        pageSize = systemInfo.dwPageSize;
+    }
+
+    // scan all of memory starting from this frame, and return the last writeable page found
+    register char* currentPage = (char*)((DWORD)thisFrame & ~(pageSize - 1));
+    if (isGrowingDownward) {
+        while (currentPage > 0) {
+            // check for underflow
+            if (currentPage >= (char*)pageSize)
+                currentPage -= pageSize;
+            else
+                currentPage = 0;
+            if (!isPageWritable(currentPage))
+                return currentPage + pageSize;
+        }
+        return 0;
+    } else {
+        while (true) {
+            // guaranteed to complete because isPageWritable returns false at end of memory
+            currentPage += pageSize;
+            if (!isPageWritable(currentPage))
+                return currentPage;
+        }
+    }
+}
+#endif
+
 static inline void* currentThreadStackBase()
 {
 #if PLATFORM(DARWIN)
@@ -427,6 +485,15 @@ static inline void* currentThreadStackBase()
     stack_t stack;
     pthread_stackseg_np(thread, &stack);
     return stack.ss_sp;
+#elif PLATFORM(SYMBIAN)
+    static void* stackBase = 0;
+    if (stackBase == 0) {
+        TThreadStackInfo info;
+        RThread thread;
+        thread.StackInfo(info);
+        stackBase = (void*)info.iBase;
+    }
+    return (void*)stackBase;
 #elif PLATFORM(UNIX)
     static void* stackBase = 0;
     static size_t stackSize = 0;
@@ -449,15 +516,13 @@ static inline void* currentThreadStackBase()
         stackThread = thread;
     }
     return static_cast<char*>(stackBase) + stackSize;
-#elif PLATFORM(SYMBIAN)
-    static void* stackBase = 0;
-    if (stackBase == 0) {
-        TThreadStackInfo info;
-        RThread thread;
-        thread.StackInfo(info);
-        stackBase = (void*)info.iBase;
+#elif PLATFORM(WINCE)
+    if (g_stackBase)
+        return g_stackBase;
+    else {
+        int dummy;
+        return getStackBase(&dummy);
     }
-    return (void*)stackBase;
 #else
 #error Need a way to get the stack base on this platform
 #endif
@@ -807,7 +872,7 @@ void Heap::setGCProtectNeedsLocking()
         m_protectedValuesMutex.set(new Mutex);
 }
 
-void Heap::protect(JSValuePtr k)
+void Heap::protect(JSValue k)
 {
     ASSERT(k);
     ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
@@ -824,7 +889,7 @@ void Heap::protect(JSValuePtr k)
         m_protectedValuesMutex->unlock();
 }
 
-void Heap::unprotect(JSValuePtr k)
+void Heap::unprotect(JSValue k)
 {
     ASSERT(k);
     ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
@@ -841,7 +906,7 @@ void Heap::unprotect(JSValuePtr k)
         m_protectedValuesMutex->unlock();
 }
 
-Heap* Heap::heap(JSValuePtr v)
+Heap* Heap::heap(JSValue v)
 {
     if (!v.isCell())
         return 0;
@@ -985,13 +1050,15 @@ bool Heap::collect()
     markStackObjectsConservatively();
     markProtectedObjects();
     if (m_markListSet && m_markListSet->size())
-        ArgList::markLists(*m_markListSet);
+        MarkedArgumentBuffer::markLists(*m_markListSet);
     if (m_globalData->exception && !m_globalData->exception.marked())
         m_globalData->exception.mark();
     m_globalData->interpreter->registerFile().markCallFrames(this);
     m_globalData->smallStrings.mark();
     if (m_globalData->scopeNodeBeingReparsed)
         m_globalData->scopeNodeBeingReparsed->mark();
+    if (m_globalData->firstStringifierToMark)
+        JSONObject::markStringifiers(m_globalData->firstStringifierToMark);
 
     JAVASCRIPTCORE_GC_MARKED();
 
@@ -1082,8 +1149,10 @@ static const char* typeName(JSCell* cell)
 {
     if (cell->isString())
         return "string";
+#if USE(JSVALUE32)
     if (cell->isNumber())
         return "number";
+#endif
     if (cell->isGetterSetter())
         return "gettersetter";
     ASSERT(cell->isObject());
index ba41d607f22995463f8a3b1ef29f55e894e4d7be..8c490094df52957cc6f65e29d3d9ec60fffe20db 100644 (file)
 
 namespace JSC {
 
-    class ArgList;
+    class MarkedArgumentBuffer;
     class CollectorBlock;
     class JSCell;
     class JSGlobalData;
-    class JSValuePtr;
+    class JSValue;
 
     enum OperationInProgress { NoOperation, Allocation, Collection };
     enum HeapType { PrimaryHeap, NumberHeap };
@@ -96,10 +96,10 @@ namespace JSC {
         Statistics statistics() const;
 
         void setGCProtectNeedsLocking();
-        void protect(JSValuePtr);
-        void unprotect(JSValuePtr);
+        void protect(JSValue);
+        void unprotect(JSValue);
 
-        static Heap* heap(JSValuePtr); // 0 for immediate values
+        static Heap* heap(JSValue); // 0 for immediate values
 
         size_t globalObjectCount();
         size_t protectedObjectCount();
@@ -113,7 +113,7 @@ namespace JSC {
 
         void markConservatively(void* start, void* end);
 
-        HashSet<ArgList*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<ArgList*>; return *m_markListSet; }
+        HashSet<MarkedArgumentBuffer*>& markListSet() { if (!m_markListSet) m_markListSet = new HashSet<MarkedArgumentBuffer*>; return *m_markListSet; }
 
         JSGlobalData* globalData() const { return m_globalData; }
         static bool isNumber(JSCell*);
@@ -147,7 +147,7 @@ namespace JSC {
         OwnPtr<Mutex> m_protectedValuesMutex; // Only non-null if the client explicitly requested it via setGCPrtotectNeedsLocking().
         ProtectCountSet m_protectedValues;
 
-        HashSet<ArgList*>* m_markListSet;
+        HashSet<MarkedArgumentBuffer*>* m_markListSet;
 
 #if ENABLE(JSC_MULTIPLE_THREADS)
         void makeUsableFromMultipleThreads();
@@ -167,8 +167,13 @@ namespace JSC {
     template<size_t bytesPerWord> struct CellSize;
 
     // cell size needs to be a power of two for certain optimizations in collector.cpp
-    template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; }; // 32-bit
-    template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; }; // 64-bit
+#if USE(JSVALUE32)
+    template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; };
+#else
+    template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 64; };
+#endif
+    template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; };
+
     const size_t BLOCK_SIZE = 16 * 4096; // 64k
 
     // derived constants
index fe0a830b3f02c405a23dbc0622d2cb84b5f66005..3837817d052f78ece061ac6de717104defb7b7eb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2003, 2007 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 
 namespace JSC {
 
-const char* const nullCString = 0;
+static const char* const nullCString = 0;
 
 #define INITIALIZE_PROPERTY_NAME(name) , name(globalData, #name)
 
 CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData)
     : nullIdentifier(globalData, nullCString)
+    , emptyIdentifier(globalData, "")
     , underscoreProto(globalData, "__proto__")
     , thisIdentifier(globalData, "this")
     JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
index 45b99a8f7292dd6a1a0468c229387f6123453ab2..408d81903755161a0eff1bfe7c42db8e53762a10 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2003,2007 Apple Computer, Inc
+ *  Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -24,7 +24,7 @@
 #include "Identifier.h"
 #include <wtf/Noncopyable.h>
 
-// ArgList of property names, passed to a macro so we can do set them up various
+// MarkedArgumentBuffer of property names, passed to a macro so we can do set them up various
 // ways without repeating the list.
 #define JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(macro) \
     macro(__defineGetter__) \
     macro(test) \
     macro(toExponential) \
     macro(toFixed) \
+    macro(toISOString) \
+    macro(toJSON) \
     macro(toLocaleString) \
     macro(toPrecision) \
     macro(toString) \
     macro(UTC) \
-    macro(valueOf)
+    macro(valueOf) \
+    macro(displayName)
 
 namespace JSC {
 
@@ -74,6 +77,7 @@ namespace JSC {
 
     public:
         const Identifier nullIdentifier;
+        const Identifier emptyIdentifier;
         const Identifier underscoreProto;
         const Identifier thisIdentifier;
 
index 5655fa54c442cdaf2a8b399941bc6d1c723c9eb2..b8b15819d59315f2aef1b4fc49e1472346a1df56 100644 (file)
@@ -50,7 +50,7 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source)
     return Completion(Normal);
 }
 
-Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValuePtr thisValue)
+Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue)
 {
     JSLock lock(exec);
     
@@ -63,8 +63,8 @@ Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& s
 
     JSObject* thisObj = (!thisValue || thisValue.isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue.toObject(exec);
 
-    JSValuePtr exception = noValue();
-    JSValuePtr result = exec->interpreter()->execute(programNode.get(), exec, scopeChain.node(), thisObj, &exception);
+    JSValue exception;
+    JSValue result = exec->interpreter()->execute(programNode.get(), exec, scopeChain.node(), thisObj, &exception);
 
     if (exception) {
         if (exception.isObject() && asObject(exception)->isWatchdogException())
index 9631b50a18a84db90eaabfeef8af4cb3d87c2e6c..41c9a642f286e037fea5e7f66a428bf8693c9f99 100644 (file)
@@ -39,24 +39,24 @@ namespace JSC {
      */
     class Completion {
     public:
-        Completion(ComplType type = Normal, JSValuePtr value = noValue())
+        Completion(ComplType type = Normal, JSValue value = JSValue())
             : m_type(type)
             , m_value(value)
         {
         }
 
         ComplType complType() const { return m_type; }
-        JSValuePtr value() const { return m_value; }
-        void setValue(JSValuePtr v) { m_value = v; }
+        JSValue value() const { return m_value; }
+        void setValue(JSValue v) { m_value = v; }
         bool isValueCompletion() const { return m_value; }
 
     private:
         ComplType m_type;
-        JSValuePtr m_value;
+        JSValue m_value;
     };
 
     Completion checkSyntax(ExecState*, const SourceCode&);
-    Completion evaluate(ExecState*, ScopeChain&, const SourceCode&, JSValuePtr thisValue = noValue());
+    Completion evaluate(ExecState*, ScopeChain&, const SourceCode&, JSValue thisValue = JSValue());
 
 } // namespace JSC
 
index 7a729ae33787d283f42f819328eae4b34efc0c54..7ee59d7ef77bf261c18c16c8190be56aff60957e 100644 (file)
@@ -30,7 +30,7 @@
 
 namespace JSC {
 
-JSObject* construct(ExecState* exec, JSValuePtr object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
+JSObject* construct(ExecState* exec, JSValue object, ConstructType constructType, const ConstructData& constructData, const ArgList& args)
 {
     if (constructType == ConstructTypeHost)
         return constructData.native.function(exec, asObject(object), args);
index 559c1bd5eb7291e649f786970c0d967c9ca3c0fc..9d580d5799cfa3f3ac97441867a7071279a19e0a 100644 (file)
@@ -35,7 +35,7 @@ namespace JSC {
     class ExecState;
     class FunctionBodyNode;
     class JSObject;
-    class JSValuePtr;
+    class JSValue;
     class ScopeChainNode;
 
     enum ConstructType {
@@ -56,7 +56,7 @@ namespace JSC {
         } js;
     };
 
-    JSObject* construct(ExecState*, JSValuePtr constructor, ConstructType, const ConstructData&, const ArgList&);
+    JSObject* construct(ExecState*, JSValue constructor, ConstructType, const ConstructData&, const ArgList&);
 
 } // namespace JSC
 
index 92ab897442fd5a9651603907fcae8f2a55f1448e..6d7d934062c354302058c378c3a2b25813a0c5d5 100644 (file)
 #include "config.h"
 #include "DateConstructor.h"
 
+#include "DateConversion.h"
 #include "DateInstance.h"
-#include "DateMath.h"
 #include "DatePrototype.h"
+#include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
 #include "ObjectPrototype.h"
 #include "PrototypeFunction.h"
 #include <math.h>
 #include <time.h>
+#include <wtf/DateMath.h>
 #include <wtf/MathExtras.h>
 
+#if PLATFORM(WINCE) && !PLATFORM(QT)
+extern "C" time_t time(time_t* timer); //provided by libce
+#endif
+
 #if HAVE(SYS_TIME_H)
 #include <sys/time.h>
 #endif
 #include <sys/timeb.h>
 #endif
 
+using namespace WTF;
+
 namespace JSC {
 
 // TODO: MakeTime (15.9.11.1) etc. ?
 
 ASSERT_CLASS_FITS_IN_CELL(DateConstructor);
 
-static JSValuePtr dateParse(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateNow(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateUTC(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL dateParse(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateNow(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateUTC(ExecState*, JSObject*, JSValue, const ArgList&);
 
 DateConstructor::DateConstructor(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, DatePrototype* datePrototype)
     : InternalFunction(&exec->globalData(), structure, Identifier(exec, datePrototype->classInfo()->className))
 {
       putDirectWithoutTransition(exec->propertyNames().prototype, datePrototype, DontEnum|DontDelete|ReadOnly);
 
-      putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().parse, dateParse), DontEnum);
-      putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
-      putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().now, dateNow), DontEnum);
+      putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().parse, dateParse), DontEnum);
+      putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 7, exec->propertyNames().UTC, dateUTC), DontEnum);
+      putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().now, dateNow), DontEnum);
 
       putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 7), ReadOnly | DontEnum | DontDelete);
 }
@@ -73,35 +81,35 @@ JSObject* constructDate(ExecState* exec, const ArgList& args)
     if (numArgs == 0) // new Date() ECMA 15.9.3.3
         value = getCurrentUTCTime();
     else if (numArgs == 1) {
-        if (args.at(exec, 0).isObject(&DateInstance::info))
-            value = asDateInstance(args.at(exec, 0))->internalNumber();
+        if (args.at(0).isObject(&DateInstance::info))
+            value = asDateInstance(args.at(0))->internalNumber();
         else {
-            JSValuePtr primitive = args.at(exec, 0).toPrimitive(exec);
+            JSValue primitive = args.at(0).toPrimitive(exec);
             if (primitive.isString())
                 value = parseDate(primitive.getString());
             else
                 value = primitive.toNumber(exec);
         }
     } else {
-        if (isnan(args.at(exec, 0).toNumber(exec))
-                || isnan(args.at(exec, 1).toNumber(exec))
-                || (numArgs >= 3 && isnan(args.at(exec, 2).toNumber(exec)))
-                || (numArgs >= 4 && isnan(args.at(exec, 3).toNumber(exec)))
-                || (numArgs >= 5 && isnan(args.at(exec, 4).toNumber(exec)))
-                || (numArgs >= 6 && isnan(args.at(exec, 5).toNumber(exec)))
-                || (numArgs >= 7 && isnan(args.at(exec, 6).toNumber(exec))))
+        if (isnan(args.at(0).toNumber(exec))
+                || isnan(args.at(1).toNumber(exec))
+                || (numArgs >= 3 && isnan(args.at(2).toNumber(exec)))
+                || (numArgs >= 4 && isnan(args.at(3).toNumber(exec)))
+                || (numArgs >= 5 && isnan(args.at(4).toNumber(exec)))
+                || (numArgs >= 6 && isnan(args.at(5).toNumber(exec)))
+                || (numArgs >= 7 && isnan(args.at(6).toNumber(exec))))
             value = NaN;
         else {
           GregorianDateTime t;
-          int year = args.at(exec, 0).toInt32(exec);
+          int year = args.at(0).toInt32(exec);
           t.year = (year >= 0 && year <= 99) ? year : year - 1900;
-          t.month = args.at(exec, 1).toInt32(exec);
-          t.monthDay = (numArgs >= 3) ? args.at(exec, 2).toInt32(exec) : 1;
-          t.hour = args.at(exec, 3).toInt32(exec);
-          t.minute = args.at(exec, 4).toInt32(exec);
-          t.second = args.at(exec, 5).toInt32(exec);
+          t.month = args.at(1).toInt32(exec);
+          t.monthDay = (numArgs >= 3) ? args.at(2).toInt32(exec) : 1;
+          t.hour = args.at(3).toInt32(exec);
+          t.minute = args.at(4).toInt32(exec);
+          t.second = args.at(5).toInt32(exec);
           t.isDST = -1;
-          double ms = (numArgs >= 7) ? args.at(exec, 6).toNumber(exec) : 0;
+          double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0;
           value = gregorianDateTimeToMS(t, ms, false);
         }
     }
@@ -123,7 +131,7 @@ ConstructType DateConstructor::getConstructData(ConstructData& constructData)
 }
 
 // ECMA 15.9.2
-static JSValuePtr callDate(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
+static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const ArgList&)
 {
     time_t localTime = time(0);
     tm localTM;
@@ -138,37 +146,37 @@ CallType DateConstructor::getCallData(CallData& callData)
     return CallTypeHost;
 }
 
-static JSValuePtr dateParse(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL dateParse(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, parseDate(args.at(exec, 0).toString(exec)));
+    return jsNumber(exec, parseDate(args.at(0).toString(exec)));
 }
 
-static JSValuePtr dateNow(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
+static JSValue JSC_HOST_CALL dateNow(ExecState* exec, JSObject*, JSValue, const ArgList&)
 {
     return jsNumber(exec, getCurrentUTCTime());
 }
 
-static JSValuePtr dateUTC(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL dateUTC(ExecState* exec, JSObject*, JSValue, const ArgList& args) 
 {
     int n = args.size();
-    if (isnan(args.at(exec, 0).toNumber(exec))
-            || isnan(args.at(exec, 1).toNumber(exec))
-            || (n >= 3 && isnan(args.at(exec, 2).toNumber(exec)))
-            || (n >= 4 && isnan(args.at(exec, 3).toNumber(exec)))
-            || (n >= 5 && isnan(args.at(exec, 4).toNumber(exec)))
-            || (n >= 6 && isnan(args.at(exec, 5).toNumber(exec)))
-            || (n >= 7 && isnan(args.at(exec, 6).toNumber(exec))))
+    if (isnan(args.at(0).toNumber(exec))
+            || isnan(args.at(1).toNumber(exec))
+            || (n >= 3 && isnan(args.at(2).toNumber(exec)))
+            || (n >= 4 && isnan(args.at(3).toNumber(exec)))
+            || (n >= 5 && isnan(args.at(4).toNumber(exec)))
+            || (n >= 6 && isnan(args.at(5).toNumber(exec)))
+            || (n >= 7 && isnan(args.at(6).toNumber(exec))))
         return jsNaN(exec);
 
     GregorianDateTime t;
-    int year = args.at(exec, 0).toInt32(exec);
+    int year = args.at(0).toInt32(exec);
     t.year = (year >= 0 && year <= 99) ? year : year - 1900;
-    t.month = args.at(exec, 1).toInt32(exec);
-    t.monthDay = (n >= 3) ? args.at(exec, 2).toInt32(exec) : 1;
-    t.hour = args.at(exec, 3).toInt32(exec);
-    t.minute = args.at(exec, 4).toInt32(exec);
-    t.second = args.at(exec, 5).toInt32(exec);
-    double ms = (n >= 7) ? args.at(exec, 6).toNumber(exec) : 0;
+    t.month = args.at(1).toInt32(exec);
+    t.monthDay = (n >= 3) ? args.at(2).toInt32(exec) : 1;
+    t.hour = args.at(3).toInt32(exec);
+    t.minute = args.at(4).toInt32(exec);
+    t.second = args.at(5).toInt32(exec);
+    double ms = (n >= 7) ? args.at(6).toNumber(exec) : 0;
     return jsNumber(exec, gregorianDateTimeToMS(t, ms, true));
 }
 
diff --git a/runtime/DateConversion.cpp b/runtime/DateConversion.cpp
new file mode 100644 (file)
index 0000000..a725478
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above.  If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#include "config.h"
+#include "DateConversion.h"
+
+#include "UString.h"
+#include <wtf/DateMath.h>
+#include <wtf/StringExtras.h>
+
+using namespace WTF;
+
+namespace JSC {
+
+double parseDate(const UString &date)
+{
+    return parseDateFromNullTerminatedCharacters(date.UTF8String().c_str());
+}
+
+UString formatDate(const GregorianDateTime &t)
+{
+    char buffer[100];
+    snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",
+        weekdayName[(t.weekDay + 6) % 7],
+        monthName[t.month], t.monthDay, t.year + 1900);
+    return buffer;
+}
+
+UString formatDateUTCVariant(const GregorianDateTime &t)
+{
+    char buffer[100];
+    snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",
+        weekdayName[(t.weekDay + 6) % 7],
+        t.monthDay, monthName[t.month], t.year + 1900);
+    return buffer;
+}
+
+UString formatTime(const GregorianDateTime &t, bool utc)
+{
+    char buffer[100];
+    if (utc) {
+        snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
+    } else {
+        int offset = abs(gmtoffset(t));
+        char timeZoneName[70];
+        struct tm gtm = t;
+        strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
+
+        if (timeZoneName[0]) {
+            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
+                t.hour, t.minute, t.second,
+                gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
+        } else {
+            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
+                t.hour, t.minute, t.second,
+                gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
+        }
+    }
+    return UString(buffer);
+}
+
+} // namespace JSC
diff --git a/runtime/DateConversion.h b/runtime/DateConversion.h
new file mode 100644 (file)
index 0000000..0d12815
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef DateConversion_h
+#define DateConversion_h
+
+namespace WTF {
+    struct GregorianDateTime;
+}
+
+namespace JSC {
+
+class UString;
+
+double parseDate(const UString&);
+UString formatDate(const WTF::GregorianDateTime&);
+UString formatDateUTCVariant(const WTF::GregorianDateTime&);
+UString formatTime(const WTF::GregorianDateTime&, bool inputIsUTC);
+
+} // namespace JSC
+
+#endif // DateConversion_h
index 8806dec3d8e823f3a2f013d9e5bcdf82bc6aaaaf..62791aecb28627f6f7b0668b5f128e18da04f505 100644 (file)
 #include "config.h"
 #include "DateInstance.h"
 
-#include "DateMath.h"
 #include <math.h>
+#include <wtf/DateMath.h>
 #include <wtf/MathExtras.h>
 
+using namespace WTF;
+
 namespace JSC {
 
 struct DateInstance::Cache {
@@ -58,13 +60,13 @@ void DateInstance::msToGregorianDateTime(double milli, bool outputIsUTC, Gregori
 
     if (outputIsUTC) {
         if (m_cache->m_gregorianDateTimeUTCCachedForMS != milli) {
-            JSC::msToGregorianDateTime(milli, true, m_cache->m_cachedGregorianDateTimeUTC);
+            WTF::msToGregorianDateTime(milli, true, m_cache->m_cachedGregorianDateTimeUTC);
             m_cache->m_gregorianDateTimeUTCCachedForMS = milli;
         }
         t.copyFrom(m_cache->m_cachedGregorianDateTimeUTC);
     } else {
         if (m_cache->m_gregorianDateTimeCachedForMS != milli) {
-            JSC::msToGregorianDateTime(milli, false, m_cache->m_cachedGregorianDateTime);
+            WTF::msToGregorianDateTime(milli, false, m_cache->m_cachedGregorianDateTime);
             m_cache->m_gregorianDateTimeCachedForMS = milli;
         }
         t.copyFrom(m_cache->m_cachedGregorianDateTime);
index 398f2995bb8d2ee140b1020fabf01d08d516f6c3..3b73521a7cfc5cddf8b4ab18acec2eeed9373edd 100644 (file)
 
 #include "JSWrapperObject.h"
 
-namespace JSC {
-
+namespace WTF {
     struct GregorianDateTime;
+}
+
+namespace JSC {
 
     class DateInstance : public JSWrapperObject {
     public:
@@ -34,14 +36,14 @@ namespace JSC {
 
         double internalNumber() const { return internalValue().uncheckedGetNumber(); }
 
-        bool getTime(GregorianDateTime&, int& offset) const;
-        bool getUTCTime(GregorianDateTime&) const;
+        bool getTime(WTF::GregorianDateTime&, int& offset) const;
+        bool getUTCTime(WTF::GregorianDateTime&) const;
         bool getTime(double& milliseconds, int& offset) const;
         bool getUTCTime(double& milliseconds) const;
 
         static const ClassInfo info;
 
-        void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&) const;
+        void msToGregorianDateTime(double, bool outputIsUTC, WTF::GregorianDateTime&) const;
 
     private:
         virtual const ClassInfo* classInfo() const { return &info; }
@@ -52,9 +54,9 @@ namespace JSC {
         mutable Cache* m_cache;
     };
 
-    DateInstance* asDateInstance(JSValuePtr);
+    DateInstance* asDateInstance(JSValue);
 
-    inline DateInstance* asDateInstance(JSValuePtr value)
+    inline DateInstance* asDateInstance(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&DateInstance::info));
         return static_cast<DateInstance*>(asObject(value));
diff --git a/runtime/DateMath.cpp b/runtime/DateMath.cpp
deleted file mode 100644 (file)
index b452963..0000000
+++ /dev/null
@@ -1,939 +0,0 @@
-/*
- * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * 
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. 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
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Alternatively, the contents of this file may be used under the terms
- * of either the Mozilla Public License Version 1.1, found at
- * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
- * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
- * (the "GPL"), in which case the provisions of the MPL or the GPL are
- * applicable instead of those above.  If you wish to allow use of your
- * version of this file only under the terms of one of those two
- * licenses (the MPL or the GPL) and not to allow others to use your
- * version of this file under the LGPL, indicate your decision by
- * deletingthe provisions above and replace them with the notice and
- * other provisions required by the MPL or the GPL, as the case may be.
- * If you do not delete the provisions above, a recipient may use your
- * version of this file under any of the LGPL, the MPL or the GPL.
- */
-
-#include "config.h"
-#include "DateMath.h"
-
-#include "JSNumberCell.h"
-#include <math.h>
-#include <stdint.h>
-#include <time.h>
-#include <wtf/ASCIICType.h>
-#include <wtf/Assertions.h>
-#include <wtf/CurrentTime.h>
-#include <wtf/MathExtras.h>
-#include <wtf/StringExtras.h>
-
-#if HAVE(ERRNO_H)
-#include <errno.h>
-#endif
-
-#if PLATFORM(DARWIN)
-#include <notify.h>
-#endif
-
-#if HAVE(SYS_TIME_H)
-#include <sys/time.h>
-#endif
-
-#if HAVE(SYS_TIMEB_H)
-#include <sys/timeb.h>
-#endif
-
-#if HAVE(STRINGS_H)
-#include <strings.h>
-#endif
-
-using namespace WTF;
-
-namespace JSC {
-
-/* Constants */
-
-static const double minutesPerDay = 24.0 * 60.0;
-static const double secondsPerDay = 24.0 * 60.0 * 60.0;
-static const double secondsPerYear = 24.0 * 60.0 * 60.0 * 365.0;
-
-static const double usecPerSec = 1000000.0;
-
-static const double maxUnixTime = 2145859200.0; // 12/31/2037
-
-// Day of year for the first day of each month, where index 0 is January, and day 0 is January 1.
-// First for non-leap years, then for leap years.
-static const int firstDayOfMonth[2][12] = {
-    {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
-    {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
-};
-
-static inline bool isLeapYear(int year)
-{
-    if (year % 4 != 0)
-        return false;
-    if (year % 400 == 0)
-        return true;
-    if (year % 100 == 0)
-        return false;
-    return true;
-}
-
-static inline int daysInYear(int year)
-{
-    return 365 + isLeapYear(year);
-}
-
-static inline double daysFrom1970ToYear(int year)
-{
-    // The Gregorian Calendar rules for leap years:
-    // Every fourth year is a leap year.  2004, 2008, and 2012 are leap years.
-    // However, every hundredth year is not a leap year.  1900 and 2100 are not leap years.
-    // Every four hundred years, there's a leap year after all.  2000 and 2400 are leap years.
-
-    static const int leapDaysBefore1971By4Rule = 1970 / 4;
-    static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100;
-    static const int leapDaysBefore1971By400Rule = 1970 / 400;
-
-    const double yearMinusOne = year - 1;
-    const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule;
-    const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule;
-    const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefore1971By400Rule;
-
-    return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule;
-}
-
-static inline double msToDays(double ms)
-{
-    return floor(ms / msPerDay);
-}
-
-static inline int msToYear(double ms)
-{
-    int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970);
-    double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear);
-    if (msFromApproxYearTo1970 > ms)
-        return approxYear - 1;
-    if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms)
-        return approxYear + 1;
-    return approxYear;
-}
-
-static inline int dayInYear(double ms, int year)
-{
-    return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year));
-}
-
-static inline double msToMilliseconds(double ms)
-{
-    double result = fmod(ms, msPerDay);
-    if (result < 0)
-        result += msPerDay;
-    return result;
-}
-
-// 0: Sunday, 1: Monday, etc.
-static inline int msToWeekDay(double ms)
-{
-    int wd = (static_cast<int>(msToDays(ms)) + 4) % 7;
-    if (wd < 0)
-        wd += 7;
-    return wd;
-}
-
-static inline int msToSeconds(double ms)
-{
-    double result = fmod(floor(ms / msPerSecond), secondsPerMinute);
-    if (result < 0)
-        result += secondsPerMinute;
-    return static_cast<int>(result);
-}
-
-static inline int msToMinutes(double ms)
-{
-    double result = fmod(floor(ms / msPerMinute), minutesPerHour);
-    if (result < 0)
-        result += minutesPerHour;
-    return static_cast<int>(result);
-}
-
-static inline int msToHours(double ms)
-{
-    double result = fmod(floor(ms/msPerHour), hoursPerDay);
-    if (result < 0)
-        result += hoursPerDay;
-    return static_cast<int>(result);
-}
-
-static inline int monthFromDayInYear(int dayInYear, bool leapYear)
-{
-    const int d = dayInYear;
-    int step;
-
-    if (d < (step = 31))
-        return 0;
-    step += (leapYear ? 29 : 28);
-    if (d < step)
-        return 1;
-    if (d < (step += 31))
-        return 2;
-    if (d < (step += 30))
-        return 3;
-    if (d < (step += 31))
-        return 4;
-    if (d < (step += 30))
-        return 5;
-    if (d < (step += 31))
-        return 6;
-    if (d < (step += 31))
-        return 7;
-    if (d < (step += 30))
-        return 8;
-    if (d < (step += 31))
-        return 9;
-    if (d < (step += 30))
-        return 10;
-    return 11;
-}
-
-static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& startDayOfNextMonth, int daysInThisMonth)
-{
-    startDayOfThisMonth = startDayOfNextMonth;
-    startDayOfNextMonth += daysInThisMonth;
-    return (dayInYear <= startDayOfNextMonth);
-}
-
-static inline int dayInMonthFromDayInYear(int dayInYear, bool leapYear)
-{
-    const int d = dayInYear;
-    int step;
-    int next = 30;
-
-    if (d <= next)
-        return d + 1;
-    const int daysInFeb = (leapYear ? 29 : 28);
-    if (checkMonth(d, step, next, daysInFeb))
-        return d - step;
-    if (checkMonth(d, step, next, 31))
-        return d - step;
-    if (checkMonth(d, step, next, 30))
-        return d - step;
-    if (checkMonth(d, step, next, 31))
-        return d - step;
-    if (checkMonth(d, step, next, 30))
-        return d - step;
-    if (checkMonth(d, step, next, 31))
-        return d - step;
-    if (checkMonth(d, step, next, 31))
-        return d - step;
-    if (checkMonth(d, step, next, 30))
-        return d - step;
-    if (checkMonth(d, step, next, 31))
-        return d - step;
-    if (checkMonth(d, step, next, 30))
-        return d - step;
-    step = next;
-    return d - step;
-}
-
-static inline int monthToDayInYear(int month, bool isLeapYear)
-{
-    return firstDayOfMonth[isLeapYear][month];
-}
-
-static inline double timeToMS(double hour, double min, double sec, double ms)
-{
-    return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);
-}
-
-static int dateToDayInYear(int year, int month, int day)
-{
-    year += month / 12;
-
-    month %= 12;
-    if (month < 0) {
-        month += 12;
-        --year;
-    }
-
-    int yearday = static_cast<int>(floor(daysFrom1970ToYear(year)));
-    int monthday = monthToDayInYear(month, isLeapYear(year));
-
-    return yearday + monthday + day - 1;
-}
-
-double getCurrentUTCTime()
-{
-    return floor(getCurrentUTCTimeWithMicroseconds());
-}
-
-// Returns current time in milliseconds since 1 Jan 1970.
-double getCurrentUTCTimeWithMicroseconds()
-{
-    return currentTime() * 1000.0; 
-}
-
-void getLocalTime(const time_t* localTime, struct tm* localTM)
-{
-#if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WIN_CE)
-    *localTM = *localtime(localTime);
-#elif COMPILER(MSVC)
-    localtime_s(localTM, localTime);
-#else
-    localtime_r(localTime, localTM);
-#endif
-}
-
-// There is a hard limit at 2038 that we currently do not have a workaround
-// for (rdar://problem/5052975).
-static inline int maximumYearForDST()
-{
-    return 2037;
-}
-
-static inline int minimumYearForDST()
-{
-    // Because of the 2038 issue (see maximumYearForDST) if the current year is
-    // greater than the max year minus 27 (2010), we want to use the max year
-    // minus 27 instead, to ensure there is a range of 28 years that all years
-    // can map to.
-    return std::min(msToYear(getCurrentUTCTime()), maximumYearForDST() - 27) ;
-}
-
-/*
- * Find an equivalent year for the one given, where equivalence is deterined by
- * the two years having the same leapness and the first day of the year, falling
- * on the same day of the week.
- *
- * This function returns a year between this current year and 2037, however this
- * function will potentially return incorrect results if the current year is after
- * 2010, (rdar://problem/5052975), if the year passed in is before 1900 or after
- * 2100, (rdar://problem/5055038).
- */
-int equivalentYearForDST(int year)
-{
-    // It is ok if the cached year is not the current year as long as the rules
-    // for DST did not change between the two years; if they did the app would need
-    // to be restarted.
-    static int minYear = minimumYearForDST();
-    int maxYear = maximumYearForDST();
-
-    int difference;
-    if (year > maxYear)
-        difference = minYear - year;
-    else if (year < minYear)
-        difference = maxYear - year;
-    else
-        return year;
-
-    int quotient = difference / 28;
-    int product = (quotient) * 28;
-
-    year += product;
-    ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cast<int>(NaN)));
-    return year;
-}
-
-static int32_t calculateUTCOffset()
-{
-    tm localt;
-    memset(&localt, 0, sizeof(localt));
-    // get the difference between this time zone and UTC on Jan 01, 2000 12:00:00 AM
-    localt.tm_mday = 1;
-    localt.tm_year = 100;
-    time_t utcOffset = 946684800 - mktime(&localt);
-
-    return static_cast<int32_t>(utcOffset * 1000);
-}
-
-#if PLATFORM(DARWIN)
-static int32_t s_cachedUTCOffset; // In milliseconds. An assumption here is that access to an int32_t variable is atomic on platforms that take this code path.
-static bool s_haveCachedUTCOffset;
-static int s_notificationToken;
-#endif
-
-/*
- * Get the difference in milliseconds between this time zone and UTC (GMT)
- * NOT including DST.
- */
-double getUTCOffset()
-{
-#if PLATFORM(DARWIN)
-    if (s_haveCachedUTCOffset) {
-        int notified;
-        uint32_t status = notify_check(s_notificationToken, &notified);
-        if (status == NOTIFY_STATUS_OK && !notified)
-            return s_cachedUTCOffset;
-    }
-#endif
-
-    int32_t utcOffset = calculateUTCOffset();
-
-#if PLATFORM(DARWIN)
-    // Theoretically, it is possible that several threads will be executing this code at once, in which case we will have a race condition,
-    // and a newer value may be overwritten. In practice, time zones don't change that often.
-    s_cachedUTCOffset = utcOffset;
-#endif
-
-    return utcOffset;
-}
-
-/*
- * Get the DST offset for the time passed in.  Takes
- * seconds (not milliseconds) and cannot handle dates before 1970
- * on some OS'
- */
-static double getDSTOffsetSimple(double localTimeSeconds, double utcOffset)
-{
-    if (localTimeSeconds > maxUnixTime)
-        localTimeSeconds = maxUnixTime;
-    else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0)
-        localTimeSeconds += secondsPerDay;
-
-    //input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset()
-    double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset;
-
-    // Offset from UTC but doesn't include DST obviously
-    int offsetHour =  msToHours(offsetTime);
-    int offsetMinute =  msToMinutes(offsetTime);
-
-    // FIXME: time_t has a potential problem in 2038
-    time_t localTime = static_cast<time_t>(localTimeSeconds);
-
-    tm localTM;
-    getLocalTime(&localTime, &localTM);
-
-    double diff = ((localTM.tm_hour - offsetHour) * secondsPerHour) + ((localTM.tm_min - offsetMinute) * 60);
-
-    if (diff < 0)
-        diff += secondsPerDay;
-
-    return (diff * msPerSecond);
-}
-
-// Get the DST offset, given a time in UTC
-static double getDSTOffset(double ms, double utcOffset)
-{
-    // On Mac OS X, the call to localtime (see getDSTOffsetSimple) will return historically accurate
-    // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript
-    // standard explicitly dictates that historical information should not be considered when
-    // determining DST. For this reason we shift away from years that localtime can handle but would
-    // return historically accurate information.
-    int year = msToYear(ms);
-    int equivalentYear = equivalentYearForDST(year);
-    if (year != equivalentYear) {
-        bool leapYear = isLeapYear(year);
-        int dayInYearLocal = dayInYear(ms, year);
-        int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear);
-        int month = monthFromDayInYear(dayInYearLocal, leapYear);
-        int day = dateToDayInYear(equivalentYear, month, dayInMonth);
-        ms = (day * msPerDay) + msToMilliseconds(ms);
-    }
-
-    return getDSTOffsetSimple(ms / msPerSecond, utcOffset);
-}
-
-double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
-{
-    int day = dateToDayInYear(t.year + 1900, t.month, t.monthDay);
-    double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds);
-    double result = (day * msPerDay) + ms;
-
-    if (!inputIsUTC) { // convert to UTC
-        double utcOffset = getUTCOffset();
-        result -= utcOffset;
-        result -= getDSTOffset(result, utcOffset);
-    }
-
-    return result;
-}
-
-void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm)
-{
-    // input is UTC
-    double dstOff = 0.0;
-    const double utcOff = getUTCOffset();
-
-    if (!outputIsUTC) {  // convert to local time
-        dstOff = getDSTOffset(ms, utcOff);
-        ms += dstOff + utcOff;
-    }
-
-    const int year = msToYear(ms);
-    tm.second   =  msToSeconds(ms);
-    tm.minute   =  msToMinutes(ms);
-    tm.hour     =  msToHours(ms);
-    tm.weekDay  =  msToWeekDay(ms);
-    tm.yearDay  =  dayInYear(ms, year);
-    tm.monthDay =  dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year));
-    tm.month    =  monthFromDayInYear(tm.yearDay, isLeapYear(year));
-    tm.year     =  year - 1900;
-    tm.isDST    =  dstOff != 0.0;
-
-    tm.utcOffset = static_cast<long>((dstOff + utcOff) / msPerSecond);
-    tm.timeZone = NULL;
-}
-
-void initDateMath()
-{
-#ifndef NDEBUG
-    static bool alreadyInitialized;
-    ASSERT(!alreadyInitialized++);
-#endif
-
-    equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
-#if PLATFORM(DARWIN)
-    // Register for a notification whenever the time zone changes.
-    uint32_t status = notify_register_check("com.apple.system.timezone", &s_notificationToken);
-    if (status == NOTIFY_STATUS_OK) {
-        s_cachedUTCOffset = calculateUTCOffset();
-        s_haveCachedUTCOffset = true;
-    }
-#endif
-}
-
-static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second)
-{
-    double days = (day - 32075)
-        + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4)
-        + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12
-        - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4)
-        - 2440588;
-    return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMinute + second;
-}
-
-// We follow the recommendation of RFC 2822 to consider all
-// obsolete time zones not listed here equivalent to "-0000".
-static const struct KnownZone {
-#if !PLATFORM(WIN_OS)
-    const
-#endif
-        char tzName[4];
-    int tzOffset;
-} known_zones[] = {
-    { "UT", 0 },
-    { "GMT", 0 },
-    { "EST", -300 },
-    { "EDT", -240 },
-    { "CST", -360 },
-    { "CDT", -300 },
-    { "MST", -420 },
-    { "MDT", -360 },
-    { "PST", -480 },
-    { "PDT", -420 }
-};
-
-inline static void skipSpacesAndComments(const char*& s)
-{
-    int nesting = 0;
-    char ch;
-    while ((ch = *s)) {
-        if (!isASCIISpace(ch)) {
-            if (ch == '(')
-                nesting++;
-            else if (ch == ')' && nesting > 0)
-                nesting--;
-            else if (nesting == 0)
-                break;
-        }
-        s++;
-    }
-}
-
-// returns 0-11 (Jan-Dec); -1 on failure
-static int findMonth(const char* monthStr)
-{
-    ASSERT(monthStr);
-    char needle[4];
-    for (int i = 0; i < 3; ++i) {
-        if (!*monthStr)
-            return -1;
-        needle[i] = static_cast<char>(toASCIILower(*monthStr++));
-    }
-    needle[3] = '\0';
-    const char *haystack = "janfebmaraprmayjunjulaugsepoctnovdec";
-    const char *str = strstr(haystack, needle);
-    if (str) {
-        int position = static_cast<int>(str - haystack);
-        if (position % 3 == 0)
-            return position / 3;
-    }
-    return -1;
-}
-
-static bool parseLong(const char* string, char** stopPosition, int base, long* result)
-{
-    *result = strtol(string, stopPosition, base);
-    // Avoid the use of errno as it is not available on Windows CE
-    if (string == *stopPosition || *result == LONG_MIN || *result == LONG_MAX)
-        return false;
-    return true;
-}
-
-double parseDate(const UString &date)
-{
-    // This parses a date in the form:
-    //     Tuesday, 09-Nov-99 23:12:40 GMT
-    // or
-    //     Sat, 01-Jan-2000 08:00:00 GMT
-    // or
-    //     Sat, 01 Jan 2000 08:00:00 GMT
-    // or
-    //     01 Jan 99 22:00 +0100    (exceptions in rfc822/rfc2822)
-    // ### non RFC formats, added for Javascript:
-    //     [Wednesday] January 09 1999 23:12:40 GMT
-    //     [Wednesday] January 09 23:12:40 GMT 1999
-    //
-    // We ignore the weekday.
-
-    CString dateCString = date.UTF8String();
-    const char *dateString = dateCString.c_str();
-     
-    // Skip leading space
-    skipSpacesAndComments(dateString);
-
-    long month = -1;
-    const char *wordStart = dateString;
-    // Check contents of first words if not number
-    while (*dateString && !isASCIIDigit(*dateString)) {
-        if (isASCIISpace(*dateString) || *dateString == '(') {
-            if (dateString - wordStart >= 3)
-                month = findMonth(wordStart);
-            skipSpacesAndComments(dateString);
-            wordStart = dateString;
-        } else
-           dateString++;
-    }
-
-    // Missing delimiter between month and day (like "January29")?
-    if (month == -1 && wordStart != dateString)
-        month = findMonth(wordStart);
-
-    skipSpacesAndComments(dateString);
-
-    if (!*dateString)
-        return NaN;
-
-    // ' 09-Nov-99 23:12:40 GMT'
-    char* newPosStr;
-    long day;
-    if (!parseLong(dateString, &newPosStr, 10, &day))
-        return NaN;
-    dateString = newPosStr;
-
-    if (!*dateString)
-        return NaN;
-
-    if (day < 0)
-        return NaN;
-
-    long year = 0;
-    if (day > 31) {
-        // ### where is the boundary and what happens below?
-        if (*dateString != '/')
-            return NaN;
-        // looks like a YYYY/MM/DD date
-        if (!*++dateString)
-            return NaN;
-        year = day;
-        if (!parseLong(dateString, &newPosStr, 10, &month))
-            return NaN;
-        month -= 1;
-        dateString = newPosStr;
-        if (*dateString++ != '/' || !*dateString)
-            return NaN;
-        if (!parseLong(dateString, &newPosStr, 10, &day))
-            return NaN;
-        dateString = newPosStr;
-    } else if (*dateString == '/' && month == -1) {
-        dateString++;
-        // This looks like a MM/DD/YYYY date, not an RFC date.
-        month = day - 1; // 0-based
-        if (!parseLong(dateString, &newPosStr, 10, &day))
-            return NaN;
-        if (day < 1 || day > 31)
-            return NaN;
-        dateString = newPosStr;
-        if (*dateString == '/')
-            dateString++;
-        if (!*dateString)
-            return NaN;
-     } else {
-        if (*dateString == '-')
-            dateString++;
-
-        skipSpacesAndComments(dateString);
-
-        if (*dateString == ',')
-            dateString++;
-
-        if (month == -1) { // not found yet
-            month = findMonth(dateString);
-            if (month == -1)
-                return NaN;
-
-            while (*dateString && *dateString != '-' && *dateString != ',' && !isASCIISpace(*dateString))
-                dateString++;
-
-            if (!*dateString)
-                return NaN;
-
-            // '-99 23:12:40 GMT'
-            if (*dateString != '-' && *dateString != '/' && *dateString != ',' && !isASCIISpace(*dateString))
-                return NaN;
-            dateString++;
-        }
-    }
-
-    if (month < 0 || month > 11)
-        return NaN;
-
-    // '99 23:12:40 GMT'
-    if (year <= 0 && *dateString) {
-        if (!parseLong(dateString, &newPosStr, 10, &year))
-            return NaN;
-    }
-    
-    // Don't fail if the time is missing.
-    long hour = 0;
-    long minute = 0;
-    long second = 0;
-    if (!*newPosStr)
-        dateString = newPosStr;
-    else {
-        // ' 23:12:40 GMT'
-        if (!(isASCIISpace(*newPosStr) || *newPosStr == ',')) {
-            if (*newPosStr != ':')
-                return NaN;
-            // There was no year; the number was the hour.
-            year = -1;
-        } else {
-            // in the normal case (we parsed the year), advance to the next number
-            dateString = ++newPosStr;
-            skipSpacesAndComments(dateString);
-        }
-
-        parseLong(dateString, &newPosStr, 10, &hour);
-        // Do not check for errno here since we want to continue
-        // even if errno was set becasue we are still looking
-        // for the timezone!
-
-        // Read a number? If not, this might be a timezone name.
-        if (newPosStr != dateString) {
-            dateString = newPosStr;
-
-            if (hour < 0 || hour > 23)
-                return NaN;
-
-            if (!*dateString)
-                return NaN;
-
-            // ':12:40 GMT'
-            if (*dateString++ != ':')
-                return NaN;
-
-            if (!parseLong(dateString, &newPosStr, 10, &minute))
-                return NaN;
-            dateString = newPosStr;
-
-            if (minute < 0 || minute > 59)
-                return NaN;
-
-            // ':40 GMT'
-            if (*dateString && *dateString != ':' && !isASCIISpace(*dateString))
-                return NaN;
-
-            // seconds are optional in rfc822 + rfc2822
-            if (*dateString ==':') {
-                dateString++;
-
-                if (!parseLong(dateString, &newPosStr, 10, &second))
-                    return NaN;
-                dateString = newPosStr;
-            
-                if (second < 0 || second > 59)
-                    return NaN;
-            }
-
-            skipSpacesAndComments(dateString);
-
-            if (strncasecmp(dateString, "AM", 2) == 0) {
-                if (hour > 12)
-                    return NaN;
-                if (hour == 12)
-                    hour = 0;
-                dateString += 2;
-                skipSpacesAndComments(dateString);
-            } else if (strncasecmp(dateString, "PM", 2) == 0) {
-                if (hour > 12)
-                    return NaN;
-                if (hour != 12)
-                    hour += 12;
-                dateString += 2;
-                skipSpacesAndComments(dateString);
-            }
-        }
-    }
-
-    bool haveTZ = false;
-    int offset = 0;
-
-    // Don't fail if the time zone is missing. 
-    // Some websites omit the time zone (4275206).
-    if (*dateString) {
-        if (strncasecmp(dateString, "GMT", 3) == 0 || strncasecmp(dateString, "UTC", 3) == 0) {
-            dateString += 3;
-            haveTZ = true;
-        }
-
-        if (*dateString == '+' || *dateString == '-') {
-            long o;
-            if (!parseLong(dateString, &newPosStr, 10, &o))
-                return NaN;
-            dateString = newPosStr;
-
-            if (o < -9959 || o > 9959)
-                return NaN;
-
-            int sgn = (o < 0) ? -1 : 1;
-            o = abs(o);
-            if (*dateString != ':') {
-                offset = ((o / 100) * 60 + (o % 100)) * sgn;
-            } else { // GMT+05:00
-                long o2;
-                if (!parseLong(dateString, &newPosStr, 10, &o2))
-                    return NaN;
-                dateString = newPosStr;
-                offset = (o * 60 + o2) * sgn;
-            }
-            haveTZ = true;
-        } else {
-            for (int i = 0; i < int(sizeof(known_zones) / sizeof(KnownZone)); i++) {
-                if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
-                    offset = known_zones[i].tzOffset;
-                    dateString += strlen(known_zones[i].tzName);
-                    haveTZ = true;
-                    break;
-                }
-            }
-        }
-    }
-
-    skipSpacesAndComments(dateString);
-
-    if (*dateString && year == -1) {
-        if (!parseLong(dateString, &newPosStr, 10, &year))
-            return NaN;
-        dateString = newPosStr;
-    }
-     
-    skipSpacesAndComments(dateString);
-     
-    // Trailing garbage
-    if (*dateString)
-        return NaN;
-
-    // Y2K: Handle 2 digit years.
-    if (year >= 0 && year < 100) {
-        if (year < 50)
-            year += 2000;
-        else
-            year += 1900;
-    }
-
-    // fall back to local timezone
-    if (!haveTZ) {
-        GregorianDateTime t;
-        t.monthDay = day;
-        t.month = month;
-        t.year = year - 1900;
-        t.isDST = -1;
-        t.second = second;
-        t.minute = minute;
-        t.hour = hour;
-
-        // Use our gregorianDateTimeToMS() rather than mktime() as the latter can't handle the full year range.
-        return gregorianDateTimeToMS(t, 0, false);
-    }
-
-    return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond;
-}
-
-double timeClip(double t)
-{
-    if (!isfinite(t))
-        return NaN;
-    if (fabs(t) > 8.64E15)
-        return NaN;
-    return trunc(t);
-}
-
-UString formatDate(const GregorianDateTime &t)
-{
-    char buffer[100];
-    snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",
-        weekdayName[(t.weekDay + 6) % 7],
-        monthName[t.month], t.monthDay, t.year + 1900);
-    return buffer;
-}
-
-UString formatDateUTCVariant(const GregorianDateTime &t)
-{
-    char buffer[100];
-    snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",
-        weekdayName[(t.weekDay + 6) % 7],
-        t.monthDay, monthName[t.month], t.year + 1900);
-    return buffer;
-}
-
-UString formatTime(const GregorianDateTime &t, bool utc)
-{
-    char buffer[100];
-    if (utc) {
-        snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
-    } else {
-        int offset = abs(gmtoffset(t));
-        char tzname[70];
-        struct tm gtm = t;
-        strftime(tzname, sizeof(tzname), "%Z", &gtm);
-
-        if (tzname[0]) {
-            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
-                t.hour, t.minute, t.second,
-                gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, tzname);
-        } else {
-            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
-                t.hour, t.minute, t.second,
-                gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
-        }
-    }
-    return UString(buffer);
-}
-
-} // namespace JSC
diff --git a/runtime/DateMath.h b/runtime/DateMath.h
deleted file mode 100644 (file)
index 8a15c80..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- */
-
-#ifndef DateMath_h
-#define DateMath_h
-
-#include <time.h>
-#include <string.h>
-#include <wtf/Noncopyable.h>
-
-namespace JSC {
-
-class UString;
-struct GregorianDateTime;
-
-void initDateMath();
-void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&);
-double gregorianDateTimeToMS(const GregorianDateTime&, double, bool inputIsUTC);
-double getUTCOffset();
-int equivalentYearForDST(int year);
-double getCurrentUTCTime();
-double getCurrentUTCTimeWithMicroseconds();
-void getLocalTime(const time_t*, tm*);
-
-// Not really math related, but this is currently the only shared place to put these.  
-double parseDate(const UString&);
-double timeClip(double);
-UString formatDate(const GregorianDateTime&);
-UString formatDateUTCVariant(const GregorianDateTime&);
-UString formatTime(const GregorianDateTime&, bool inputIsUTC);
-
-
-const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
-const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-const double hoursPerDay = 24.0;
-const double minutesPerHour = 60.0;
-const double secondsPerHour = 60.0 * 60.0;
-const double secondsPerMinute = 60.0;
-const double msPerSecond = 1000.0;
-const double msPerMinute = 60.0 * 1000.0;
-const double msPerHour = 60.0 * 60.0 * 1000.0;
-const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0;
-
-// Intentionally overridding the default tm of the system
-// Tee members of tm differ on various operating systems.
-struct GregorianDateTime : Noncopyable {
-    GregorianDateTime()
-        : second(0)
-        , minute(0)
-        , hour(0)
-        , weekDay(0)
-        , monthDay(0)
-        , yearDay(0)
-        , month(0)
-        , year(0)
-        , isDST(0)
-        , utcOffset(0)
-        , timeZone(0)
-    {
-    }
-
-    ~GregorianDateTime()
-    {
-        delete [] timeZone;
-    }
-
-    GregorianDateTime(const tm& inTm)
-        : second(inTm.tm_sec)
-        , minute(inTm.tm_min)
-        , hour(inTm.tm_hour)
-        , weekDay(inTm.tm_wday)
-        , monthDay(inTm.tm_mday)
-        , yearDay(inTm.tm_yday)
-        , month(inTm.tm_mon)
-        , year(inTm.tm_year)
-        , isDST(inTm.tm_isdst)
-    {
-#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT)
-        utcOffset = static_cast<int>(inTm.tm_gmtoff);
-
-        int inZoneSize = strlen(inTm.tm_zone) + 1;
-        timeZone = new char[inZoneSize];
-        strncpy(timeZone, inTm.tm_zone, inZoneSize);
-#else
-        utcOffset = static_cast<int>(getUTCOffset() / msPerSecond + (isDST ? secondsPerHour : 0));
-        timeZone = 0;
-#endif
-    }
-
-    operator tm() const
-    {
-        tm ret;
-        memset(&ret, 0, sizeof(ret));
-
-        ret.tm_sec   =  second;
-        ret.tm_min   =  minute;
-        ret.tm_hour  =  hour;
-        ret.tm_wday  =  weekDay;
-        ret.tm_mday  =  monthDay;
-        ret.tm_yday  =  yearDay;
-        ret.tm_mon   =  month;
-        ret.tm_year  =  year;
-        ret.tm_isdst =  isDST;
-
-#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT)
-        ret.tm_gmtoff = static_cast<long>(utcOffset);
-        ret.tm_zone = timeZone;
-#endif
-
-        return ret;
-    }
-
-    void copyFrom(const GregorianDateTime& rhs)
-    {
-        second = rhs.second;
-        minute = rhs.minute;
-        hour = rhs.hour;
-        weekDay = rhs.weekDay;
-        monthDay = rhs.monthDay;
-        yearDay = rhs.yearDay;
-        month = rhs.month;
-        year = rhs.year;
-        isDST = rhs.isDST;
-        utcOffset = rhs.utcOffset;
-        if (rhs.timeZone) {
-            int inZoneSize = strlen(rhs.timeZone) + 1;
-            timeZone = new char[inZoneSize];
-            strncpy(timeZone, rhs.timeZone, inZoneSize);
-        } else
-            timeZone = 0;
-    }
-
-    int second;
-    int minute;
-    int hour;
-    int weekDay;
-    int monthDay;
-    int yearDay;
-    int month;
-    int year;
-    int isDST;
-    int utcOffset;
-    char* timeZone;
-};
-
-static inline int gmtoffset(const GregorianDateTime& t)
-{
-    return t.utcOffset;
-}
-
-} // namespace JSC
-
-#endif // DateMath_h
index 8535bbcf2c166f1b4b8a2c861c8e39492218db00..ce7df28c35832210762a59b47b817b9bd7117196 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2008, 2009 Torch Mobile, 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
 #include "config.h"
 #include "DatePrototype.h"
 
-#include "DateMath.h"
+#include "DateConversion.h"
+#include "Error.h"
 #include "JSString.h"
 #include "ObjectPrototype.h"
 #include "DateInstance.h"
 #include <float.h>
+
+#if !PLATFORM(MAC) && HAVE(LANGINFO_H)
+#include <langinfo.h>
+#endif
+
 #include <limits.h>
 #include <locale.h>
 #include <math.h>
 #include <time.h>
 #include <wtf/Assertions.h>
+#include <wtf/DateMath.h>
 #include <wtf/MathExtras.h>
 #include <wtf/StringExtras.h>
 #include <wtf/UnusedParam.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 
+#if PLATFORM(WINCE) && !PLATFORM(QT)
+extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); //provided by libce
+#endif
+
 using namespace WTF;
 
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(DatePrototype);
 
-static JSValuePtr dateProtoFuncGetDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetDay(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetMilliSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetTime(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetTimezoneOffset(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCDay(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCMilliseconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetUTCSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncGetYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetMilliSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetTime(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCDate(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCFullYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCHours(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCMilliseconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCMinutes(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCMonth(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetUTCSeconds(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncSetYear(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToDateString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToGMTString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToLocaleDateString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToLocaleTimeString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToTimeString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr dateProtoFuncToUTCString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState*, JSObject*, JSValue, const ArgList&);
+
+static JSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState*, JSObject*, JSValue, const ArgList&);
 
 }
 
@@ -133,16 +148,16 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMil
     bool useCustomFormat = false;
     UString customFormatString;
 
-    UString arg0String = args.at(exec, 0).toString(exec);
-    if (arg0String == "custom" && !args.at(exec, 1).isUndefined()) {
+    UString arg0String = args.at(0).toString(exec);
+    if (arg0String == "custom" && !args.at(1).isUndefined()) {
         useCustomFormat = true;
-        customFormatString = args.at(exec, 1).toString(exec);
-    } else if (format == LocaleDateAndTime && !args.at(exec, 1).isUndefined()) {
+        customFormatString = args.at(1).toString(exec);
+    } else if (format == LocaleDateAndTime && !args.at(1).isUndefined()) {
         dateStyle = styleFromArgString(arg0String, dateStyle);
-        timeStyle = styleFromArgString(args.at(exec, 1).toString(exec), timeStyle);
-    } else if (format != LocaleTime && !args.at(exec, 0).isUndefined())
+        timeStyle = styleFromArgString(args.at(1).toString(exec), timeStyle);
+    } else if (format != LocaleTime && !args.at(0).isUndefined())
         dateStyle = styleFromArgString(arg0String, dateStyle);
-    else if (format != LocaleDate && !args.at(exec, 0).isUndefined())
+    else if (format != LocaleDate && !args.at(0).isUndefined())
         timeStyle = styleFromArgString(arg0String, timeStyle);
 
     CFLocaleRef locale = CFLocaleCopyCurrent();
@@ -193,19 +208,19 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, const ArgList& args, in
     // hours
     if (maxArgs >= 4 && idx < numArgs) {
         t->hour = 0;
-        milliseconds += args.at(exec, idx++).toInt32(exec, ok) * msPerHour;
+        milliseconds += args.at(idx++).toInt32(exec, ok) * msPerHour;
     }
 
     // minutes
     if (maxArgs >= 3 && idx < numArgs && ok) {
         t->minute = 0;
-        milliseconds += args.at(exec, idx++).toInt32(exec, ok) * msPerMinute;
+        milliseconds += args.at(idx++).toInt32(exec, ok) * msPerMinute;
     }
     
     // seconds
     if (maxArgs >= 2 && idx < numArgs && ok) {
         t->second = 0;
-        milliseconds += args.at(exec, idx++).toInt32(exec, ok) * msPerSecond;
+        milliseconds += args.at(idx++).toInt32(exec, ok) * msPerSecond;
     }
     
     if (!ok)
@@ -213,7 +228,7 @@ static bool fillStructuresUsingTimeArgs(ExecState* exec, const ArgList& args, in
         
     // milliseconds
     if (idx < numArgs) {
-        double millis = args.at(exec, idx).toNumber(exec);
+        double millis = args.at(idx).toNumber(exec);
         ok = isfinite(millis);
         milliseconds += millis;
     } else
@@ -239,16 +254,16 @@ static bool fillStructuresUsingDateArgs(ExecState *exec, const ArgList& args, in
   
     // years
     if (maxArgs >= 3 && idx < numArgs)
-        t->year = args.at(exec, idx++).toInt32(exec, ok) - 1900;
+        t->year = args.at(idx++).toInt32(exec, ok) - 1900;
     
     // months
     if (maxArgs >= 2 && idx < numArgs && ok)   
-        t->month = args.at(exec, idx++).toInt32(exec, ok);
+        t->month = args.at(idx++).toInt32(exec, ok);
     
     // days
     if (idx < numArgs && ok) {   
         t->monthDay = 0;
-        *ms += args.at(exec, idx).toInt32(exec, ok) * msPerDay;
+        *ms += args.at(idx).toInt32(exec, ok) * msPerDay;
     }
     
     return ok;
@@ -259,6 +274,7 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState
 /* Source for DatePrototype.lut.h
 @begin dateTable
   toString              dateProtoFuncToString                DontEnum|Function       0
+  toISOString           dateProtoFuncToISOString             DontEnum|Function       0
   toUTCString           dateProtoFuncToUTCString             DontEnum|Function       0
   toDateString          dateProtoFuncToDateString            DontEnum|Function       0
   toTimeString          dateProtoFuncToTimeString            DontEnum|Function       0
@@ -302,6 +318,7 @@ const ClassInfo DatePrototype::info = {"Date", &DateInstance::info, 0, ExecState
   setUTCFullYear        dateProtoFuncSetUTCFullYear          DontEnum|Function       3
   setYear               dateProtoFuncSetYear                 DontEnum|Function       1
   getYear               dateProtoFuncGetYear                 DontEnum|Function       0
+  toJSON                dateProtoFuncToJSON                  DontEnum|Function       0
 @end
 */
 
@@ -321,7 +338,7 @@ bool DatePrototype::getOwnPropertySlot(ExecState* exec, const Identifier& proper
 
 // Functions
 
-JSValuePtr dateProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -338,7 +355,7 @@ JSValuePtr dateProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValu
     return jsNontrivialString(exec, formatDate(t) + " " + formatTime(t, utc));
 }
 
-JSValuePtr dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -355,7 +372,29 @@ JSValuePtr dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValuePtr thisV
     return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
 }
 
-JSValuePtr dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+    if (!thisValue.isObject(&DateInstance::info))
+        return throwError(exec, TypeError);
+    
+    const bool utc = true;
+    
+    DateInstance* thisDateObj = asDateInstance(thisValue); 
+    double milli = thisDateObj->internalNumber();
+    if (!isfinite(milli))
+        return jsNontrivialString(exec, "Invalid Date");
+    
+    GregorianDateTime t;
+    thisDateObj->msToGregorianDateTime(milli, utc, t);
+    // Maximum amount of space we need in buffer: 6 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second)
+    // 6 for formatting and one for null termination = 23.  We add one extra character to allow us to force null termination.
+    char buffer[24];
+    snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02dZ", 1900 + t.year, t.month + 1, t.monthDay, t.hour, t.minute, t.second);
+    buffer[sizeof(buffer) - 1] = 0;
+    return jsNontrivialString(exec, buffer);
+}
+
+JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -372,7 +411,7 @@ JSValuePtr dateProtoFuncToDateString(ExecState* exec, JSObject*, JSValuePtr this
     return jsNontrivialString(exec, formatDate(t));
 }
 
-JSValuePtr dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -389,7 +428,7 @@ JSValuePtr dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValuePtr this
     return jsNontrivialString(exec, formatTime(t, utc));
 }
 
-JSValuePtr dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -402,7 +441,7 @@ JSValuePtr dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr th
     return formatLocaleDate(exec, thisDateObj, milli, LocaleDateAndTime, args);
 }
 
-JSValuePtr dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -415,7 +454,7 @@ JSValuePtr dateProtoFuncToLocaleDateString(ExecState* exec, JSObject*, JSValuePt
     return formatLocaleDate(exec, thisDateObj, milli, LocaleDate, args);
 }
 
-JSValuePtr dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -428,7 +467,7 @@ JSValuePtr dateProtoFuncToLocaleTimeString(ExecState* exec, JSObject*, JSValuePt
     return formatLocaleDate(exec, thisDateObj, milli, LocaleTime, args);
 }
 
-JSValuePtr dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -441,7 +480,7 @@ JSValuePtr dateProtoFuncGetTime(ExecState* exec, JSObject*, JSValuePtr thisValue
     return jsNumber(exec, milli);
 }
 
-JSValuePtr dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -458,7 +497,7 @@ JSValuePtr dateProtoFuncGetFullYear(ExecState* exec, JSObject*, JSValuePtr thisV
     return jsNumber(exec, 1900 + t.year);
 }
 
-JSValuePtr dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -475,7 +514,7 @@ JSValuePtr dateProtoFuncGetUTCFullYear(ExecState* exec, JSObject*, JSValuePtr th
     return jsNumber(exec, 1900 + t.year);
 }
 
-JSValuePtr dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -492,7 +531,7 @@ JSValuePtr dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSValuePtr thisV
     return jsNontrivialString(exec, formatDateUTCVariant(t) + " " + formatTime(t, utc));
 }
 
-JSValuePtr dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -509,7 +548,7 @@ JSValuePtr dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValuePtr thisValu
     return jsNumber(exec, t.month);
 }
 
-JSValuePtr dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -526,7 +565,7 @@ JSValuePtr dateProtoFuncGetUTCMonth(ExecState* exec, JSObject*, JSValuePtr thisV
     return jsNumber(exec, t.month);
 }
 
-JSValuePtr dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -543,7 +582,7 @@ JSValuePtr dateProtoFuncGetDate(ExecState* exec, JSObject*, JSValuePtr thisValue
     return jsNumber(exec, t.monthDay);
 }
 
-JSValuePtr dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -560,7 +599,7 @@ JSValuePtr dateProtoFuncGetUTCDate(ExecState* exec, JSObject*, JSValuePtr thisVa
     return jsNumber(exec, t.monthDay);
 }
 
-JSValuePtr dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -577,7 +616,7 @@ JSValuePtr dateProtoFuncGetDay(ExecState* exec, JSObject*, JSValuePtr thisValue,
     return jsNumber(exec, t.weekDay);
 }
 
-JSValuePtr dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -594,7 +633,7 @@ JSValuePtr dateProtoFuncGetUTCDay(ExecState* exec, JSObject*, JSValuePtr thisVal
     return jsNumber(exec, t.weekDay);
 }
 
-JSValuePtr dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -611,7 +650,7 @@ JSValuePtr dateProtoFuncGetHours(ExecState* exec, JSObject*, JSValuePtr thisValu
     return jsNumber(exec, t.hour);
 }
 
-JSValuePtr dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -628,7 +667,7 @@ JSValuePtr dateProtoFuncGetUTCHours(ExecState* exec, JSObject*, JSValuePtr thisV
     return jsNumber(exec, t.hour);
 }
 
-JSValuePtr dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -645,7 +684,7 @@ JSValuePtr dateProtoFuncGetMinutes(ExecState* exec, JSObject*, JSValuePtr thisVa
     return jsNumber(exec, t.minute);
 }
 
-JSValuePtr dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -662,7 +701,7 @@ JSValuePtr dateProtoFuncGetUTCMinutes(ExecState* exec, JSObject*, JSValuePtr thi
     return jsNumber(exec, t.minute);
 }
 
-JSValuePtr dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -679,7 +718,7 @@ JSValuePtr dateProtoFuncGetSeconds(ExecState* exec, JSObject*, JSValuePtr thisVa
     return jsNumber(exec, t.second);
 }
 
-JSValuePtr dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -696,7 +735,7 @@ JSValuePtr dateProtoFuncGetUTCSeconds(ExecState* exec, JSObject*, JSValuePtr thi
     return jsNumber(exec, t.second);
 }
 
-JSValuePtr dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -711,7 +750,7 @@ JSValuePtr dateProtoFuncGetMilliSeconds(ExecState* exec, JSObject*, JSValuePtr t
     return jsNumber(exec, ms);
 }
 
-JSValuePtr dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -726,7 +765,7 @@ JSValuePtr dateProtoFuncGetUTCMilliseconds(ExecState* exec, JSObject*, JSValuePt
     return jsNumber(exec, ms);
 }
 
-JSValuePtr dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -743,20 +782,20 @@ JSValuePtr dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValuePtr
     return jsNumber(exec, -gmtoffset(t) / minutesPerHour);
 }
 
-JSValuePtr dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetTime(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     DateInstance* thisDateObj = asDateInstance(thisValue); 
 
-    double milli = timeClip(args.at(exec, 0).toNumber(exec));
-    JSValuePtr result = jsNumber(exec, milli);
+    double milli = timeClip(args.at(0).toNumber(exec));
+    JSValue result = jsNumber(exec, milli);
     thisDateObj->setInternalValue(result);
     return result;
 }
 
-static JSValuePtr setNewValueFromTimeArgs(ExecState* exec, JSValuePtr thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+static JSValue setNewValueFromTimeArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -765,7 +804,7 @@ static JSValuePtr setNewValueFromTimeArgs(ExecState* exec, JSValuePtr thisValue,
     double milli = thisDateObj->internalNumber();
     
     if (args.isEmpty() || isnan(milli)) {
-        JSValuePtr result = jsNaN(exec);
+        JSValue result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }
@@ -777,24 +816,24 @@ static JSValuePtr setNewValueFromTimeArgs(ExecState* exec, JSValuePtr thisValue,
     thisDateObj->msToGregorianDateTime(milli, inputIsUTC, t);
 
     if (!fillStructuresUsingTimeArgs(exec, args, numArgsToUse, &ms, &t)) {
-        JSValuePtr result = jsNaN(exec);
+        JSValue result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     } 
     
-    JSValuePtr result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+    JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
     thisDateObj->setInternalValue(result);
     return result;
 }
 
-static JSValuePtr setNewValueFromDateArgs(ExecState* exec, JSValuePtr thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
+static JSValue setNewValueFromDateArgs(ExecState* exec, JSValue thisValue, const ArgList& args, int numArgsToUse, bool inputIsUTC)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
 
     DateInstance* thisDateObj = asDateInstance(thisValue);
     if (args.isEmpty()) {
-        JSValuePtr result = jsNaN(exec);
+        JSValue result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }      
@@ -814,101 +853,101 @@ static JSValuePtr setNewValueFromDateArgs(ExecState* exec, JSValuePtr thisValue,
     }
     
     if (!fillStructuresUsingDateArgs(exec, args, numArgsToUse, &ms, &t)) {
-        JSValuePtr result = jsNaN(exec);
+        JSValue result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     } 
            
-    JSValuePtr result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
+    JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, inputIsUTC));
     thisDateObj->setInternalValue(result);
     return result;
 }
 
-JSValuePtr dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetMilliSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
     return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCMilliseconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
     return setNewValueFromTimeArgs(exec, thisValue, args, 1, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
     return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCSeconds(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
     return setNewValueFromTimeArgs(exec, thisValue, args, 2, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
     return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCMinutes(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
     return setNewValueFromTimeArgs(exec, thisValue, args, 3, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
     return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetUTCHours(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCHours(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
     return setNewValueFromTimeArgs(exec, thisValue, args, 4, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
     return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetUTCDate(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCDate(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
     return setNewValueFromDateArgs(exec, thisValue, args, 1, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
     return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetUTCMonth(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
     return setNewValueFromDateArgs(exec, thisValue, args, 2, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = false;
     return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetUTCFullYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     const bool inputIsUTC = true;
     return setNewValueFromDateArgs(exec, thisValue, args, 3, inputIsUTC);
 }
 
-JSValuePtr dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -917,7 +956,7 @@ JSValuePtr dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValuePtr thisValue
 
     DateInstance* thisDateObj = asDateInstance(thisValue);     
     if (args.isEmpty()) { 
-        JSValuePtr result = jsNaN(exec);
+        JSValue result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }
@@ -937,20 +976,20 @@ JSValuePtr dateProtoFuncSetYear(ExecState* exec, JSObject*, JSValuePtr thisValue
     }
     
     bool ok = true;
-    int32_t year = args.at(exec, 0).toInt32(exec, ok);
+    int32_t year = args.at(0).toInt32(exec, ok);
     if (!ok) {
-        JSValuePtr result = jsNaN(exec);
+        JSValue result = jsNaN(exec);
         thisDateObj->setInternalValue(result);
         return result;
     }
             
     t.year = (year > 99 || year < 0) ? year - 1900 : year;
-    JSValuePtr result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
+    JSValue result = jsNumber(exec, gregorianDateTimeToMS(t, ms, utc));
     thisDateObj->setInternalValue(result);
     return result;
 }
 
-JSValuePtr dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&DateInstance::info))
         return throwError(exec, TypeError);
@@ -969,4 +1008,27 @@ JSValuePtr dateProtoFuncGetYear(ExecState* exec, JSObject*, JSValuePtr thisValue
     return jsNumber(exec, t.year);
 }
 
+JSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
+{
+    JSObject* object = thisValue.toThisObject(exec);
+    if (exec->hadException())
+        return jsNull();
+    
+    JSValue toISOValue = object->get(exec, exec->globalData().propertyNames->toISOString);
+    if (exec->hadException())
+        return jsNull();
+
+    CallData callData;
+    CallType callType = toISOValue.getCallData(callData);
+    if (callType == CallTypeNone)
+        return throwError(exec, TypeError, "toISOString is not a function");
+
+    JSValue result = call(exec, asObject(toISOValue), callType, callData, object, exec->emptyList());
+    if (exec->hadException())
+        return jsNull();
+    if (result.isObject())
+        return throwError(exec, TypeError, "toISOString did not return a primitive value");
+    return result;
+}
+
 } // namespace JSC
index a6bbdf28813f6b85327b83973fcf6bf9425da43d..5f4d0ec43da2cda5fcb46235d46997dd3b706933 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC {
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
             return Structure::create(prototype, TypeInfo(ObjectType));
         }
index 5e21c8e56e54244104e7b81afde67bd27ccff6e1..db1d8ccb0b60a26c44da665cf13efa2bcdc0f322 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "ConstructData.h"
 #include "ErrorConstructor.h"
+#include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSObject.h"
 #include "JSString.h"
@@ -72,7 +73,7 @@ JSObject* Error::create(ExecState* exec, ErrorType type, const UString& message,
             break;
     }
 
-    ArgList args;
+    MarkedArgumentBuffer args;
     if (message.isEmpty())
         args.append(jsString(exec, name));
     else
index 5cc0df0fff93badf2e7de5cf40cac45feafb8065..07b7e233814977111018ec8cb95e7b48993e9e6b 100644 (file)
@@ -41,8 +41,8 @@ ErrorConstructor::ErrorConstructor(ExecState* exec, PassRefPtr<Structure> struct
 ErrorInstance* constructError(ExecState* exec, const ArgList& args)
 {
     ErrorInstance* obj = new (exec) ErrorInstance(exec->lexicalGlobalObject()->errorStructure());
-    if (!args.at(exec, 0).isUndefined())
-        obj->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0).toString(exec)));
+    if (!args.at(0).isUndefined())
+        obj->putDirect(exec->propertyNames().message, jsString(exec, args.at(0).toString(exec)));
     return obj;
 }
 
@@ -58,7 +58,7 @@ ConstructType ErrorConstructor::getConstructData(ConstructData& constructData)
 }
 
 // ECMA 15.9.2
-static JSValuePtr callErrorConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callErrorConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     // "Error()" gives the sames result as "new Error()"
     return constructError(exec, args);
index 8703d81bf8b3672cbbcd0792fcb8fbf481d2304b..599390ee92f280c564786993d52e4e7ac0065cf8 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "ErrorPrototype.h"
 
+#include "JSFunction.h"
 #include "JSString.h"
 #include "ObjectPrototype.h"
 #include "PrototypeFunction.h"
@@ -30,7 +31,7 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
 
-static JSValuePtr errorProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
 
 // ECMA 15.9.4
 ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
@@ -41,16 +42,16 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, PassRefPtr<Structure> structure,
     putDirectWithoutTransition(exec->propertyNames().name, jsNontrivialString(exec, "Error"), DontEnum);
     putDirectWithoutTransition(exec->propertyNames().message, jsNontrivialString(exec, "Unknown error"), DontEnum);
 
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, errorProtoFuncToString), DontEnum);
 }
 
-JSValuePtr errorProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
     UString s = "Error";
 
-    JSValuePtr v = thisObj->get(exec, exec->propertyNames().name);
+    JSValue v = thisObj->get(exec, exec->propertyNames().name);
     if (!v.isUndefined())
         s = v.toString(exec);
 
index 30f1503dfc4c6bf5134dc8ce6024f13132b901c2..e63594c032ca5436d5912b31aeb6dbc35a5365d3 100644 (file)
@@ -51,22 +51,22 @@ public:
     virtual UString toString(ExecState*) const { return "JavaScript execution exceeded timeout."; }
 };
 
-JSValuePtr createInterruptedExecutionException(JSGlobalData* globalData)
+JSValue createInterruptedExecutionException(JSGlobalData* globalData)
 {
     return new (globalData) InterruptedExecutionError(globalData);
 }
 
-static JSValuePtr createError(ExecState* exec, ErrorType e, const char* msg)
+static JSValue createError(ExecState* exec, ErrorType e, const char* msg)
 {
     return Error::create(exec, e, msg, -1, -1, 0);
 }
 
-JSValuePtr createStackOverflowError(ExecState* exec)
+JSValue createStackOverflowError(ExecState* exec)
 {
     return createError(exec, RangeError, "Maximum call stack size exceeded.");
 }
 
-JSValuePtr createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock)
+JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock)
 {
     int startOffset = 0;
     int endOffset = 0;
@@ -81,7 +81,7 @@ JSValuePtr createUndefinedVariableError(ExecState* exec, const Identifier& ident
     return exception;
 }
     
-static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValuePtr value, UString error)
+static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue value, UString error)
 {
     if (!expressionStop || expressionStart > codeBlock->source()->length()) {
         UString errorText = value.toString(exec);
@@ -125,7 +125,7 @@ static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, in
     return errorText;
 }
 
-JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValuePtr value, unsigned bytecodeOffset, CodeBlock* codeBlock)
+JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
 {
     UString message = "not a valid argument for '";
     message.append(op);
@@ -143,7 +143,7 @@ JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValuePtr va
     return exception;
 }
 
-JSObject* createNotAConstructorError(ExecState* exec, JSValuePtr value, unsigned bytecodeOffset, CodeBlock* codeBlock)
+JSObject* createNotAConstructorError(ExecState* exec, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
 {
     int startOffset = 0;
     int endOffset = 0;
@@ -164,7 +164,7 @@ JSObject* createNotAConstructorError(ExecState* exec, JSValuePtr value, unsigned
     return exception;
 }
 
-JSValuePtr createNotAFunctionError(ExecState* exec, JSValuePtr value, unsigned bytecodeOffset, CodeBlock* codeBlock)
+JSValue createNotAFunctionError(ExecState* exec, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
 {
     int startOffset = 0;
     int endOffset = 0;
index d4dfdd865fcf219f6f71d61f4a5784fe1f8c4713..93629dc5991a33a20d217b8164c799e842a4859c 100644 (file)
@@ -29,7 +29,6 @@
 #ifndef ExceptionHelpers_h
 #define ExceptionHelpers_h
 
-#include "JSImmediate.h"
 
 namespace JSC {
 
@@ -40,16 +39,16 @@ namespace JSC {
     class JSGlobalData;
     class JSNotAnObjectErrorStub;
     class JSObject;
-    class JSValuePtr;
+    class JSValue;
     class Node;
 
-    JSValuePtr createInterruptedExecutionException(JSGlobalData*);
-    JSValuePtr createStackOverflowError(ExecState*);
-    JSValuePtr createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*);
+    JSValue createInterruptedExecutionException(JSGlobalData*);
+    JSValue createStackOverflowError(ExecState*);
+    JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*);
     JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState*, bool isNull);
-    JSObject* createInvalidParamError(ExecState*, const char* op, JSValuePtr, unsigned bytecodeOffset, CodeBlock*);
-    JSObject* createNotAConstructorError(ExecState*, JSValuePtr, unsigned bytecodeOffset, CodeBlock*);
-    JSValuePtr createNotAFunctionError(ExecState*, JSValuePtr, unsigned bytecodeOffset, CodeBlock*);
+    JSObject* createInvalidParamError(ExecState*, const char* op, JSValue, unsigned bytecodeOffset, CodeBlock*);
+    JSObject* createNotAConstructorError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
+    JSValue createNotAFunctionError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
     JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, unsigned bytecodeOffset, CodeBlock*);
 
 } // namespace JSC
index ff77b9d19dd4725e39ae3f68ef598e210d55083d..f4f5cc8e611570048bf68dc4eeffcfbb01885e6a 100644 (file)
@@ -54,7 +54,7 @@ ConstructType FunctionConstructor::getConstructData(ConstructData& constructData
     return ConstructTypeHost;
 }
 
-static JSValuePtr callFunctionConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callFunctionConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     return constructFunction(exec, args);
 }
@@ -75,17 +75,19 @@ FunctionBodyNode* extractFunctionBody(ProgramNode* program)
     if (children.size() != 1)
         return 0;
 
-    ExprStatementNode* exprStatement = static_cast<ExprStatementNode*>(children[0].get()); 
+    StatementNode* exprStatement = children[0];
+    ASSERT(exprStatement);
     ASSERT(exprStatement->isExprStatement());
     if (!exprStatement || !exprStatement->isExprStatement())
         return 0;
 
-    FuncExprNode* funcExpr = static_cast<FuncExprNode*>(exprStatement->expr());
+    ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
+    ASSERT(funcExpr);
     ASSERT(funcExpr->isFuncExprNode());
     if (!funcExpr || !funcExpr->isFuncExprNode())
         return 0;
 
-    FunctionBodyNode* body = funcExpr->body();
+    FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
     ASSERT(body);
     return body;
 }
@@ -100,12 +102,12 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
     if (args.isEmpty())
         program = "(function() { \n})";
     else if (args.size() == 1)
-        program = "(function() { " + args.at(exec, 0).toString(exec) + "\n})";
+        program = "(function() { " + args.at(0).toString(exec) + "\n})";
     else {
-        program = "(function(" + args.at(exec, 0).toString(exec);
+        program = "(function(" + args.at(0).toString(exec);
         for (size_t i = 1; i < args.size() - 1; i++)
-            program += "," + args.at(exec, i).toString(exec);
-        program += ") { " + args.at(exec, args.size() - 1).toString(exec) + "\n})";
+            program += "," + args.at(i).toString(exec);
+        program += ") { " + args.at(args.size() - 1).toString(exec) + "\n})";
     }
 
     int errLine;
index 7be26856d704b998750ffe9a979962a727f1ab9b..9ba2144190571d9d789b796eeff47db1bd1be287 100644 (file)
 #include "JSFunction.h"
 #include "JSString.h"
 #include "Interpreter.h"
+#include "Lexer.h"
 #include "PrototypeFunction.h"
 
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(FunctionPrototype);
 
-static JSValuePtr functionProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionProtoFuncApply(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr functionProtoFuncCall(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionProtoFuncApply(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*, JSObject*, JSValue, const ArgList&);
 
 FunctionPrototype::FunctionPrototype(ExecState* exec, PassRefPtr<Structure> structure)
     : InternalFunction(&exec->globalData(), structure, exec->propertyNames().nullIdentifier)
@@ -42,14 +43,16 @@ FunctionPrototype::FunctionPrototype(ExecState* exec, PassRefPtr<Structure> stru
     putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
 }
 
-void FunctionPrototype::addFunctionProperties(ExecState* exec, Structure* prototypeFunctionStructure)
+void FunctionPrototype::addFunctionProperties(ExecState* exec, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction)
 {
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().apply, functionProtoFuncApply), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().call, functionProtoFuncCall), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, functionProtoFuncToString), DontEnum);
+    *applyFunction = new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().apply, functionProtoFuncApply);
+    putDirectFunctionWithoutTransition(exec, *applyFunction, DontEnum);
+    *callFunction = new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().call, functionProtoFuncCall);
+    putDirectFunctionWithoutTransition(exec, *callFunction, DontEnum);
 }
 
-static JSValuePtr callFunctionPrototype(ExecState*, JSObject*, JSValuePtr, const ArgList&)
+static JSValue JSC_HOST_CALL callFunctionPrototype(ExecState*, JSObject*, JSValue, const ArgList&)
 {
     return jsUndefined();
 }
@@ -63,11 +66,31 @@ CallType FunctionPrototype::getCallData(CallData& callData)
 
 // Functions
 
-JSValuePtr functionProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+// Compatibility hack for the Optimost JavaScript library. (See <rdar://problem/6595040>.)
+static inline void insertSemicolonIfNeeded(UString& functionBody)
+{
+    ASSERT(functionBody[0] == '{');
+    ASSERT(functionBody[functionBody.size() - 1] == '}');
+
+    for (size_t i = functionBody.size() - 2; i > 0; --i) {
+        UChar ch = functionBody[i];
+        if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) {
+            if (ch != ';' && ch != '}')
+                functionBody = functionBody.substr(0, i + 1) + ";" + functionBody.substr(i + 1, functionBody.size() - (i + 1));
+            return;
+        }
+    }
+}
+
+JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (thisValue.isObject(&JSFunction::info)) {
         JSFunction* function = asFunction(thisValue);
-        return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->body()->paramString() + ") " + function->body()->toSourceString());
+        if (!function->isHostFunction()) {
+            UString functionBody = function->body()->toSourceString();
+            insertSemicolonIfNeeded(functionBody);
+            return jsString(exec, "function " + function->name(&exec->globalData()) + "(" + function->body()->paramString() + ") " + functionBody);
+        }
     }
 
     if (thisValue.isObject(&InternalFunction::info)) {
@@ -78,59 +101,44 @@ JSValuePtr functionProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr this
     return throwError(exec, TypeError);
 }
 
-JSValuePtr functionProtoFuncApply(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL functionProtoFuncApply(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     CallData callData;
     CallType callType = thisValue.getCallData(callData);
     if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSValuePtr thisArg = args.at(exec, 0);
-    JSValuePtr argArray = args.at(exec, 1);
+    JSValue array = args.at(1);
 
-    JSValuePtr applyThis;
-    if (thisArg.isUndefinedOrNull())
-        applyThis = exec->globalThisValue();
-    else
-        applyThis = thisArg.toObject(exec);
-
-    ArgList applyArgs;
-    if (!argArray.isUndefinedOrNull()) {
-        if (!argArray.isObject())
+    MarkedArgumentBuffer applyArgs;
+    if (!array.isUndefinedOrNull()) {
+        if (!array.isObject())
             return throwError(exec, TypeError);
-        if (asObject(argArray)->classInfo() == &Arguments::info)
-            asArguments(argArray)->fillArgList(exec, applyArgs);
-        else if (exec->interpreter()->isJSArray(argArray))
-            asArray(argArray)->fillArgList(exec, applyArgs);
-        else if (asObject(argArray)->inherits(&JSArray::info)) {
-            unsigned length = asArray(argArray)->get(exec, exec->propertyNames().length).toUInt32(exec);
+        if (asObject(array)->classInfo() == &Arguments::info)
+            asArguments(array)->fillArgList(exec, applyArgs);
+        else if (isJSArray(&exec->globalData(), array))
+            asArray(array)->fillArgList(exec, applyArgs);
+        else if (asObject(array)->inherits(&JSArray::info)) {
+            unsigned length = asArray(array)->get(exec, exec->propertyNames().length).toUInt32(exec);
             for (unsigned i = 0; i < length; ++i)
-                applyArgs.append(asArray(argArray)->get(exec, i));
+                applyArgs.append(asArray(array)->get(exec, i));
         } else
             return throwError(exec, TypeError);
     }
 
-    return call(exec, thisValue, callType, callData, applyThis, applyArgs);
+    return call(exec, thisValue, callType, callData, args.at(0), applyArgs);
 }
 
-JSValuePtr functionProtoFuncCall(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL functionProtoFuncCall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     CallData callData;
     CallType callType = thisValue.getCallData(callData);
     if (callType == CallTypeNone)
         return throwError(exec, TypeError);
 
-    JSValuePtr thisArg = args.at(exec, 0);
-
-    JSObject* callThis;
-    if (thisArg.isUndefinedOrNull())
-        callThis = exec->globalThisValue();
-    else
-        callThis = thisArg.toObject(exec);
-
-    ArgList argsTail;
-    args.getSlice(1, argsTail);
-    return call(exec, thisValue, callType, callData, callThis, argsTail);
+    ArgList callArgs;
+    args.getSlice(1, callArgs);
+    return call(exec, thisValue, callType, callData, args.at(0), callArgs);
 }
 
 } // namespace JSC
index 33d68b729513e12b3640b444bc1157b5b685c5bb..607ddab15a9902f93e77788b61f5d1e249d9f8e1 100644 (file)
 
 namespace JSC {
 
+    class PrototypeFunction;
+
     class FunctionPrototype : public InternalFunction {
     public:
         FunctionPrototype(ExecState*, PassRefPtr<Structure>);
-        void addFunctionProperties(ExecState*, Structure* prototypeFunctionStructure);
+        void addFunctionProperties(ExecState*, Structure* prototypeFunctionStructure, NativeFunctionWrapper** callFunction, NativeFunctionWrapper** applyFunction);
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr proto)
+        static PassRefPtr<Structure> createStructure(JSValue proto)
         {
             return Structure::create(proto, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
         }
index 39ee6fcb6fa5ee87b42244f86763cbb4a0acddd7..cd1b40a15f28a8a94a548209a5a82cf044d5d766 100644 (file)
@@ -38,17 +38,17 @@ void GetterSetter::mark()
         m_setter->mark();
 }
 
-JSValuePtr GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValue GetterSetter::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     ASSERT_NOT_REACHED();
     return jsNull();
 }
 
-bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value)
+bool GetterSetter::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
 {
     ASSERT_NOT_REACHED();
     number = 0;
-    value = noValue();
+    value = JSValue();
     return true;
 }
 
index 48e1baf3f7880e5da221ebaeb09b30d9f628d929..e6b74a1ed0cfb354be6f9fe159ca114b332d4e87 100644 (file)
@@ -50,8 +50,8 @@ namespace JSC {
     private:
         virtual bool isGetterSetter() const;
 
-        virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
-        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
+        virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
         virtual UString toString(ExecState*) const;
@@ -61,9 +61,9 @@ namespace JSC {
         JSObject* m_setter;  
     };
 
-    GetterSetter* asGetterSetter(JSValuePtr);
+    GetterSetter* asGetterSetter(JSValue);
 
-    inline GetterSetter* asGetterSetter(JSValuePtr value)
+    inline GetterSetter* asGetterSetter(JSValue value)
     {
         ASSERT(asCell(value)->isGetterSetter());
         return static_cast<GetterSetter*>(asCell(value));
index cda9fb11ea87e658bbf9803964fb3a8016ae3252..fea89f875e5c8afe4ade5e56c0ed1dbe4893f2a6 100644 (file)
 #include "config.h"
 #include "InitializeThreading.h"
 
-#include "JSImmediate.h"
 #include "Collector.h"
-#include "DateMath.h"
 #include "dtoa.h"
 #include "Identifier.h"
 #include "JSGlobalObject.h"
 #include "UString.h"
+#include <wtf/DateMath.h>
 #include <wtf/Threading.h>
 
 using namespace WTF;
@@ -52,7 +51,7 @@ static void initializeThreadingOnce()
     initializeUString();
 #if ENABLE(JSC_MULTIPLE_THREADS)
     s_dtoaP5Mutex = new Mutex;
-    initDateMath();
+    WTF::initializeDates();
 #endif
 }
 
index 6714cf5426855025da380b636d3e0c5b5af60d60..b5c95715592edd5a298439d5a91b5beccd617541 100644 (file)
@@ -48,4 +48,24 @@ const UString& InternalFunction::name(JSGlobalData* globalData)
     return asString(getDirect(globalData->propertyNames->name))->value();
 }
 
+const UString InternalFunction::displayName(JSGlobalData* globalData)
+{
+    JSValue displayName = getDirect(globalData->propertyNames->displayName);
+    
+    if (displayName && isJSString(globalData, displayName))
+        return asString(displayName)->value();
+    
+    return UString::null();
+}
+
+const UString InternalFunction::calculatedDisplayName(JSGlobalData* globalData)
+{
+    const UString explicitName = displayName(globalData);
+    
+    if (!explicitName.isEmpty())
+        return explicitName;
+    
+    return name(globalData);
+}
+
 } // namespace JSC
index cc4b917e440df4e3a045f378b4d4991ab370522c..310644cedc05c8561504be40baf52cbd5ee59362 100644 (file)
@@ -34,11 +34,13 @@ namespace JSC {
     class InternalFunction : public JSObject {
     public:
         virtual const ClassInfo* classInfo() const; 
-        static const ClassInfo info;
+        static JS_EXPORTDATA const ClassInfo info;
 
         const UString& name(JSGlobalData*);
+        const UString displayName(JSGlobalData*);
+        const UString calculatedDisplayName(JSGlobalData*);
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr proto) 
+        static PassRefPtr<Structure> createStructure(JSValue proto) 
         { 
             return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance | HasStandardGetOwnPropertySlot)); 
         }
@@ -51,9 +53,9 @@ namespace JSC {
         virtual CallType getCallData(CallData&) = 0;
     };
 
-    InternalFunction* asInternalFunction(JSValuePtr);
+    InternalFunction* asInternalFunction(JSValue);
 
-    inline InternalFunction* asInternalFunction(JSValuePtr value)
+    inline InternalFunction* asInternalFunction(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&InternalFunction::info));
         return static_cast<InternalFunction*>(asObject(value));
diff --git a/runtime/JSAPIValueWrapper.cpp b/runtime/JSAPIValueWrapper.cpp
new file mode 100644 (file)
index 0000000..475fad5
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2004, 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 Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "JSAPIValueWrapper.h"
+
+#include "NumberObject.h"
+#include "UString.h"
+
+namespace JSC {
+
+JSValue JSAPIValueWrapper::toPrimitive(ExecState*, PreferredPrimitiveType) const
+{
+    ASSERT_NOT_REACHED();
+    return JSValue();
+}
+
+bool JSAPIValueWrapper::getPrimitiveNumber(ExecState*, double&, JSValue&)
+{
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+bool JSAPIValueWrapper::toBoolean(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+double JSAPIValueWrapper::toNumber(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+UString JSAPIValueWrapper::toString(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return UString();
+}
+
+JSObject* JSAPIValueWrapper::toObject(ExecState*) const
+{
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+} // namespace JSC
diff --git a/runtime/JSAPIValueWrapper.h b/runtime/JSAPIValueWrapper.h
new file mode 100644 (file)
index 0000000..e16fbba
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
+ *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ *  Copyright (C) 2003, 2004, 2005, 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 Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef JSAPIValueWrapper_h
+#define JSAPIValueWrapper_h
+
+#include <wtf/Platform.h>
+
+#include "JSCell.h"
+
+namespace JSC {
+
+    class JSAPIValueWrapper : public JSCell {
+        friend JSValue jsAPIValueWrapper(ExecState*, JSValue);
+    public:
+        JSValue value() const { return m_value; }
+
+        virtual bool isAPIValueWrapper() const { return true; }
+
+        virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
+        virtual bool toBoolean(ExecState*) const;
+        virtual double toNumber(ExecState*) const;
+        virtual UString toString(ExecState*) const;
+        virtual JSObject* toObject(ExecState*) const;
+
+    private:
+        JSAPIValueWrapper(JSValue value)
+            : JSCell(0)
+            , m_value(value)
+        {
+        }
+
+        JSValue m_value;
+    };
+
+    inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value)
+    {
+        return new (exec) JSAPIValueWrapper(value);
+    }
+
+} // namespace JSC
+
+#endif // JSAPIValueWrapper_h
index a2d26347c51c780a178597eed94e7d81865cbd48..33c84c2542b3f0dd7960e70807f7223d872cb9bc 100644 (file)
@@ -40,7 +40,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation);
 const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
 
 JSActivation::JSActivation(CallFrame* callFrame, PassRefPtr<FunctionBodyNode> functionBody)
-    : Base(callFrame->globalData().activationStructure, new JSActivationData(functionBody, callFrame))
+    : Base(callFrame->globalData().activationStructure, new JSActivationData(functionBody, callFrame->registers()))
 {
 }
 
@@ -57,7 +57,7 @@ void JSActivation::mark()
     if (!registerArray)
         return;
 
-    size_t numParametersMinusThis = d()->functionBody->generatedBytecode().m_numParameters - 1;
+    size_t numParametersMinusThis = d()->functionBody->parameterCount();
 
     size_t i = 0;
     size_t count = numParametersMinusThis; 
@@ -67,7 +67,7 @@ void JSActivation::mark()
             r.mark();
     }
 
-    size_t numVars = d()->functionBody->generatedBytecode().m_numVars;
+    size_t numVars = d()->numVars;
 
     // Skip the call frame, which sits between the parameters and vars.
     i += RegisterFile::CallFrameHeaderSize;
@@ -75,7 +75,7 @@ void JSActivation::mark()
 
     for ( ; i < count; ++i) {
         Register& r = registerArray[i];
-        if (!r.marked())
+        if (r.jsValue() && !r.marked())
             r.mark();
     }
 }
@@ -85,7 +85,7 @@ bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propert
     if (symbolTableGet(propertyName, slot))
         return true;
 
-    if (JSValuePtr* location = getDirectLocation(propertyName)) {
+    if (JSValue* location = getDirectLocation(propertyName)) {
         slot.setValueSlot(location);
         return true;
     }
@@ -103,7 +103,7 @@ bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propert
     return false;
 }
 
-void JSActivation::put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
@@ -118,7 +118,7 @@ void JSActivation::put(ExecState*, const Identifier& propertyName, JSValuePtr va
 }
 
 // FIXME: Make this function honor ReadOnly (const) and DontEnum
-void JSActivation::putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+void JSActivation::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
 {
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
@@ -130,7 +130,7 @@ void JSActivation::putWithAttributes(ExecState*, const Identifier& propertyName,
     // expose in the activation object.
     ASSERT(!hasGetterSetterProperties());
     PutPropertySlot slot;
-    putDirect(propertyName, value, attributes, true, slot);
+    JSObject::putWithAttributes(exec, propertyName, value, attributes, true, slot);
 }
 
 bool JSActivation::deleteProperty(ExecState* exec, const Identifier& propertyName)
@@ -151,7 +151,7 @@ bool JSActivation::isDynamicScope() const
     return d()->functionBody->usesEval();
 }
 
-JSValuePtr JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     JSActivation* activation = asActivation(slot.slotBase());
 
index 5e82bdc97f2582f716b1b00b0ed17500701567dd..e69aa6e6385826d84c079c5acdd2d4ff7f7510d2 100644 (file)
@@ -54,9 +54,9 @@ namespace JSC {
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
 
-        virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
+        virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
 
-        virtual void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes);
+        virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
 
         virtual JSObject* toThisObject(ExecState*) const;
@@ -66,28 +66,30 @@ namespace JSC {
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+        static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
 
     private:
         struct JSActivationData : public JSVariableObjectData {
-            JSActivationData(PassRefPtr<FunctionBodyNode> functionBody, Register* registers)
-                : JSVariableObjectData(&functionBody->generatedBytecode().symbolTable(), registers)
-                , functionBody(functionBody)
+            JSActivationData(PassRefPtr<FunctionBodyNode> _functionBody, Register* registers)
+                : JSVariableObjectData(&_functionBody->generatedBytecode().symbolTable(), registers)
+                , functionBody(_functionBody)
+                , numVars(functionBody->generatedBytecode().m_numVars)
             {
             }
 
             RefPtr<FunctionBodyNode> functionBody;
+            size_t numVars;
         };
         
-        static JSValuePtr argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
+        static JSValue argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
         NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
 
         JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
     };
 
-    JSActivation* asActivation(JSValuePtr);
+    JSActivation* asActivation(JSValue);
 
-    inline JSActivation* asActivation(JSValuePtr value)
+    inline JSActivation* asActivation(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&JSActivation::info));
         return static_cast<JSActivation*>(asObject(value));
index 89a2b45b2450c0c91569b8f3b167aaa7af8d5855..708ef99a27e3e878b780bda0eeedae2a67413fc0 100644 (file)
 #include "JSArray.h"
 
 #include "ArrayPrototype.h"
+#include "CachedCall.h"
 #include "PropertyNameArray.h"
 #include <wtf/AVLTree.h>
 #include <wtf/Assertions.h>
+#include <wtf/OwnPtr.h>
 #include <Operations.h>
 
 #define CHECK_ARRAY_CONSISTENCY 0
@@ -65,9 +67,9 @@ ASSERT_CLASS_FITS_IN_CELL(JSArray);
 
 // The definition of MAX_STORAGE_VECTOR_LENGTH is dependant on the definition storageSize
 // function below - the MAX_STORAGE_VECTOR_LENGTH limit is defined such that the storage
-// size calculation cannot overflow.  (sizeof(ArrayStorage) - sizeof(JSValuePtr)) +
-// (vectorLength * sizeof(JSValuePtr)) must be <= 0xFFFFFFFFU (which is maximum value of size_t).
-#define MAX_STORAGE_VECTOR_LENGTH static_cast<unsigned>((0xFFFFFFFFU - (sizeof(ArrayStorage) - sizeof(JSValuePtr))) / sizeof(JSValuePtr))
+// size calculation cannot overflow.  (sizeof(ArrayStorage) - sizeof(JSValue)) +
+// (vectorLength * sizeof(JSValue)) must be <= 0xFFFFFFFFU (which is maximum value of size_t).
+#define MAX_STORAGE_VECTOR_LENGTH static_cast<unsigned>((0xFFFFFFFFU - (sizeof(ArrayStorage) - sizeof(JSValue))) / sizeof(JSValue))
 
 // These values have to be macros to be used in max() and min() without introducing
 // a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
@@ -90,10 +92,10 @@ static inline size_t storageSize(unsigned vectorLength)
 
     // MAX_STORAGE_VECTOR_LENGTH is defined such that provided (vectorLength <= MAX_STORAGE_VECTOR_LENGTH)
     // - as asserted above - the following calculation cannot overflow.
-    size_t size = (sizeof(ArrayStorage) - sizeof(JSValuePtr)) + (vectorLength * sizeof(JSValuePtr));
+    size_t size = (sizeof(ArrayStorage) - sizeof(JSValue)) + (vectorLength * sizeof(JSValue));
     // Assertion to detect integer overflow in previous calculation (should not be possible, provided that
     // MAX_STORAGE_VECTOR_LENGTH is correctly defined).
-    ASSERT(((size - (sizeof(ArrayStorage) - sizeof(JSValuePtr))) / sizeof(JSValuePtr) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(JSValuePtr))));
+    ASSERT(((size - (sizeof(ArrayStorage) - sizeof(JSValue))) / sizeof(JSValue) == vectorLength) && (size >= (sizeof(ArrayStorage) - sizeof(JSValue))));
 
     return size;
 }
@@ -132,9 +134,9 @@ JSArray::JSArray(PassRefPtr<Structure> structure)
     unsigned initialCapacity = 0;
 
     m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
-    m_fastAccessCutoff = 0;
     m_storage->m_vectorLength = initialCapacity;
-    m_storage->m_length = 0;
+
+    m_fastAccessCutoff = 0;
 
     checkConsistency();
 }
@@ -144,40 +146,45 @@ JSArray::JSArray(PassRefPtr<Structure> structure, unsigned initialLength)
 {
     unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
 
-    m_storage = static_cast<ArrayStorage*>(fastZeroedMalloc(storageSize(initialCapacity)));
-    m_fastAccessCutoff = 0;
-    m_storage->m_vectorLength = initialCapacity;
+    m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
     m_storage->m_length = initialLength;
+    m_storage->m_vectorLength = initialCapacity;
+    m_storage->m_numValuesInVector = 0;
+    m_storage->m_sparseValueMap = 0;
+    m_storage->lazyCreationData = 0;
 
-    Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValuePtr));
+    JSValue* vector = m_storage->m_vector;
+    for (size_t i = 0; i < initialCapacity; ++i)
+        vector[i] = JSValue();
+
+    m_fastAccessCutoff = 0;
 
     checkConsistency();
+
+    Heap::heap(this)->reportExtraMemoryCost(initialCapacity * sizeof(JSValue));
 }
 
-JSArray::JSArray(ExecState* exec, PassRefPtr<Structure> structure, const ArgList& list)
+JSArray::JSArray(PassRefPtr<Structure> structure, const ArgList& list)
     : JSObject(structure)
 {
-    unsigned length = list.size();
+    unsigned initialCapacity = list.size();
 
-    m_fastAccessCutoff = length;
-
-    ArrayStorage* storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(length)));
-
-    storage->m_vectorLength = length;
-    storage->m_numValuesInVector = length;
-    storage->m_sparseValueMap = 0;
-    storage->m_length = length;
+    m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
+    m_storage->m_length = initialCapacity;
+    m_storage->m_vectorLength = initialCapacity;
+    m_storage->m_numValuesInVector = initialCapacity;
+    m_storage->m_sparseValueMap = 0;
 
     size_t i = 0;
     ArgList::const_iterator end = list.end();
     for (ArgList::const_iterator it = list.begin(); it != end; ++it, ++i)
-        storage->m_vector[i] = (*it).jsValue(exec);
+        m_storage->m_vector[i] = *it;
 
-    m_storage = storage;
-
-    Heap::heap(this)->reportExtraMemoryCost(storageSize(length));
+    m_fastAccessCutoff = initialCapacity;
 
     checkConsistency();
+
+    Heap::heap(this)->reportExtraMemoryCost(storageSize(initialCapacity));
 }
 
 JSArray::~JSArray()
@@ -199,7 +206,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot
     }
 
     if (i < storage->m_vectorLength) {
-        JSValuePtr& valueSlot = storage->m_vector[i];
+        JSValue& valueSlot = storage->m_vector[i];
         if (valueSlot) {
             slot.setValueSlot(&valueSlot);
             return true;
@@ -233,7 +240,7 @@ bool JSArray::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName
 }
 
 // ECMA 15.4.5.1
-void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     bool isArrayIndex;
     unsigned i = propertyName.toArrayIndex(&isArrayIndex);
@@ -255,7 +262,7 @@ void JSArray::put(ExecState* exec, const Identifier& propertyName, JSValuePtr va
     JSObject::put(exec, propertyName, value, slot);
 }
 
-void JSArray::put(ExecState* exec, unsigned i, JSValuePtr value)
+void JSArray::put(ExecState* exec, unsigned i, JSValue value)
 {
     checkConsistency();
 
@@ -266,7 +273,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValuePtr value)
     }
 
     if (i < m_storage->m_vectorLength) {
-        JSValuePtr& valueSlot = m_storage->m_vector[i];
+        JSValue& valueSlot = m_storage->m_vector[i];
         if (valueSlot) {
             valueSlot = value;
             checkConsistency();
@@ -282,7 +289,7 @@ void JSArray::put(ExecState* exec, unsigned i, JSValuePtr value)
     putSlowCase(exec, i, value);
 }
 
-NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValuePtr value)
+NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue value)
 {
     ArrayStorage* storage = m_storage;
     SparseArrayValueMap* map = storage->m_sparseValueMap;
@@ -353,12 +360,12 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValuePtr v
 
     if (newNumValuesInVector == storage->m_numValuesInVector + 1) {
         for (unsigned j = vectorLength; j < newVectorLength; ++j)
-            storage->m_vector[j] = noValue();
+            storage->m_vector[j] = JSValue();
         if (i > MIN_SPARSE_ARRAY_INDEX)
             map->remove(i);
     } else {
         for (unsigned j = vectorLength; j < max(vectorLength, MIN_SPARSE_ARRAY_INDEX); ++j)
-            storage->m_vector[j] = noValue();
+            storage->m_vector[j] = JSValue();
         for (unsigned j = max(vectorLength, MIN_SPARSE_ARRAY_INDEX); j < newVectorLength; ++j)
             storage->m_vector[j] = map->take(j);
     }
@@ -393,12 +400,12 @@ bool JSArray::deleteProperty(ExecState* exec, unsigned i)
     ArrayStorage* storage = m_storage;
 
     if (i < storage->m_vectorLength) {
-        JSValuePtr& valueSlot = storage->m_vector[i];
+        JSValue& valueSlot = storage->m_vector[i];
         if (!valueSlot) {
             checkConsistency();
             return false;
         }
-        valueSlot = noValue();
+        valueSlot = JSValue();
         --storage->m_numValuesInVector;
         if (m_fastAccessCutoff > i)
             m_fastAccessCutoff = i;
@@ -468,7 +475,7 @@ bool JSArray::increaseVectorLength(unsigned newLength)
     storage->m_vectorLength = newVectorLength;
 
     for (unsigned i = vectorLength; i < newVectorLength; ++i)
-        storage->m_vector[i] = noValue();
+        storage->m_vector[i] = JSValue();
 
     m_storage = storage;
     return true;
@@ -488,9 +495,9 @@ void JSArray::setLength(unsigned newLength)
 
         unsigned usedVectorLength = min(length, storage->m_vectorLength);
         for (unsigned i = newLength; i < usedVectorLength; ++i) {
-            JSValuePtr& valueSlot = storage->m_vector[i];
+            JSValue& valueSlot = storage->m_vector[i];
             bool hadValue = valueSlot;
-            valueSlot = noValue();
+            valueSlot = JSValue();
             storage->m_numValuesInVector -= hadValue;
         }
 
@@ -513,7 +520,7 @@ void JSArray::setLength(unsigned newLength)
     checkConsistency();
 }
 
-JSValuePtr JSArray::pop()
+JSValue JSArray::pop()
 {
     checkConsistency();
 
@@ -523,19 +530,19 @@ JSValuePtr JSArray::pop()
 
     --length;
 
-    JSValuePtr result;
+    JSValue result;
 
     if (m_fastAccessCutoff > length) {
-        JSValuePtr& valueSlot = m_storage->m_vector[length];
+        JSValue& valueSlot = m_storage->m_vector[length];
         result = valueSlot;
         ASSERT(result);
-        valueSlot = noValue();
+        valueSlot = JSValue();
         --m_storage->m_numValuesInVector;
         m_fastAccessCutoff = length;
     } else if (length < m_storage->m_vectorLength) {
-        JSValuePtr& valueSlot = m_storage->m_vector[length];
+        JSValue& valueSlot = m_storage->m_vector[length];
         result = valueSlot;
-        valueSlot = noValue();
+        valueSlot = JSValue();
         if (result)
             --m_storage->m_numValuesInVector;
         else
@@ -562,7 +569,7 @@ JSValuePtr JSArray::pop()
     return result;
 }
 
-void JSArray::push(ExecState* exec, JSValuePtr value)
+void JSArray::push(ExecState* exec, JSValue value)
 {
     checkConsistency();
 
@@ -602,7 +609,7 @@ void JSArray::mark()
 
     unsigned usedVectorLength = min(storage->m_length, storage->m_vectorLength);
     for (unsigned i = 0; i < usedVectorLength; ++i) {
-        JSValuePtr value = storage->m_vector[i];
+        JSValue value = storage->m_vector[i];
         if (value && !value.marked())
             value.mark();
     }
@@ -610,7 +617,7 @@ void JSArray::mark()
     if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
         SparseArrayValueMap::iterator end = map->end();
         for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
-            JSValuePtr value = it->second;
+            JSValue value = it->second;
             if (!value.marked())
                 value.mark();
         }
@@ -619,12 +626,12 @@ void JSArray::mark()
 
 static int compareNumbersForQSort(const void* a, const void* b)
 {
-    double da = static_cast<const JSValuePtr*>(a)->uncheckedGetNumber();
-    double db = static_cast<const JSValuePtr*>(b)->uncheckedGetNumber();
+    double da = static_cast<const JSValue*>(a)->uncheckedGetNumber();
+    double db = static_cast<const JSValue*>(b)->uncheckedGetNumber();
     return (da > db) - (da < db);
 }
 
-typedef std::pair<JSValuePtr, UString> ValueStringPair;
+typedef std::pair<JSValue, UString> ValueStringPair;
 
 static int compareByStringPairForQSort(const void* a, const void* b)
 {
@@ -633,7 +640,7 @@ static int compareByStringPairForQSort(const void* a, const void* b)
     return compare(va->second, vb->second);
 }
 
-void JSArray::sortNumeric(ExecState* exec, JSValuePtr compareFunction, CallType callType, const CallData& callData)
+void JSArray::sortNumeric(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
 {
     unsigned lengthNotIncludingUndefined = compactForSorting();
     if (m_storage->m_sparseValueMap) {
@@ -659,7 +666,7 @@ void JSArray::sortNumeric(ExecState* exec, JSValuePtr compareFunction, CallType
     // For numeric comparison, which is fast, qsort is faster than mergesort. We
     // also don't require mergesort's stability, since there's no user visible
     // side-effect from swapping the order of equal primitive values.
-    qsort(m_storage->m_vector, size, sizeof(JSValuePtr), compareNumbersForQSort);
+    qsort(m_storage->m_vector, size, sizeof(JSValue), compareNumbersForQSort);
 
     checkConsistency(SortConsistencyCheck);
 }
@@ -687,7 +694,7 @@ void JSArray::sort(ExecState* exec)
     }
 
     for (size_t i = 0; i < lengthNotIncludingUndefined; i++) {
-        JSValuePtr value = m_storage->m_vector[i];
+        JSValue value = m_storage->m_vector[i];
         ASSERT(!value.isUndefined());
         values[i].first = value;
     }
@@ -725,7 +732,7 @@ void JSArray::sort(ExecState* exec)
 }
 
 struct AVLTreeNodeForArrayCompare {
-    JSValuePtr value;
+    JSValue value;
 
     // Child pointers.  The high bit of gt is robbed and used as the
     // balance factor sign.  The high bit of lt is robbed and used as
@@ -736,15 +743,16 @@ struct AVLTreeNodeForArrayCompare {
 
 struct AVLTreeAbstractorForArrayCompare {
     typedef int32_t handle; // Handle is an index into m_nodes vector.
-    typedef JSValuePtr key;
+    typedef JSValue key;
     typedef int32_t size;
 
     Vector<AVLTreeNodeForArrayCompare> m_nodes;
     ExecState* m_exec;
-    JSValuePtr m_compareFunction;
+    JSValue m_compareFunction;
     CallType m_compareCallType;
     const CallData* m_compareCallData;
-    JSValuePtr m_globalThisValue;
+    JSValue m_globalThisValue;
+    OwnPtr<CachedCall> m_cachedCall;
 
     handle get_less(handle h) { return m_nodes[h].lt & 0x7FFFFFFF; }
     void set_less(handle h, handle lh) { m_nodes[h].lt &= 0x80000000; m_nodes[h].lt |= lh; }
@@ -780,10 +788,18 @@ struct AVLTreeAbstractorForArrayCompare {
         if (m_exec->hadException())
             return 1;
 
-        ArgList arguments;
-        arguments.append(va);
-        arguments.append(vb);
-        double compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments).toNumber(m_exec);
+        double compareResult;
+        if (m_cachedCall) {
+            m_cachedCall->setThis(m_globalThisValue);
+            m_cachedCall->setArgument(0, va);
+            m_cachedCall->setArgument(1, vb);
+            compareResult = m_cachedCall->call().toNumber(m_cachedCall->newCallFrame());
+        } else {
+            MarkedArgumentBuffer arguments;
+            arguments.append(va);
+            arguments.append(vb);
+            compareResult = call(m_exec, m_compareFunction, m_compareCallType, *m_compareCallData, m_globalThisValue, arguments).toNumber(m_exec);
+        }
         return (compareResult < 0) ? -1 : 1; // Not passing equality through, because we need to store all values, even if equivalent.
     }
 
@@ -793,7 +809,7 @@ struct AVLTreeAbstractorForArrayCompare {
     static handle null() { return 0x7FFFFFFF; }
 };
 
-void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callType, const CallData& callData)
+void JSArray::sort(ExecState* exec, JSValue compareFunction, CallType callType, const CallData& callData)
 {
     checkConsistency();
 
@@ -818,6 +834,9 @@ void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callTyp
     tree.abstractor().m_globalThisValue = exec->globalThisValue();
     tree.abstractor().m_nodes.resize(usedVectorLength + (m_storage->m_sparseValueMap ? m_storage->m_sparseValueMap->size() : 0));
 
+    if (callType == CallTypeJS)
+        tree.abstractor().m_cachedCall.set(new CachedCall(exec, asFunction(compareFunction), 2, exec->exceptionSlot()));
+
     if (!tree.abstractor().m_nodes.begin()) {
         throwOutOfMemoryError(exec);
         return;
@@ -831,14 +850,14 @@ void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callTyp
 
     // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
     for (; numDefined < usedVectorLength; ++numDefined) {
-        JSValuePtr v = m_storage->m_vector[numDefined];
+        JSValue v = m_storage->m_vector[numDefined];
         if (!v || v.isUndefined())
             break;
         tree.abstractor().m_nodes[numDefined].value = v;
         tree.insert(numDefined);
     }
     for (unsigned i = numDefined; i < usedVectorLength; ++i) {
-        JSValuePtr v = m_storage->m_vector[i];
+        JSValue v = m_storage->m_vector[i];
         if (v) {
             if (v.isUndefined())
                 ++numUndefined;
@@ -892,7 +911,7 @@ void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callTyp
 
     // Ensure that unused values in the vector are zeroed out.
     for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
-        m_storage->m_vector[i] = noValue();
+        m_storage->m_vector[i] = JSValue();
 
     m_fastAccessCutoff = newUsedVectorLength;
     m_storage->m_numValuesInVector = newUsedVectorLength;
@@ -900,7 +919,7 @@ void JSArray::sort(ExecState* exec, JSValuePtr compareFunction, CallType callTyp
     checkConsistency(SortConsistencyCheck);
 }
 
-void JSArray::fillArgList(ExecState* exec, ArgList& args)
+void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
 {
     unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff);
     unsigned i = 0;
@@ -910,6 +929,19 @@ void JSArray::fillArgList(ExecState* exec, ArgList& args)
         args.append(get(exec, i));
 }
 
+void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize)
+{
+    ASSERT(m_storage->m_length == maxSize);
+    UNUSED_PARAM(maxSize);
+    unsigned fastAccessLength = min(m_storage->m_length, m_fastAccessCutoff);
+    unsigned i = 0;
+    for (; i < fastAccessLength; ++i)
+        buffer[i] = getIndex(i);
+    uint32_t size = m_storage->m_length;
+    for (; i < size; ++i)
+        buffer[i] = get(exec, i);
+}
+
 unsigned JSArray::compactForSorting()
 {
     checkConsistency();
@@ -922,12 +954,12 @@ unsigned JSArray::compactForSorting()
     unsigned numUndefined = 0;
 
     for (; numDefined < usedVectorLength; ++numDefined) {
-        JSValuePtr v = storage->m_vector[numDefined];
+        JSValue v = storage->m_vector[numDefined];
         if (!v || v.isUndefined())
             break;
     }
     for (unsigned i = numDefined; i < usedVectorLength; ++i) {
-        JSValuePtr v = storage->m_vector[i];
+        JSValue v = storage->m_vector[i];
         if (v) {
             if (v.isUndefined())
                 ++numUndefined;
@@ -959,7 +991,7 @@ unsigned JSArray::compactForSorting()
     for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
         storage->m_vector[i] = jsUndefined();
     for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
-        storage->m_vector[i] = noValue();
+        storage->m_vector[i] = JSValue();
 
     m_fastAccessCutoff = newUsedVectorLength;
     storage->m_numValuesInVector = newUsedVectorLength;
@@ -992,7 +1024,7 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
 
     unsigned numValuesInVector = 0;
     for (unsigned i = 0; i < m_storage->m_vectorLength; ++i) {
-        if (JSValuePtr value = m_storage->m_vector[i]) {
+        if (JSValue value = m_storage->m_vector[i]) {
             ASSERT(i < m_storage->m_length);
             if (type != DestructorConsistencyCheck)
                 value->type(); // Likely to crash if the object was deallocated.
@@ -1031,16 +1063,16 @@ JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
     return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
 }
 
-JSArray* constructArray(ExecState* exec, JSValuePtr singleItemValue)
+JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
 {
-    ArgList values;
+    MarkedArgumentBuffer values;
     values.append(singleItemValue);
-    return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), values);
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
 }
 
 JSArray* constructArray(ExecState* exec, const ArgList& values)
 {
-    return new (exec) JSArray(exec, exec->lexicalGlobalObject()->arrayStructure(), values);
+    return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), values);
 }
 
 } // namespace JSC
index 7eecf335ad9531f7a58bb2921f7f380eb6f69064..ea490d86aa4c2dee468f1f408d857fc2b6eca998 100644 (file)
@@ -25,7 +25,7 @@
 
 namespace JSC {
 
-    typedef HashMap<unsigned, JSValuePtr> SparseArrayValueMap;
+    typedef HashMap<unsigned, JSValue> SparseArrayValueMap;
 
     struct ArrayStorage {
         unsigned m_length;
@@ -33,7 +33,7 @@ namespace JSC {
         unsigned m_numValuesInVector;
         SparseArrayValueMap* m_sparseValueMap;
         void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily.
-        JSValuePtr m_vector[1];
+        JSValue m_vector[1];
     };
 
     class JSArray : public JSObject {
@@ -42,48 +42,49 @@ namespace JSC {
     public:
         explicit JSArray(PassRefPtr<Structure>);
         JSArray(PassRefPtr<Structure>, unsigned initialLength);
-        JSArray(ExecState*, PassRefPtr<Structure>, const ArgList& initialValues);
+        JSArray(PassRefPtr<Structure>, const ArgList& initialValues);
         virtual ~JSArray();
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
-        virtual void put(ExecState*, unsigned propertyName, JSValuePtr); // FIXME: Make protected and add setItem.
+        virtual void put(ExecState*, unsigned propertyName, JSValue); // FIXME: Make protected and add setItem.
 
-        static const ClassInfo info;
+        static JS_EXPORTDATA const ClassInfo info;
 
         unsigned length() const { return m_storage->m_length; }
         void setLength(unsigned); // OK to use on new arrays, but not if it might be a RegExpMatchArray.
 
         void sort(ExecState*);
-        void sort(ExecState*, JSValuePtr compareFunction, CallType, const CallData&);
-        void sortNumeric(ExecState*, JSValuePtr compareFunction, CallType, const CallData&);
+        void sort(ExecState*, JSValue compareFunction, CallType, const CallData&);
+        void sortNumeric(ExecState*, JSValue compareFunction, CallType, const CallData&);
 
-        void push(ExecState*, JSValuePtr);
-        JSValuePtr pop();
+        void push(ExecState*, JSValue);
+        JSValue pop();
 
         bool canGetIndex(unsigned i) { return i < m_fastAccessCutoff; }
-        JSValuePtr getIndex(unsigned i)
+        JSValue getIndex(unsigned i)
         {
             ASSERT(canGetIndex(i));
             return m_storage->m_vector[i];
         }
 
         bool canSetIndex(unsigned i) { return i < m_fastAccessCutoff; }
-        JSValuePtr setIndex(unsigned i, JSValuePtr v)
+        JSValue setIndex(unsigned i, JSValue v)
         {
             ASSERT(canSetIndex(i));
             return m_storage->m_vector[i] = v;
         }
 
-        void fillArgList(ExecState*, ArgList&);
+        void fillArgList(ExecState*, MarkedArgumentBuffer&);
+        void copyToRegisters(ExecState*, Register*, uint32_t);
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
             return Structure::create(prototype, TypeInfo(ObjectType));
         }
 
     protected:
-        virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
@@ -96,7 +97,7 @@ namespace JSC {
         virtual const ClassInfo* classInfo() const { return &info; }
 
         bool getOwnPropertySlotSlowCase(ExecState*, unsigned propertyName, PropertySlot&);
-        void putSlowCase(ExecState*, unsigned propertyName, JSValuePtr);
+        void putSlowCase(ExecState*, unsigned propertyName, JSValue);
 
         bool increaseVectorLength(unsigned newLength);
         
@@ -109,19 +110,21 @@ namespace JSC {
         ArrayStorage* m_storage;
     };
 
-    JSArray* asArray(JSValuePtr);
+    JSArray* asArray(JSValue);
 
     JSArray* constructEmptyArray(ExecState*);
     JSArray* constructEmptyArray(ExecState*, unsigned initialLength);
-    JSArray* constructArray(ExecState*, JSValuePtr singleItemValue);
+    JSArray* constructArray(ExecState*, JSValue singleItemValue);
     JSArray* constructArray(ExecState*, const ArgList& values);
 
-    inline JSArray* asArray(JSValuePtr value)
+    inline JSArray* asArray(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&JSArray::info));
         return static_cast<JSArray*>(asObject(value));
     }
 
+    inline bool isJSArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsArrayVPtr; }
+
 } // namespace JSC
 
 #endif // JSArray_h
index 54cf7cbd669ee03713d41a2c782a9c38e1b31977..2a5e72f74c69e7e7a0b6b55dd853b2126997a3d2 100644 (file)
@@ -43,7 +43,7 @@ JSByteArray::JSByteArray(ExecState* exec, PassRefPtr<Structure> structure, ByteA
     putDirect(exec->globalData().propertyNames->length, jsNumber(exec, m_storage->length()), ReadOnly | DontDelete);
 }
     
-PassRefPtr<Structure> JSByteArray::createStructure(JSValuePtr prototype)
+PassRefPtr<Structure> JSByteArray::createStructure(JSValue prototype)
 {
     PassRefPtr<Structure> result = Structure::create(prototype, TypeInfo(ObjectType));
     return result;
@@ -69,7 +69,7 @@ bool JSByteArray::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Pro
     return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
 }
 
-void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     bool ok;
     unsigned index = propertyName.toUInt32(&ok, false);
@@ -80,7 +80,7 @@ void JSByteArray::put(ExecState* exec, const Identifier& propertyName, JSValuePt
     JSObject::put(exec, propertyName, value, slot);
 }
 
-void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
+void JSByteArray::put(ExecState* exec, unsigned propertyName, JSValue value)
 {
     setIndex(exec, propertyName, value);
 }
index 19c8f0ecc384d0d8c89a7afd2910e07fc3714af0..57374e0ace608361ea14d8a40f7b7c7f578fcce5 100644 (file)
 namespace JSC {
 
     class JSByteArray : public JSObject {
-        friend class Interpreter;
+        friend class VPtrSet;
     public:
         bool canAccessIndex(unsigned i) { return i < m_storage->length(); }
-        JSValuePtr getIndex(ExecState* exec, unsigned i)
+        JSValue getIndex(ExecState* exec, unsigned i)
         {
             ASSERT(canAccessIndex(i));
             return jsNumber(exec, m_storage->data()[i]);
@@ -64,7 +64,7 @@ namespace JSC {
             m_storage->data()[i] = static_cast<unsigned char>(value + 0.5);
         }
         
-        void setIndex(ExecState* exec, unsigned i, JSValuePtr value)
+        void setIndex(ExecState* exec, unsigned i, JSValue value)
         {
             double byteValue = value.toNumber(exec);
             if (exec->hadException())
@@ -74,12 +74,12 @@ namespace JSC {
         }
 
         JSByteArray(ExecState* exec, PassRefPtr<Structure>, WTF::ByteArray* storage, const JSC::ClassInfo* = &s_defaultInfo);
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype);
+        static PassRefPtr<Structure> createStructure(JSValue prototype);
         
         virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&);
         virtual bool getOwnPropertySlot(JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
-        virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValuePtr, JSC::PutPropertySlot&);
-        virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValuePtr);
+        virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&);
+        virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue);
 
         virtual void getPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&);
 
@@ -88,6 +88,8 @@ namespace JSC {
         
         size_t length() const { return m_storage->length(); }
 
+        WTF::ByteArray* storage() const { return m_storage.get(); }
+
     private:
         enum VPtrStealingHackType { VPtrStealingHack };
         JSByteArray(VPtrStealingHackType) 
@@ -100,11 +102,14 @@ namespace JSC {
         const ClassInfo* m_classInfo;
     };
     
-    JSByteArray* asByteArray(JSValuePtr value);
-    inline JSByteArray* asByteArray(JSValuePtr value)
+    JSByteArray* asByteArray(JSValue value);
+    inline JSByteArray* asByteArray(JSValue value)
     {
         return static_cast<JSByteArray*>(asCell(value));
     }
-}
 
-#endif
+    inline bool isJSByteArray(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsByteArrayVPtr; }
+
+} // namespace JSC
+
+#endif // JSByteArray_h
index d449deb368b82a24f6a5b55176e8aaf8d012818d..c733ed90783b1e8e1fbad55ae7231f3abbdd4f30 100644 (file)
@@ -90,16 +90,6 @@ bool JSCell::getUInt32(uint32_t&) const
     return false;
 }
 
-bool JSCell::getTruncatedInt32(int32_t&) const
-{
-    return false;
-}
-
-bool JSCell::getTruncatedUInt32(uint32_t&) const
-{
-    return false;
-}
-
 bool JSCell::getString(UString&stringValue) const
 {
     if (!isString())
@@ -157,12 +147,12 @@ bool JSCell::getOwnPropertySlot(ExecState* exec, unsigned identifier, PropertySl
     return true;
 }
 
-void JSCell::put(ExecState* exec, const Identifier& identifier, JSValuePtr value, PutPropertySlot& slot)
+void JSCell::put(ExecState* exec, const Identifier& identifier, JSValue value, PutPropertySlot& slot)
 {
     toObject(exec)->put(exec, identifier, value, slot);
 }
 
-void JSCell::put(ExecState* exec, unsigned identifier, JSValuePtr value)
+void JSCell::put(ExecState* exec, unsigned identifier, JSValue value)
 {
     toObject(exec)->put(exec, identifier, value);
 }
@@ -197,9 +187,9 @@ const ClassInfo* JSCell::classInfo() const
     return 0;
 }
 
-JSValuePtr JSCell::getJSNumber()
+JSValue JSCell::getJSNumber()
 {
-    return noValue();
+    return JSValue();
 }
 
 bool JSCell::isGetterSetter() const
index 43d81a55563dbae2738aa9c857db84fcbb4e0ff9..2cb5959a1571005c88223952681d98c1e50111ca 100644 (file)
 namespace JSC {
 
     class JSCell : Noncopyable {
-        friend class JIT;
         friend class GetterSetter;
         friend class Heap;
+        friend class JIT;
         friend class JSNumberCell;
         friend class JSObject;
         friend class JSPropertyNameIterator;
         friend class JSString;
-        friend class JSValuePtr;
-        friend class Interpreter;
+        friend class JSValue;
+        friend class JSAPIValueWrapper;
+        friend struct VPtrSet;
 
     private:
         explicit JSCell(Structure*);
@@ -48,11 +49,14 @@ namespace JSC {
 
     public:
         // Querying the type.
+#if USE(JSVALUE32)
         bool isNumber() const;
+#endif
         bool isString() const;
         bool isObject() const;
         virtual bool isGetterSetter() const;
         virtual bool isObject(const ClassInfo*) const;
+        virtual bool isAPIValueWrapper() const { return false; }
 
         Structure* structure() const;
 
@@ -66,14 +70,12 @@ namespace JSC {
         virtual ConstructType getConstructData(ConstructData&);
 
         // Extracting integer values.
-        // FIXME: remove these methods, can check isNumberCell in JSValuePtr && then call asNumberCell::*.
+        // FIXME: remove these methods, can check isNumberCell in JSValue && then call asNumberCell::*.
         virtual bool getUInt32(uint32_t&) const;
-        virtual bool getTruncatedInt32(int32_t&) const;
-        virtual bool getTruncatedUInt32(uint32_t&) const;
 
         // Basic conversions.
-        virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
-        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&) = 0;
+        virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const = 0;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&) = 0;
         virtual bool toBoolean(ExecState*) const = 0;
         virtual double toNumber(ExecState*) const = 0;
         virtual UString toString(ExecState*) const = 0;
@@ -88,15 +90,15 @@ namespace JSC {
 
         // Object operations, with the toObject operation included.
         virtual const ClassInfo* classInfo() const;
-        virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
-        virtual void put(ExecState*, unsigned propertyName, JSValuePtr);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+        virtual void put(ExecState*, unsigned propertyName, JSValue);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
 
         virtual JSObject* toThisObject(ExecState*) const;
         virtual UString toThisString(ExecState*) const;
         virtual JSString* toThisJSString(ExecState*);
-        virtual JSValuePtr getJSNumber();
+        virtual JSValue getJSNumber();
         void* vptr() { return *reinterpret_cast<void**>(this); }
 
     private:
@@ -108,9 +110,9 @@ namespace JSC {
         Structure* m_structure;
     };
 
-    JSCell* asCell(JSValuePtr);
+    JSCell* asCell(JSValue);
 
-    inline JSCell* asCell(JSValuePtr value)
+    inline JSCell* asCell(JSValue value)
     {
         return value.asCell();
     }
@@ -124,10 +126,12 @@ namespace JSC {
     {
     }
 
+#if USE(JSVALUE32)
     inline bool JSCell::isNumber() const
     {
         return Heap::isNumber(const_cast<JSCell*>(this));
     }
+#endif
 
     inline bool JSCell::isObject() const
     {
@@ -154,12 +158,6 @@ namespace JSC {
         return Heap::markCell(this);
     }
 
-    ALWAYS_INLINE JSCell* JSValuePtr::asCell() const
-    {
-        ASSERT(isCell());
-        return m_ptr;
-    }
-
     inline void* JSCell::operator new(size_t size, JSGlobalData* globalData)
     {
 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE
@@ -171,128 +169,185 @@ namespace JSC {
 
     // --- JSValue inlines ----------------------------
 
-    inline bool JSValuePtr::isString() const
+    inline bool JSValue::isString() const
     {
-        return !JSImmediate::isImmediate(asValue()) && asCell()->isString();
+        return isCell() && asCell()->isString();
     }
 
-    inline bool JSValuePtr::isGetterSetter() const
+    inline bool JSValue::isGetterSetter() const
     {
-        return !JSImmediate::isImmediate(asValue()) && asCell()->isGetterSetter();
+        return isCell() && asCell()->isGetterSetter();
     }
 
-    inline bool JSValuePtr::isObject() const
+    inline bool JSValue::isObject() const
     {
-        return !JSImmediate::isImmediate(asValue()) && asCell()->isObject();
+        return isCell() && asCell()->isObject();
     }
 
-    inline bool JSValuePtr::getString(UString& s) const
+    inline bool JSValue::getString(UString& s) const
     {
-        return !JSImmediate::isImmediate(asValue()) && asCell()->getString(s);
+        return isCell() && asCell()->getString(s);
     }
 
-    inline UString JSValuePtr::getString() const
+    inline UString JSValue::getString() const
     {
-        return JSImmediate::isImmediate(asValue()) ? UString() : asCell()->getString();
+        return isCell() ? asCell()->getString() : UString();
     }
 
-    inline JSObject* JSValuePtr::getObject() const
+    inline JSObject* JSValue::getObject() const
     {
-        return JSImmediate::isImmediate(asValue()) ? 0 : asCell()->getObject();
+        return isCell() ? asCell()->getObject() : 0;
     }
 
-    inline CallType JSValuePtr::getCallData(CallData& callData)
+    inline CallType JSValue::getCallData(CallData& callData)
     {
-        return JSImmediate::isImmediate(asValue()) ? CallTypeNone : asCell()->getCallData(callData);
+        return isCell() ? asCell()->getCallData(callData) : CallTypeNone;
     }
 
-    inline ConstructType JSValuePtr::getConstructData(ConstructData& constructData)
+    inline ConstructType JSValue::getConstructData(ConstructData& constructData)
     {
-        return JSImmediate::isImmediate(asValue()) ? ConstructTypeNone : asCell()->getConstructData(constructData);
+        return isCell() ? asCell()->getConstructData(constructData) : ConstructTypeNone;
     }
 
-    ALWAYS_INLINE bool JSValuePtr::getUInt32(uint32_t& v) const
+    ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
     {
-        return JSImmediate::isImmediate(asValue()) ? JSImmediate::getUInt32(asValue(), v) : asCell()->getUInt32(v);
-    }
-
-    ALWAYS_INLINE bool JSValuePtr::getTruncatedInt32(int32_t& v) const
-    {
-        return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedInt32(asValue(), v) : asCell()->getTruncatedInt32(v);
+        if (isInt32()) {
+            int32_t i = asInt32();
+            v = static_cast<uint32_t>(i);
+            return i >= 0;
+        }
+        if (isDouble()) {
+            double d = asDouble();
+            v = static_cast<uint32_t>(d);
+            return v == d;
+        }
+        return false;
     }
 
-    inline bool JSValuePtr::getTruncatedUInt32(uint32_t& v) const
+    inline void JSValue::mark()
     {
-        return JSImmediate::isImmediate(asValue()) ? JSImmediate::getTruncatedUInt32(asValue(), v) : asCell()->getTruncatedUInt32(v);
+        asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells
     }
 
-    inline void JSValuePtr::mark()
+    inline bool JSValue::marked() const
     {
-        asCell()->mark(); // callers should check !marked() before calling mark(), so this should only be called with cells
+        return !isCell() || asCell()->marked();
     }
 
-    inline bool JSValuePtr::marked() const
+#if !USE(JSVALUE32_64)
+    ALWAYS_INLINE JSCell* JSValue::asCell() const
     {
-        return JSImmediate::isImmediate(asValue()) || asCell()->marked();
+        ASSERT(isCell());
+        return m_ptr;
     }
+#endif // !USE(JSVALUE32_64)
 
-    inline JSValuePtr JSValuePtr::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
+    inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
     {
-        return JSImmediate::isImmediate(asValue()) ? asValue() : asCell()->toPrimitive(exec, preferredType);
+        return isCell() ? asCell()->toPrimitive(exec, preferredType) : asValue();
     }
 
-    inline bool JSValuePtr::getPrimitiveNumber(ExecState* exec, double& number, JSValuePtr& value)
+    inline bool JSValue::getPrimitiveNumber(ExecState* exec, double& number, JSValue& value)
     {
-        if (JSImmediate::isImmediate(asValue())) {
-            number = JSImmediate::toDouble(asValue());
-            value = asValue();
+        if (isInt32()) {
+            number = asInt32();
+            value = *this;
+            return true;
+        }
+        if (isDouble()) {
+            number = asDouble();
+            value = *this;
+            return true;
+        }
+        if (isCell())
+            return asCell()->getPrimitiveNumber(exec, number, value);
+        if (isTrue()) {
+            number = 1.0;
+            value = *this;
+            return true;
+        }
+        if (isFalse() || isNull()) {
+            number = 0.0;
+            value = *this;
             return true;
         }
-        return asCell()->getPrimitiveNumber(exec, number, value);
+        ASSERT(isUndefined());
+        number = nonInlineNaN();
+        value = *this;
+        return true;
     }
 
-    inline bool JSValuePtr::toBoolean(ExecState* exec) const
+    inline bool JSValue::toBoolean(ExecState* exec) const
     {
-        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toBoolean(asValue()) : asCell()->toBoolean(exec);
+        if (isInt32())
+            return asInt32() != 0;
+        if (isDouble())
+            return asDouble() > 0.0 || asDouble() < 0.0; // false for NaN
+        if (isCell())
+            return asCell()->toBoolean(exec);
+        return isTrue(); // false, null, and undefined all convert to false.
     }
 
-    ALWAYS_INLINE double JSValuePtr::toNumber(ExecState* exec) const
+    ALWAYS_INLINE double JSValue::toNumber(ExecState* exec) const
     {
-        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asCell()->toNumber(exec);
+        if (isInt32())
+            return asInt32();
+        if (isDouble())
+            return asDouble();
+        if (isCell())
+            return asCell()->toNumber(exec);
+        if (isTrue())
+            return 1.0;
+        return isUndefined() ? nonInlineNaN() : 0; // null and false both convert to 0.
     }
 
-    inline UString JSValuePtr::toString(ExecState* exec) const
+    inline UString JSValue::toString(ExecState* exec) const
     {
-        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toString(exec);
+        if (isCell())
+            return asCell()->toString(exec);
+        if (isInt32())
+            return UString::from(asInt32());
+        if (isDouble())
+            return asDouble() == 0.0 ? "0" : UString::from(asDouble());
+        if (isTrue())
+            return "true";
+        if (isFalse())
+            return "false";
+        if (isNull())
+            return "null";
+        ASSERT(isUndefined());
+        return "undefined";
     }
 
-    inline JSObject* JSValuePtr::toObject(ExecState* exec) const
+    inline bool JSValue::needsThisConversion() const
     {
-        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toObject(asValue(), exec) : asCell()->toObject(exec);
+        if (UNLIKELY(!isCell()))
+            return true;
+        return asCell()->structure()->typeInfo().needsThisConversion();
     }
 
-    inline JSObject* JSValuePtr::toThisObject(ExecState* exec) const
+    inline UString JSValue::toThisString(ExecState* exec) const
     {
-        if (UNLIKELY(JSImmediate::isImmediate(asValue())))
-            return JSImmediate::toThisObject(asValue(), exec);
-        return asCell()->toThisObject(exec);
+        return isCell() ? asCell()->toThisString(exec) : toString(exec);
     }
 
-    inline bool JSValuePtr::needsThisConversion() const
+    inline JSValue JSValue::getJSNumber()
     {
-        if (UNLIKELY(JSImmediate::isImmediate(asValue())))
-            return true;
-        return asCell()->structure()->typeInfo().needsThisConversion();
+        if (isInt32() || isDouble())
+            return *this;
+        if (isCell())
+            return asCell()->getJSNumber();
+        return JSValue();
     }
 
-    inline UString JSValuePtr::toThisString(ExecState* exec) const
+    inline JSObject* JSValue::toObject(ExecState* exec) const
     {
-        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toString(asValue()) : asCell()->toThisString(exec);
+        return isCell() ? asCell()->toObject(exec) : toObjectSlowCase(exec);
     }
 
-    inline JSValuePtr JSValuePtr::getJSNumber()
+    inline JSObject* JSValue::toThisObject(ExecState* exec) const
     {
-        return JSImmediate::isNumber(asValue()) ? asValue() : JSImmediate::isImmediate(asValue()) ? noValue() : asCell()->getJSNumber();
+        return isCell() ? asCell()->toThisObject(exec) : toThisObjectSlowCase(exec);
     }
 
 } // namespace JSC
index cb18115428ab9f6576649705b212b911a21edf29..7fedad7cd22a428b1aa10489372357f0b2b5474e 100644 (file)
@@ -45,68 +45,100 @@ ASSERT_CLASS_FITS_IN_CELL(JSFunction);
 
 const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 };
 
+JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
+    : Base(&exec->globalData(), structure, name)
+#if ENABLE(JIT)
+    , m_body(FunctionBodyNode::createNativeThunk(&exec->globalData()))
+#else
+    , m_body(0)
+#endif
+{
+#if ENABLE(JIT)
+    setNativeFunction(func);
+    putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
+#else
+    UNUSED_PARAM(length);
+    UNUSED_PARAM(func);
+    ASSERT_NOT_REACHED();
+#endif
+}
+
 JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* body, ScopeChainNode* scopeChainNode)
     : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name)
     , m_body(body)
-    , m_scopeChain(scopeChainNode)
 {
+    setScopeChain(scopeChainNode);
 }
 
 JSFunction::~JSFunction()
 {
-#if ENABLE(JIT) 
     // JIT code for other functions may have had calls linked directly to the code for this function; these links
     // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once
     // this memory is freed and may be reused (potentially for another, different JSFunction).
+#if ENABLE(JIT_OPTIMIZE_CALL)
     if (m_body && m_body->isGenerated())
         m_body->generatedBytecode().unlinkCallers();
 #endif
+    if (!isHostFunction())
+        scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too?
 }
 
 void JSFunction::mark()
 {
     Base::mark();
     m_body->mark();
-    m_scopeChain.mark();
+    if (!isHostFunction())
+        scopeChain().mark();
 }
 
 CallType JSFunction::getCallData(CallData& callData)
 {
+    if (isHostFunction()) {
+        callData.native.function = nativeFunction();
+        return CallTypeHost;
+    }
     callData.js.functionBody = m_body.get();
-    callData.js.scopeChain = m_scopeChain.node();
+    callData.js.scopeChain = scopeChain().node();
     return CallTypeJS;
 }
 
-JSValuePtr JSFunction::call(ExecState* exec, JSValuePtr thisValue, const ArgList& args)
+JSValue JSFunction::call(ExecState* exec, JSValue thisValue, const ArgList& args)
 {
-    return exec->interpreter()->execute(m_body.get(), exec, this, thisValue.toThisObject(exec), args, m_scopeChain.node(), exec->exceptionSlot());
+    ASSERT(!isHostFunction());
+    return exec->interpreter()->execute(m_body.get(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
 }
 
-JSValuePtr JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     JSFunction* thisObj = asFunction(slot.slotBase());
+    ASSERT(!thisObj->isHostFunction());
     return exec->interpreter()->retrieveArguments(exec, thisObj);
 }
 
-JSValuePtr JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     JSFunction* thisObj = asFunction(slot.slotBase());
+    ASSERT(!thisObj->isHostFunction());
     return exec->interpreter()->retrieveCaller(exec, thisObj);
 }
 
-JSValuePtr JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     JSFunction* thisObj = asFunction(slot.slotBase());
+    ASSERT(!thisObj->isHostFunction());
     return jsNumber(exec, thisObj->m_body->parameterCount());
 }
 
 bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 {
+    if (isHostFunction())
+        return Base::getOwnPropertySlot(exec, propertyName, slot);
+
     if (propertyName == exec->propertyNames().prototype) {
-        JSValuePtr* location = getDirectLocation(propertyName);
+        JSValue* location = getDirectLocation(propertyName);
 
         if (!location) {
-            JSObject* prototype = new (exec) JSObject(m_scopeChain.globalObject()->emptyObjectStructure());
+            JSObject* prototype = new (exec) JSObject(scopeChain().globalObject()->emptyObjectStructure());
             prototype->putDirect(exec->propertyNames().constructor, this, DontEnum);
             putDirect(exec->propertyNames().prototype, prototype, DontDelete);
             location = getDirectLocation(propertyName);
@@ -133,8 +165,12 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
     return Base::getOwnPropertySlot(exec, propertyName, slot);
 }
 
-void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
+    if (isHostFunction()) {
+        Base::put(exec, propertyName, value, slot);
+        return;
+    }
     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
         return;
     Base::put(exec, propertyName, value, slot);
@@ -142,6 +178,8 @@ void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValuePtr
 
 bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
 {
+    if (isHostFunction())
+        return Base::deleteProperty(exec, propertyName);
     if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
         return false;
     return Base::deleteProperty(exec, propertyName);
@@ -150,22 +188,25 @@ bool JSFunction::deleteProperty(ExecState* exec, const Identifier& propertyName)
 // ECMA 13.2.2 [[Construct]]
 ConstructType JSFunction::getConstructData(ConstructData& constructData)
 {
+    if (isHostFunction())
+        return ConstructTypeNone;
     constructData.js.functionBody = m_body.get();
-    constructData.js.scopeChain = m_scopeChain.node();
+    constructData.js.scopeChain = scopeChain().node();
     return ConstructTypeJS;
 }
 
 JSObject* JSFunction::construct(ExecState* exec, const ArgList& args)
 {
+    ASSERT(!isHostFunction());
     Structure* structure;
-    JSValuePtr prototype = get(exec, exec->propertyNames().prototype);
+    JSValue prototype = get(exec, exec->propertyNames().prototype);
     if (prototype.isObject())
         structure = asObject(prototype)->inheritorID();
     else
         structure = exec->lexicalGlobalObject()->emptyObjectStructure();
     JSObject* thisObj = new (exec) JSObject(structure);
 
-    JSValuePtr result = exec->interpreter()->execute(m_body.get(), exec, this, thisObj, args, m_scopeChain.node(), exec->exceptionSlot());
+    JSValue result = exec->interpreter()->execute(m_body.get(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot());
     if (exec->hadException() || !result.isObject())
         return thisObj;
     return asObject(result);
index 6a43737ad77ec78d3f9f3f6aba40f479e77aa4d6..b27e5157f766fef164745420d800e907c942936b 100644 (file)
@@ -39,29 +39,30 @@ namespace JSC {
 
     class JSFunction : public InternalFunction {
         friend class JIT;
-        friend class Interpreter;
+        friend class VPtrSet;
 
         typedef InternalFunction Base;
 
         JSFunction(PassRefPtr<Structure> structure)
             : InternalFunction(structure)
-            , m_scopeChain(NoScopeChain())
         {
+            clearScopeChain();
         }
 
     public:
+        JSFunction(ExecState*, PassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
         JSFunction(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
         ~JSFunction();
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-        virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
 
         JSObject* construct(ExecState*, const ArgList&);
-        JSValuePtr call(ExecState*, JSValuePtr thisValue, const ArgList&);
+        JSValue call(ExecState*, JSValue thisValue, const ArgList&);
 
-        void setScope(const ScopeChain& scopeChain) { m_scopeChain = scopeChain; }
-        ScopeChain& scope() { return m_scopeChain; }
+        void setScope(const ScopeChain& scopeChain) { setScopeChain(scopeChain); }
+        ScopeChain& scope() { return scopeChain(); }
 
         void setBody(FunctionBodyNode* body) { m_body = body; }
         void setBody(PassRefPtr<FunctionBodyNode> body) { m_body = body; }
@@ -69,30 +70,64 @@ namespace JSC {
 
         virtual void mark();
 
-        static const ClassInfo info;
+        static JS_EXPORTDATA const ClassInfo info;
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype) 
+        static PassRefPtr<Structure> createStructure(JSValue prototype) 
         { 
             return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance)); 
         }
 
-    private:
-        virtual const ClassInfo* classInfo() const { return &info; }
+#if ENABLE(JIT)
+        bool isHostFunction() const { return m_body && m_body->isHostFunction(); }
+#else
+        bool isHostFunction() const { return false; }
+#endif
+        NativeFunction nativeFunction()
+        {
+            return *reinterpret_cast<NativeFunction*>(m_data);
+        }
 
         virtual ConstructType getConstructData(ConstructData&);
         virtual CallType getCallData(CallData&);
 
-        static JSValuePtr argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
-        static JSValuePtr callerGetter(ExecState*, const Identifier&, const PropertySlot&);
-        static JSValuePtr lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
+    private:
+        virtual const ClassInfo* classInfo() const { return &info; }
+
+        static JSValue argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
+        static JSValue callerGetter(ExecState*, const Identifier&, const PropertySlot&);
+        static JSValue lengthGetter(ExecState*, const Identifier&, const PropertySlot&);
 
         RefPtr<FunctionBodyNode> m_body;
-        ScopeChain m_scopeChain;
+        ScopeChain& scopeChain()
+        {
+            ASSERT(!isHostFunction());
+            return *reinterpret_cast<ScopeChain*>(m_data);
+        }
+        void clearScopeChain()
+        {
+            ASSERT(!isHostFunction());
+            new (m_data) ScopeChain(NoScopeChain());
+        }
+        void setScopeChain(ScopeChainNode* sc)
+        {
+            ASSERT(!isHostFunction());
+            new (m_data) ScopeChain(sc);
+        }
+        void setScopeChain(const ScopeChain& sc)
+        {
+            ASSERT(!isHostFunction());
+            *reinterpret_cast<ScopeChain*>(m_data) = sc;
+        }
+        void setNativeFunction(NativeFunction func)
+        {
+            *reinterpret_cast<NativeFunction*>(m_data) = func;
+        }
+        unsigned char m_data[sizeof(void*)];
     };
 
-    JSFunction* asFunction(JSValuePtr);
+    JSFunction* asFunction(JSValue);
 
-    inline JSFunction* asFunction(JSValuePtr value)
+    inline JSFunction* asFunction(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&JSFunction::info));
         return static_cast<JSFunction*>(asObject(value));
index 10b584d9a8d3e2dcef14ca3ff17e3ac97866f0be..156d1023bfc20b4d8d2583005db46f6e7fb4a5d1 100644 (file)
 #include "FunctionConstructor.h"
 #include "Interpreter.h"
 #include "JSActivation.h"
+#include "JSArray.h"
+#include "JSByteArray.h"
 #include "JSClassRef.h"
+#include "JSFunction.h"
 #include "JSLock.h"
 #include "JSNotAnObject.h"
 #include "JSStaticScopeObject.h"
@@ -56,52 +59,91 @@ using namespace WTF;
 
 namespace JSC {
 
-extern const HashTable arrayTable;
-extern const HashTable dateTable;
-extern const HashTable mathTable;
-extern const HashTable numberTable;
-extern const HashTable regExpTable;
-extern const HashTable regExpConstructorTable;
-extern const HashTable stringTable;
+extern JSC_CONST_HASHTABLE HashTable arrayTable;
+extern JSC_CONST_HASHTABLE HashTable jsonTable;
+extern JSC_CONST_HASHTABLE HashTable dateTable;
+extern JSC_CONST_HASHTABLE HashTable mathTable;
+extern JSC_CONST_HASHTABLE HashTable numberTable;
+extern JSC_CONST_HASHTABLE HashTable regExpTable;
+extern JSC_CONST_HASHTABLE HashTable regExpConstructorTable;
+extern JSC_CONST_HASHTABLE HashTable stringTable;
+
+struct VPtrSet {
+    VPtrSet();
+
+    void* jsArrayVPtr;
+    void* jsByteArrayVPtr;
+    void* jsStringVPtr;
+    void* jsFunctionVPtr;
+};
+
+VPtrSet::VPtrSet()
+{
+    // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
+    void* storage = fastMalloc(sizeof(CollectorBlock));
 
-JSGlobalData::JSGlobalData(bool isShared)
-    : initializingLazyNumericCompareFunction(false)
-    , interpreter(new Interpreter)
-    , exception(noValue())
-    , arrayTable(new HashTable(JSC::arrayTable))
-    , dateTable(new HashTable(JSC::dateTable))
-    , mathTable(new HashTable(JSC::mathTable))
-    , numberTable(new HashTable(JSC::numberTable))
-    , regExpTable(new HashTable(JSC::regExpTable))
-    , regExpConstructorTable(new HashTable(JSC::regExpConstructorTable))
-    , stringTable(new HashTable(JSC::stringTable))
+    JSCell* jsArray = new (storage) JSArray(JSArray::createStructure(jsNull()));
+    jsArrayVPtr = jsArray->vptr();
+    jsArray->~JSCell();
+
+    JSCell* jsByteArray = new (storage) JSByteArray(JSByteArray::VPtrStealingHack);
+    jsByteArrayVPtr = jsByteArray->vptr();
+    jsByteArray->~JSCell();
+
+    JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
+    jsStringVPtr = jsString->vptr();
+    jsString->~JSCell();
+
+    JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructure(jsNull()));
+    jsFunctionVPtr = jsFunction->vptr();
+    jsFunction->~JSCell();
+
+    fastFree(storage);
+}
+
+JSGlobalData::JSGlobalData(bool isShared, const VPtrSet& vptrSet)
+    : isSharedInstance(isShared)
+    , clientData(0)
+    , arrayTable(fastNew<HashTable>(JSC::arrayTable))
+    , dateTable(fastNew<HashTable>(JSC::dateTable))
+    , jsonTable(fastNew<HashTable>(JSC::jsonTable))
+    , mathTable(fastNew<HashTable>(JSC::mathTable))
+    , numberTable(fastNew<HashTable>(JSC::numberTable))
+    , regExpTable(fastNew<HashTable>(JSC::regExpTable))
+    , regExpConstructorTable(fastNew<HashTable>(JSC::regExpConstructorTable))
+    , stringTable(fastNew<HashTable>(JSC::stringTable))
     , activationStructure(JSActivation::createStructure(jsNull()))
     , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
     , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
     , stringStructure(JSString::createStructure(jsNull()))
     , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
     , notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
-#if !USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE32)
     , numberStructure(JSNumberCell::createStructure(jsNull()))
 #endif
+    , jsArrayVPtr(vptrSet.jsArrayVPtr)
+    , jsByteArrayVPtr(vptrSet.jsByteArrayVPtr)
+    , jsStringVPtr(vptrSet.jsStringVPtr)
+    , jsFunctionVPtr(vptrSet.jsFunctionVPtr)
     , identifierTable(createIdentifierTable())
     , propertyNames(new CommonIdentifiers(this))
-    , emptyList(new ArgList)
-    , newParserObjects(0)
-    , parserObjectExtraRefCounts(0)
+    , emptyList(new MarkedArgumentBuffer)
     , lexer(new Lexer(this))
     , parser(new Parser)
+    , interpreter(new Interpreter)
+#if ENABLE(JIT)
+    , jitStubs(this)
+#endif
+    , heap(this)
+    , initializingLazyNumericCompareFunction(false)
     , head(0)
     , dynamicGlobalObject(0)
-    , isSharedInstance(isShared)
-    , clientData(0)
     , scopeNodeBeingReparsed(0)
-    , heap(this)
+    , firstStringifierToMark(0)
 {
 #if PLATFORM(MAC)
     startProfilerServerIfNeeded();
 #endif
-    interpreter->initialize(this);
 }
 
 JSGlobalData::~JSGlobalData()
@@ -116,18 +158,21 @@ JSGlobalData::~JSGlobalData()
 
     arrayTable->deleteTable();
     dateTable->deleteTable();
+    jsonTable->deleteTable();
     mathTable->deleteTable();
     numberTable->deleteTable();
     regExpTable->deleteTable();
     regExpConstructorTable->deleteTable();
     stringTable->deleteTable();
-    delete arrayTable;
-    delete dateTable;
-    delete mathTable;
-    delete numberTable;
-    delete regExpTable;
-    delete regExpConstructorTable;
-    delete stringTable;
+
+    fastDelete(const_cast<HashTable*>(arrayTable));
+    fastDelete(const_cast<HashTable*>(dateTable));
+    fastDelete(const_cast<HashTable*>(jsonTable));
+    fastDelete(const_cast<HashTable*>(mathTable));
+    fastDelete(const_cast<HashTable*>(numberTable));
+    fastDelete(const_cast<HashTable*>(regExpTable));
+    fastDelete(const_cast<HashTable*>(regExpConstructorTable));
+    fastDelete(const_cast<HashTable*>(stringTable));
 
     delete parser;
     delete lexer;
@@ -139,27 +184,20 @@ JSGlobalData::~JSGlobalData()
     delete propertyNames;
     deleteIdentifierTable(identifierTable);
 
-    delete newParserObjects;
-    delete parserObjectExtraRefCounts;
-    
     delete clientData;
 }
 
-PassRefPtr<JSGlobalData> JSGlobalData::create()
+PassRefPtr<JSGlobalData> JSGlobalData::create(bool isShared)
 {
-    return adoptRef(new JSGlobalData);
+    return adoptRef(new JSGlobalData(isShared, VPtrSet()));
 }
 
 PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
 {
-#ifndef NDEBUG
     Structure::startIgnoringLeaks();
     RefPtr<JSGlobalData> data = create();
     Structure::stopIgnoringLeaks();
     return data.release();
-#else
-    return create();
-#endif
 }
 
 bool JSGlobalData::sharedInstanceExists()
@@ -171,7 +209,7 @@ JSGlobalData& JSGlobalData::sharedInstance()
 {
     JSGlobalData*& instance = sharedInstanceInternal();
     if (!instance) {
-        instance = new JSGlobalData(true);
+        instance = create(true).releaseRef();
 #if ENABLE(JSC_MULTIPLE_THREADS)
         instance->makeUsableFromMultipleThreads();
 #endif
index 42231911fc0843f60a796a61c168abb201df122b..5e487f93a34610eba1fa50ab5d82f3fe934aa197 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef JSGlobalData_h
 #define JSGlobalData_h
 
-#include <wtf/Forward.h>
-#include <wtf/HashMap.h>
-#include <wtf/RefCounted.h>
 #include "Collector.h"
 #include "ExecutableAllocator.h"
-#include "SmallStrings.h"
+#include "JITStubs.h"
 #include "JSValue.h"
+#include "SmallStrings.h"
+#include "TimeoutChecker.h"
+#include <wtf/Forward.h>
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
 
 struct OpaqueJSClass;
 struct OpaqueJSClassContextData;
 
 namespace JSC {
 
-    class ArgList;
     class CommonIdentifiers;
-    class Heap;
+    class FunctionBodyNode;
     class IdentifierTable;
     class Instruction;
     class Interpreter;
@@ -52,18 +53,24 @@ namespace JSC {
     class JSObject;
     class Lexer;
     class Parser;
-    class ParserRefCounted;
     class ScopeNode;
+    class Stringifier;
     class Structure;
     class UString;
+
     struct HashTable;
+    struct VPtrSet;
 
     class JSGlobalData : public RefCounted<JSGlobalData> {
     public:
+        struct ClientData {
+            virtual ~ClientData() = 0;
+        };
+
         static bool sharedInstanceExists();
         static JSGlobalData& sharedInstance();
 
-        static PassRefPtr<JSGlobalData> create();
+        static PassRefPtr<JSGlobalData> create(bool isShared = false);
         static PassRefPtr<JSGlobalData> createLeaked();
         ~JSGlobalData();
 
@@ -72,19 +79,12 @@ namespace JSC {
         void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
 #endif
 
-        const Vector<Instruction>& numericCompareFunction(ExecState*);
-        Vector<Instruction> lazyNumericCompareFunction;
-        bool initializingLazyNumericCompareFunction;
-
-        Interpreter* interpreter;
-
-        JSValuePtr exception;
-#if ENABLE(JIT)
-        void* exceptionLocation;
-#endif
+        bool isSharedInstance;
+        ClientData* clientData;
 
         const HashTable* arrayTable;
         const HashTable* dateTable;
+        const HashTable* jsonTable;
         const HashTable* mathTable;
         const HashTable* numberTable;
         const HashTable* regExpTable;
@@ -97,52 +97,58 @@ namespace JSC {
         RefPtr<Structure> stringStructure;
         RefPtr<Structure> notAnObjectErrorStubStructure;
         RefPtr<Structure> notAnObjectStructure;
-#if !USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE32)
         RefPtr<Structure> numberStructure;
 #endif
 
+        void* jsArrayVPtr;
+        void* jsByteArrayVPtr;
+        void* jsStringVPtr;
+        void* jsFunctionVPtr;
+
         IdentifierTable* identifierTable;
         CommonIdentifiers* propertyNames;
-        const ArgList* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
-
+        const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
         SmallStrings smallStrings;
-        
-        HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
 
-        HashSet<ParserRefCounted*>* newParserObjects;
-        HashCountedSet<ParserRefCounted*>* parserObjectExtraRefCounts;
+#if ENABLE(ASSEMBLER)
+        ExecutableAllocator executableAllocator;
+#endif
 
         Lexer* lexer;
         Parser* parser;
+        Interpreter* interpreter;
+#if ENABLE(JIT)
+        JITThunks jitStubs;
+#endif
+        TimeoutChecker timeoutChecker;
+        Heap heap;
 
-        JSGlobalObject* head;
-        JSGlobalObject* dynamicGlobalObject;
+        JSValue exception;
+#if ENABLE(JIT)
+        ReturnAddressPtr exceptionLocation;
+#endif
 
-        bool isSharedInstance;
+        const Vector<Instruction>& numericCompareFunction(ExecState*);
+        Vector<Instruction> lazyNumericCompareFunction;
+        bool initializingLazyNumericCompareFunction;
 
-        struct ClientData {
-            virtual ~ClientData() = 0;
-        };
+        HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
 
-        ClientData* clientData;
+        JSGlobalObject* head;
+        JSGlobalObject* dynamicGlobalObject;
 
         HashSet<JSObject*> arrayVisitedElements;
 
         ScopeNode* scopeNodeBeingReparsed;
+        Stringifier* firstStringifierToMark;
 
-        Heap heap;
-#if ENABLE(ASSEMBLER)
-        PassRefPtr<ExecutablePool> poolForSize(size_t n) { return m_executableAllocator.poolForSize(n); }
-#endif
     private:
-        JSGlobalData(bool isShared = false);
-#if ENABLE(ASSEMBLER)
-        ExecutableAllocator m_executableAllocator;
-#endif
-
+        JSGlobalData(bool isShared, const VPtrSet&);
         static JSGlobalData*& sharedInstanceInternal();
+        void createNativeThunk();
     };
 
-}
+} // namespace JSC
 
-#endif
+#endif // JSGlobalData_h
index eb2b349459d173777d792041274f349fe841d8ad..c56b84b0e7a46b5b46aff060ce3258daa3cc8d34 100644 (file)
 #include "FunctionConstructor.h"
 #include "FunctionPrototype.h"
 #include "GlobalEvalFunction.h"
+#include "JSFunction.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSLock.h"
+#include "JSONObject.h"
 #include "Interpreter.h"
 #include "MathObject.h"
 #include "NativeErrorConstructor.h"
@@ -78,7 +80,7 @@ static const int initialTickCountThreshold = 255;
 // Preferred number of milliseconds between each timeout check
 static const int preferredScriptCheckTimeInterval = 1000;
 
-static inline void markIfNeeded(JSValuePtr v)
+static inline void markIfNeeded(JSValue v)
 {
     if (v && !v.marked())
         v.mark();
@@ -147,7 +149,7 @@ void JSGlobalObject::init(JSObject* thisValue)
     reset(prototype());
 }
 
-void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
@@ -156,20 +158,20 @@ void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValu
     JSVariableObject::put(exec, propertyName, value, slot);
 }
 
-void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+void JSGlobalObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
 {
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
     if (symbolTablePutWithAttributes(propertyName, value, attributes))
         return;
 
-    JSValuePtr valueBefore = getDirect(propertyName);
+    JSValue valueBefore = getDirect(propertyName);
     PutPropertySlot slot;
     JSVariableObject::put(exec, propertyName, value, slot);
     if (!valueBefore) {
-        JSValuePtr valueAfter = getDirect(propertyName);
+        JSValue valueAfter = getDirect(propertyName);
         if (valueAfter)
-            putDirect(propertyName, valueAfter, attributes);
+            JSObject::putWithAttributes(exec, propertyName, valueAfter, attributes);
     }
 }
 
@@ -195,7 +197,7 @@ static inline JSObject* lastInPrototypeChain(JSObject* object)
     return o;
 }
 
-void JSGlobalObject::reset(JSValuePtr prototype)
+void JSGlobalObject::reset(JSValue prototype)
 {
     ExecState* exec = JSGlobalObject::globalExec();
 
@@ -203,7 +205,11 @@ void JSGlobalObject::reset(JSValuePtr prototype)
 
     d()->functionPrototype = new (exec) FunctionPrototype(exec, FunctionPrototype::createStructure(jsNull())); // The real prototype will be set once ObjectPrototype is created.
     d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype);
-    d()->functionPrototype->addFunctionProperties(exec, d()->prototypeFunctionStructure.get());
+    NativeFunctionWrapper* callFunction = 0;
+    NativeFunctionWrapper* applyFunction = 0;
+    d()->functionPrototype->addFunctionProperties(exec, d()->prototypeFunctionStructure.get(), &callFunction, &applyFunction);
+    d()->callFunction = callFunction;
+    d()->applyFunction = applyFunction;
     d()->objectPrototype = new (exec) ObjectPrototype(exec, ObjectPrototype::createStructure(jsNull()), d()->prototypeFunctionStructure.get());
     d()->functionPrototype->structure()->setPrototypeWithoutTransition(d()->objectPrototype);
 
@@ -234,6 +240,8 @@ void JSGlobalObject::reset(JSValuePtr prototype)
     d()->regExpPrototype = new (exec) RegExpPrototype(exec, RegExpPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
     d()->regExpStructure = RegExpObject::createStructure(d()->regExpPrototype);
 
+    d()->methodCallDummy = constructEmptyObject(exec);
+
     ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
     d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
 
@@ -248,13 +256,13 @@ void JSGlobalObject::reset(JSValuePtr prototype)
 
     // Constructors
 
-    JSValuePtr objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype);
-    JSValuePtr functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);
-    JSValuePtr arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype);
-    JSValuePtr stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
-    JSValuePtr booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);
-    JSValuePtr numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);
-    JSValuePtr dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);
+    JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype);
+    JSCell* functionConstructor = new (exec) FunctionConstructor(exec, FunctionConstructor::createStructure(d()->functionPrototype), d()->functionPrototype);
+    JSCell* arrayConstructor = new (exec) ArrayConstructor(exec, ArrayConstructor::createStructure(d()->functionPrototype), d()->arrayPrototype);
+    JSCell* stringConstructor = new (exec) StringConstructor(exec, StringConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->stringPrototype);
+    JSCell* booleanConstructor = new (exec) BooleanConstructor(exec, BooleanConstructor::createStructure(d()->functionPrototype), d()->booleanPrototype);
+    JSCell* numberConstructor = new (exec) NumberConstructor(exec, NumberConstructor::createStructure(d()->functionPrototype), d()->numberPrototype);
+    JSCell* dateConstructor = new (exec) DateConstructor(exec, DateConstructor::createStructure(d()->functionPrototype), d()->prototypeFunctionStructure.get(), d()->datePrototype);
 
     d()->regExpConstructor = new (exec) RegExpConstructor(exec, RegExpConstructor::createStructure(d()->functionPrototype), d()->regExpPrototype);
 
@@ -269,15 +277,15 @@ void JSGlobalObject::reset(JSValuePtr prototype)
     d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, typeErrorPrototype);
     d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype);
 
-    d()->objectPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
-    d()->functionPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
-    d()->arrayPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, arrayConstructor, DontEnum);
-    d()->booleanPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, booleanConstructor, DontEnum);
-    d()->stringPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, stringConstructor, DontEnum);
-    d()->numberPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, numberConstructor, DontEnum);
-    d()->datePrototype->putDirectWithoutTransition(exec->propertyNames().constructor, dateConstructor, DontEnum);
-    d()->regExpPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
-    errorPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);
+    d()->objectPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
+    d()->functionPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
+    d()->arrayPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, arrayConstructor, DontEnum);
+    d()->booleanPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, booleanConstructor, DontEnum);
+    d()->stringPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, stringConstructor, DontEnum);
+    d()->numberPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, numberConstructor, DontEnum);
+    d()->datePrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, dateConstructor, DontEnum);
+    d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
+    errorPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, DontEnum);
 
     evalErrorPrototype->putDirect(exec->propertyNames().constructor, d()->evalErrorConstructor, DontEnum);
     rangeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->rangeErrorConstructor, DontEnum);
@@ -290,28 +298,29 @@ void JSGlobalObject::reset(JSValuePtr prototype)
 
     // FIXME: These properties could be handled by a static hash table.
 
-    putDirectWithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum);
-    putDirectWithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum);
-    putDirectWithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum);
-    putDirectWithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
-    putDirectWithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum);
-    putDirectWithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum);
-    putDirectWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum);
-    putDirectWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);
-    putDirectWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);
-    putDirectWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor);
-    putDirectWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor);
-    putDirectWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor);
-    putDirectWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor);
-    putDirectWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor);
-    putDirectWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor);
+    putDirectFunctionWithoutTransition(Identifier(exec, "Object"), objectConstructor, DontEnum);
+    putDirectFunctionWithoutTransition(Identifier(exec, "Function"), functionConstructor, DontEnum);
+    putDirectFunctionWithoutTransition(Identifier(exec, "Array"), arrayConstructor, DontEnum);
+    putDirectFunctionWithoutTransition(Identifier(exec, "Boolean"), booleanConstructor, DontEnum);
+    putDirectFunctionWithoutTransition(Identifier(exec, "String"), stringConstructor, DontEnum);
+    putDirectFunctionWithoutTransition(Identifier(exec, "Number"), numberConstructor, DontEnum);
+    putDirectFunctionWithoutTransition(Identifier(exec, "Date"), dateConstructor, DontEnum);
+    putDirectFunctionWithoutTransition(Identifier(exec, "RegExp"), d()->regExpConstructor, DontEnum);
+    putDirectFunctionWithoutTransition(Identifier(exec, "Error"), d()->errorConstructor, DontEnum);
+    putDirectFunctionWithoutTransition(Identifier(exec, "EvalError"), d()->evalErrorConstructor);
+    putDirectFunctionWithoutTransition(Identifier(exec, "RangeError"), d()->rangeErrorConstructor);
+    putDirectFunctionWithoutTransition(Identifier(exec, "ReferenceError"), d()->referenceErrorConstructor);
+    putDirectFunctionWithoutTransition(Identifier(exec, "SyntaxError"), d()->syntaxErrorConstructor);
+    putDirectFunctionWithoutTransition(Identifier(exec, "TypeError"), d()->typeErrorConstructor);
+    putDirectFunctionWithoutTransition(Identifier(exec, "URIError"), d()->URIErrorConstructor);
 
     // Set global values.
     GlobalPropertyInfo staticGlobals[] = {
         GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, MathObject::createStructure(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)
+        GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete),
+        GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(JSONObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete)
     };
 
     addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo));
@@ -320,43 +329,32 @@ void JSGlobalObject::reset(JSValuePtr prototype)
 
     d()->evalFunction = new (exec) GlobalEvalFunction(exec, GlobalEvalFunction::createStructure(d()->functionPrototype), 1, exec->propertyNames().eval, globalFuncEval, this);
     putDirectFunctionWithoutTransition(exec, d()->evalFunction, DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 2, Identifier(exec, "parseInt"), globalFuncParseInt), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "parseFloat"), globalFuncParseFloat), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isNaN"), globalFuncIsNaN), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "isFinite"), globalFuncIsFinite), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "escape"), globalFuncEscape), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "unescape"), globalFuncUnescape), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURI"), globalFuncDecodeURI), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "decodeURIComponent"), globalFuncDecodeURIComponent), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURI"), globalFuncEncodeURI), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "encodeURIComponent"), globalFuncEncodeURIComponent), DontEnum);
 #ifndef NDEBUG
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, d()->prototypeFunctionStructure.get(), 1, Identifier(exec, "jscprint"), globalFuncJSCPrint), DontEnum);
 #endif
 
     resetPrototype(prototype);
 }
 
 // Set prototype, and also insert the object prototype at the end of the chain.
-void JSGlobalObject::resetPrototype(JSValuePtr prototype)
+void JSGlobalObject::resetPrototype(JSValue prototype)
 {
     setPrototype(prototype);
-    lastInPrototypeChain(this)->setPrototype(d()->objectPrototype);
-}
-
-void JSGlobalObject::setTimeoutTime(unsigned timeoutTime)
-{
-    globalData()->interpreter->setTimeoutTime(timeoutTime);
-}
 
-void JSGlobalObject::startTimeoutCheck()
-{
-    globalData()->interpreter->startTimeoutCheck();
-}
-
-void JSGlobalObject::stopTimeoutCheck()
-{
-    globalData()->interpreter->stopTimeoutCheck();
+    JSObject* oldLastInPrototypeChain = lastInPrototypeChain(this);
+    JSObject* objectPrototype = d()->objectPrototype;
+    if (oldLastInPrototypeChain != objectPrototype)
+        oldLastInPrototypeChain->setPrototype(objectPrototype);
 }
 
 void JSGlobalObject::mark()
@@ -381,6 +379,8 @@ void JSGlobalObject::mark()
     markIfNeeded(d()->URIErrorConstructor);
 
     markIfNeeded(d()->evalFunction);
+    markIfNeeded(d()->callFunction);
+    markIfNeeded(d()->applyFunction);
 
     markIfNeeded(d()->objectPrototype);
     markIfNeeded(d()->functionPrototype);
@@ -391,6 +391,8 @@ void JSGlobalObject::mark()
     markIfNeeded(d()->datePrototype);
     markIfNeeded(d()->regExpPrototype);
 
+    markIfNeeded(d()->methodCallDummy);
+
     markIfNeeded(d()->errorStructure);
 
     // No need to mark the other structures, because their prototypes are all
index f6548c9707022872cac33c49a2801f0141c60871..bad3a45a9f9f5e59a79b96c25e5b5b93aac1ee4f 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "JSGlobalData.h"
 #include "JSVariableObject.h"
+#include "NativeFunctionWrapper.h"
 #include "NumberPrototype.h"
 #include "StringPrototype.h"
 #include <wtf/HashSet.h>
@@ -40,6 +41,7 @@ namespace JSC {
     class GlobalEvalFunction;
     class NativeErrorConstructor;
     class ProgramCodeBlock;
+    class PrototypeFunction;
     class RegExpConstructor;
     class RegExpPrototype;
     class RegisterFile;
@@ -67,6 +69,8 @@ namespace JSC {
                 , typeErrorConstructor(0)
                 , URIErrorConstructor(0)
                 , evalFunction(0)
+                , callFunction(0)
+                , applyFunction(0)
                 , objectPrototype(0)
                 , functionPrototype(0)
                 , arrayPrototype(0)
@@ -75,6 +79,7 @@ namespace JSC {
                 , numberPrototype(0)
                 , datePrototype(0)
                 , regExpPrototype(0)
+                , methodCallDummy(0)
             {
             }
             
@@ -104,6 +109,8 @@ namespace JSC {
             NativeErrorConstructor* URIErrorConstructor;
 
             GlobalEvalFunction* evalFunction;
+            NativeFunctionWrapper* callFunction;
+            NativeFunctionWrapper* applyFunction;
 
             ObjectPrototype* objectPrototype;
             FunctionPrototype* functionPrototype;
@@ -114,6 +121,8 @@ namespace JSC {
             DatePrototype* datePrototype;
             RegExpPrototype* regExpPrototype;
 
+            JSObject* methodCallDummy;
+
             RefPtr<Structure> argumentsStructure;
             RefPtr<Structure> arrayStructure;
             RefPtr<Structure> booleanObjectStructure;
@@ -160,9 +169,9 @@ namespace JSC {
         virtual void mark();
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
-        virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
-        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes);
+        virtual bool hasOwnPropertyForWrite(ExecState*, const Identifier&);
+        virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
+        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes);
 
         virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunc);
         virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunc);
@@ -195,6 +204,8 @@ namespace JSC {
         DatePrototype* datePrototype() const { return d()->datePrototype; }
         RegExpPrototype* regExpPrototype() const { return d()->regExpPrototype; }
 
+        JSObject* methodCallDummy() const { return d()->methodCallDummy; }
+
         Structure* argumentsStructure() const { return d()->argumentsStructure.get(); }
         Structure* arrayStructure() const { return d()->arrayStructure.get(); }
         Structure* booleanObjectStructure() const { return d()->booleanObjectStructure.get(); }
@@ -214,10 +225,6 @@ namespace JSC {
         void setProfileGroup(unsigned value) { d()->profileGroup = value; }
         unsigned profileGroup() const { return d()->profileGroup; }
 
-        void setTimeoutTime(unsigned timeoutTime);
-        void startTimeoutCheck();
-        void stopTimeoutCheck();
-
         Debugger* debugger() const { return d()->debugger; }
         void setDebugger(Debugger* debugger) { d()->debugger = debugger; }
         
@@ -245,19 +252,19 @@ namespace JSC {
         void copyGlobalsFrom(RegisterFile&);
         void copyGlobalsTo(RegisterFile&);
         
-        void resetPrototype(JSValuePtr prototype);
+        void resetPrototype(JSValue prototype);
 
         JSGlobalData* globalData() { return d()->globalData.get(); }
         JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
             return Structure::create(prototype, TypeInfo(ObjectType));
         }
 
     protected:
         struct GlobalPropertyInfo {
-            GlobalPropertyInfo(const Identifier& i, JSValuePtr v, unsigned a)
+            GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a)
                 : identifier(i)
                 , value(v)
                 , attributes(a)
@@ -265,7 +272,7 @@ namespace JSC {
             }
 
             const Identifier identifier;
-            JSValuePtr value;
+            JSValue value;
             unsigned attributes;
         };
         void addStaticGlobals(GlobalPropertyInfo*, int count);
@@ -273,16 +280,16 @@ namespace JSC {
     private:
         // FIXME: Fold reset into init.
         void init(JSObject* thisValue);
-        void reset(JSValuePtr prototype);
+        void reset(JSValue prototype);
 
         void setRegisters(Register* registers, Register* registerArray, size_t count);
 
         void* operator new(size_t); // can only be allocated with JSGlobalData
     };
 
-    JSGlobalObject* asGlobalObject(JSValuePtr);
+    JSGlobalObject* asGlobalObject(JSValue);
 
-    inline JSGlobalObject* asGlobalObject(JSValuePtr value)
+    inline JSGlobalObject* asGlobalObject(JSValue value)
     {
         ASSERT(asObject(value)->isGlobalObject());
         return static_cast<JSGlobalObject*>(asObject(value));
@@ -319,10 +326,12 @@ namespace JSC {
         return symbolTableGet(propertyName, slot);
     }
 
-    inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
+    inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, const Identifier& propertyName)
     {
-        if (JSVariableObject::getOwnPropertySlotForWrite(exec, propertyName, slot, slotIsWriteable))
+        PropertySlot slot;
+        if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot))
             return true;
+        bool slotIsWriteable;
         return symbolTableGet(propertyName, slot, slotIsWriteable);
     }
 
@@ -334,23 +343,28 @@ namespace JSC {
         return asGlobalObject(n->object);
     }
 
-    inline JSValuePtr Structure::prototypeForLookup(ExecState* exec) const
+    inline JSValue Structure::prototypeForLookup(ExecState* exec) const
     {
         if (typeInfo().type() == ObjectType)
             return m_prototype;
 
+#if USE(JSVALUE32)
         if (typeInfo().type() == StringType)
             return exec->lexicalGlobalObject()->stringPrototype();
 
         ASSERT(typeInfo().type() == NumberType);
         return exec->lexicalGlobalObject()->numberPrototype();
+#else
+        ASSERT(typeInfo().type() == StringType);
+        return exec->lexicalGlobalObject()->stringPrototype();
+#endif
     }
 
     inline StructureChain* Structure::prototypeChain(ExecState* exec) const
     {
         // We cache our prototype chain so our clients can share it.
         if (!isValid(exec, m_cachedPrototypeChain.get())) {
-            JSValuePtr prototype = prototypeForLookup(exec);
+            JSValue prototype = prototypeForLookup(exec);
             m_cachedPrototypeChain = StructureChain::create(prototype.isNull() ? 0 : asObject(prototype)->structure());
         }
         return m_cachedPrototypeChain.get();
@@ -361,7 +375,7 @@ namespace JSC {
         if (!cachedPrototypeChain)
             return false;
 
-        JSValuePtr prototype = prototypeForLookup(exec);
+        JSValue prototype = prototypeForLookup(exec);
         RefPtr<Structure>* cachedStructure = cachedPrototypeChain->head();
         while(*cachedStructure && !prototype.isNull()) {
             if (asObject(prototype)->structure() != *cachedStructure)
index f9dbe59aaaf2cf0966fdb5a52257b8b589d6dede..be160a823c391f400ca1cc01f88f41a773f25bb6 100644 (file)
@@ -28,6 +28,7 @@
 #include "CallFrame.h"
 #include "GlobalEvalFunction.h"
 #include "JSGlobalObject.h"
+#include "LiteralParser.h"
 #include "JSString.h"
 #include "Interpreter.h"
 #include "Parser.h"
@@ -47,9 +48,9 @@ using namespace Unicode;
 
 namespace JSC {
 
-static JSValuePtr encode(ExecState* exec, const ArgList& args, const char* doNotEscape)
+static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEscape)
 {
-    UString str = args.at(exec, 0).toString(exec);
+    UString str = args.at(0).toString(exec);
     CString cstr = str.UTF8String(true);
     if (!cstr.c_str())
         return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
@@ -69,10 +70,10 @@ static JSValuePtr encode(ExecState* exec, const ArgList& args, const char* doNot
     return jsString(exec, result);
 }
 
-static JSValuePtr decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
+static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
 {
     UString result = "";
-    UString str = args.at(exec, 0).toString(exec);
+    UString str = args.at(0).toString(exec);
     int k = 0;
     int len = str.size();
     const UChar* d = str.data();
@@ -268,19 +269,23 @@ static double parseFloat(const UString& s)
     return s.toDouble(true /*tolerant*/, false /* NaN for empty string */);
 }
 
-JSValuePtr globalFuncEval(ExecState* exec, JSObject* function, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObject = thisValue.toThisObject(exec);
     JSObject* unwrappedObject = thisObject->unwrappedObject();
     if (!unwrappedObject->isGlobalObject() || static_cast<JSGlobalObject*>(unwrappedObject)->evalFunction() != function)
         return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
 
-    JSValuePtr x = args.at(exec, 0);
+    JSValue x = args.at(0);
     if (!x.isString())
         return x;
 
     UString s = x.toString(exec);
 
+    LiteralParser preparser(exec, s, LiteralParser::NonStrictJSON);
+    if (JSValue parsedObject = preparser.tryLiteralParse())
+        return parsedObject;
+
     int errLine;
     UString errMsg;
 
@@ -293,42 +298,46 @@ JSValuePtr globalFuncEval(ExecState* exec, JSObject* function, JSValuePtr thisVa
     return exec->interpreter()->execute(evalNode.get(), exec, thisObject, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot());
 }
 
-JSValuePtr globalFuncParseInt(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    JSValuePtr value = args.at(exec, 0);
-    int32_t radix = args.at(exec, 1).toInt32(exec);
+    JSValue value = args.at(0);
+    int32_t radix = args.at(1).toInt32(exec);
+
+    if (radix != 0 && radix != 10)
+        return jsNumber(exec, parseInt(value.toString(exec), radix));
+
+    if (value.isInt32())
+        return value;
 
-    if (value.isNumber() && (radix == 0 || radix == 10)) {
-        if (value.isInt32Fast())
-            return value;
-        double d = value.uncheckedGetNumber();
+    if (value.isDouble()) {
+        double d = value.asDouble();
         if (isfinite(d))
             return jsNumber(exec, (d > 0) ? floor(d) : ceil(d));
         if (isnan(d) || isinf(d))
-            return jsNaN(&exec->globalData());
-        return js0();
+            return jsNaN(exec);
+        return jsNumber(exec, 0);
     }
 
     return jsNumber(exec, parseInt(value.toString(exec), radix));
 }
 
-JSValuePtr globalFuncParseFloat(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, parseFloat(args.at(exec, 0).toString(exec)));
+    return jsNumber(exec, parseFloat(args.at(0).toString(exec)));
 }
 
-JSValuePtr globalFuncIsNaN(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsBoolean(isnan(args.at(exec, 0).toNumber(exec)));
+    return jsBoolean(isnan(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr globalFuncIsFinite(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncIsFinite(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    double n = args.at(exec, 0).toNumber(exec);
+    double n = args.at(0).toNumber(exec);
     return jsBoolean(!isnan(n) && !isinf(n));
 }
 
-JSValuePtr globalFuncDecodeURI(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     static const char do_not_unescape_when_decoding_URI[] =
         "#$&+,/:;=?@";
@@ -336,12 +345,12 @@ JSValuePtr globalFuncDecodeURI(ExecState* exec, JSObject*, JSValuePtr, const Arg
     return decode(exec, args, do_not_unescape_when_decoding_URI, true);
 }
 
-JSValuePtr globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     return decode(exec, args, "", true);
 }
 
-JSValuePtr globalFuncEncodeURI(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     static const char do_not_escape_when_encoding_URI[] =
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -352,7 +361,7 @@ JSValuePtr globalFuncEncodeURI(ExecState* exec, JSObject*, JSValuePtr, const Arg
     return encode(exec, args, do_not_escape_when_encoding_URI);
 }
 
-JSValuePtr globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     static const char do_not_escape_when_encoding_URI_component[] =
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -363,7 +372,7 @@ JSValuePtr globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValuePtr,
     return encode(exec, args, do_not_escape_when_encoding_URI_component);
 }
 
-JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     static const char do_not_escape[] =
         "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -373,7 +382,7 @@ JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
 
     UString result = "";
     UString s;
-    UString str = args.at(exec, 0).toString(exec);
+    UString str = args.at(0).toString(exec);
     const UChar* c = str.data();
     for (int k = 0; k < str.size(); k++, c++) {
         int u = c[0];
@@ -394,22 +403,22 @@ JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
     return jsString(exec, result);
 }
 
-JSValuePtr globalFuncUnescape(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     UString result = "";
-    UString str = args.at(exec, 0).toString(exec);
+    UString str = args.at(0).toString(exec);
     int k = 0;
     int len = str.size();
     while (k < len) {
         const UChar* c = str.data() + k;
         UChar u;
         if (c[0] == '%' && k <= len - 6 && c[1] == 'u') {
-            if (Lexer::isHexDigit(c[2]) && Lexer::isHexDigit(c[3]) && Lexer::isHexDigit(c[4]) && Lexer::isHexDigit(c[5])) {
+            if (isASCIIHexDigit(c[2]) && isASCIIHexDigit(c[3]) && isASCIIHexDigit(c[4]) && isASCIIHexDigit(c[5])) {
                 u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]);
                 c = &u;
                 k += 5;
             }
-        } else if (c[0] == '%' && k <= len - 3 && Lexer::isHexDigit(c[1]) && Lexer::isHexDigit(c[2])) {
+        } else if (c[0] == '%' && k <= len - 3 && isASCIIHexDigit(c[1]) && isASCIIHexDigit(c[2])) {
             u = UChar(Lexer::convertHex(c[1], c[2]));
             c = &u;
             k += 2;
@@ -422,10 +431,10 @@ JSValuePtr globalFuncUnescape(ExecState* exec, JSObject*, JSValuePtr, const ArgL
 }
 
 #ifndef NDEBUG
-JSValuePtr globalFuncJSCPrint(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     CStringBuffer string;
-    args.at(exec, 0).toString(exec).getCString(string);
+    args.at(0).toString(exec).getCString(string);
     puts(string.data());
     return jsUndefined();
 }
index 0929b172f20dc1a32782cb98c8bacef9d3ccf6b6..b1046f2dd48ee106da588968b714399db565aab5 100644 (file)
@@ -31,24 +31,24 @@ namespace JSC {
     class ArgList;
     class ExecState;
     class JSObject;
-    class JSValuePtr;
+    class JSValue;
 
     // FIXME: These functions should really be in JSGlobalObject.cpp, but putting them there
     // is a 0.5% reduction.
 
-    JSValuePtr globalFuncEval(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncParseInt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncParseFloat(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncIsNaN(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncIsFinite(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncDecodeURI(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncEncodeURI(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncEscape(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-    JSValuePtr globalFuncUnescape(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncEval(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncParseInt(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncParseFloat(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncIsNaN(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncIsFinite(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncEscape(ExecState*, JSObject*, JSValue, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncUnescape(ExecState*, JSObject*, JSValue, const ArgList&);
 #ifndef NDEBUG
-    JSValuePtr globalFuncJSCPrint(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+    JSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState*, JSObject*, JSValue, const ArgList&);
 #endif
 
     static const double mantissaOverflowLowerBound = 9007199254740992.0;
index c6cca80b71baec5966d2001a92a17cee8c82ef5f..846238d93eb25b26446f8579b9ad5f0c868021f4 100644 (file)
 #include "config.h"
 #include "JSImmediate.h"
 
-#include "BooleanConstructor.h"
-#include "BooleanPrototype.h"
-#include "Error.h"
-#include "ExceptionHelpers.h"
-#include "JSGlobalObject.h"
-#include "JSNotAnObject.h"
-#include "NumberConstructor.h"
-#include "NumberPrototype.h"
-
 namespace JSC {
 
-JSObject* JSImmediate::toThisObject(JSValuePtr v, ExecState* exec)
-{
-    ASSERT(isImmediate(v));
-    if (isNumber(v))
-        return constructNumber(exec, v);
-    if (isBoolean(v))
-        return constructBooleanFromImmediateBoolean(exec, v);
-    if (v.isNull())
-        return exec->globalThisValue();
-    
-    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
-    exec->setException(exception);
-    return new (exec) JSNotAnObject(exec, exception);
-}
-
-JSObject* JSImmediate::toObject(JSValuePtr v, ExecState* exec)
-{
-    ASSERT(isImmediate(v));
-    if (isNumber(v))
-        return constructNumber(exec, v);
-    if (isBoolean(v))
-        return constructBooleanFromImmediateBoolean(exec, v);
-    
-    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
-    exec->setException(exception);
-    return new (exec) JSNotAnObject(exec, exception);
-}
-
-JSObject* JSImmediate::prototype(JSValuePtr v, ExecState* exec)
-{
-    ASSERT(isImmediate(v));
-    if (isNumber(v))
-        return exec->lexicalGlobalObject()->numberPrototype();
-    if (isBoolean(v))
-        return exec->lexicalGlobalObject()->booleanPrototype();
-
-    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, v.isNull());
-    exec->setException(exception);
-    return new (exec) JSNotAnObject(exec, exception);
-}
-
-UString JSImmediate::toString(JSValuePtr v)
-{
-    ASSERT(isImmediate(v));
-    if (isIntegerNumber(v))
-        return UString::from(getTruncatedInt32(v));
-#if USE(ALTERNATE_JSIMMEDIATE)
-    if (isNumber(v)) {
-        ASSERT(isDoubleNumber(v));
-        double value = doubleValue(v);
-        if (value == 0.0) // +0.0 or -0.0
-            return "0";
-        return UString::from(value);
-    }
-#else
-        ASSERT(!isNumber(v));
-#endif
-    if (jsBoolean(false) == v)
-        return "false";
-    if (jsBoolean(true) == v)
-        return "true";
-    if (v.isNull())
-        return "null";
-    ASSERT(v.isUndefined());
-    return "undefined";
-}
-
-NEVER_INLINE double JSImmediate::nonInlineNaN()
-{
-    return std::numeric_limits<double>::quiet_NaN();
-}
-
 } // namespace JSC
index 3a448251deff3377ee03258a072c6b673dee6242..4ed35fc45e41ea317ee868007edca36cd63b7f27 100644 (file)
 #ifndef JSImmediate_h
 #define JSImmediate_h
 
+#include <wtf/Platform.h>
+
+#if !USE(JSVALUE32_64)
+
 #include <wtf/Assertions.h>
 #include <wtf/AlwaysInline.h>
 #include <wtf/MathExtras.h>
@@ -42,33 +46,7 @@ namespace JSC {
     class JSObject;
     class UString;
 
-    JSValuePtr js0();
-    JSValuePtr jsNull();
-    JSValuePtr jsBoolean(bool b);
-    JSValuePtr jsUndefined();
-    JSValuePtr jsImpossibleValue();
-    JSValuePtr jsNumber(ExecState* exec, double d);
-    JSValuePtr jsNumber(ExecState*, char i);
-    JSValuePtr jsNumber(ExecState*, unsigned char i);
-    JSValuePtr jsNumber(ExecState*, short i);
-    JSValuePtr jsNumber(ExecState*, unsigned short i);
-    JSValuePtr jsNumber(ExecState* exec, int i);
-    JSValuePtr jsNumber(ExecState* exec, unsigned i);
-    JSValuePtr jsNumber(ExecState* exec, long i);
-    JSValuePtr jsNumber(ExecState* exec, unsigned long i);
-    JSValuePtr jsNumber(ExecState* exec, long long i);
-    JSValuePtr jsNumber(ExecState* exec, unsigned long long i);
-    JSValuePtr jsNumber(JSGlobalData* globalData, double d);
-    JSValuePtr jsNumber(JSGlobalData* globalData, short i);
-    JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i);
-    JSValuePtr jsNumber(JSGlobalData* globalData, int i);
-    JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i);
-    JSValuePtr jsNumber(JSGlobalData* globalData, long i);
-    JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i);
-    JSValuePtr jsNumber(JSGlobalData* globalData, long long i);
-    JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i);
-
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
     inline intptr_t reinterpretDoubleToIntptr(double value)
     {
         return WTF::bitwise_cast<intptr_t>(value);
@@ -124,7 +102,7 @@ namespace JSC {
 
     /*
      * On 64-bit platforms, we support an alternative encoding form for immediates, if
-     * USE(ALTERNATE_JSIMMEDIATE) is defined.  When this format is used, double precision
+     * USE(JSVALUE64) is defined.  When this format is used, double precision
      * floating point values may also be encoded as JSImmediates.
      *
      * The encoding makes use of unused NaN space in the IEEE754 representation.  Any value
@@ -158,35 +136,30 @@ namespace JSC {
     class JSImmediate {
     private:
         friend class JIT;
-        friend class JSValuePtr;
+        friend class JSValue;
         friend class JSFastMath;
-        friend JSValuePtr js0();
-        friend JSValuePtr jsNull();
-        friend JSValuePtr jsBoolean(bool b);
-        friend JSValuePtr jsUndefined();
-        friend JSValuePtr jsImpossibleValue();
-        friend JSValuePtr jsNumber(ExecState* exec, double d);
-        friend JSValuePtr jsNumber(ExecState*, char i);
-        friend JSValuePtr jsNumber(ExecState*, unsigned char i);
-        friend JSValuePtr jsNumber(ExecState*, short i);
-        friend JSValuePtr jsNumber(ExecState*, unsigned short i);
-        friend JSValuePtr jsNumber(ExecState* exec, int i);
-        friend JSValuePtr jsNumber(ExecState* exec, unsigned i);
-        friend JSValuePtr jsNumber(ExecState* exec, long i);
-        friend JSValuePtr jsNumber(ExecState* exec, unsigned long i);
-        friend JSValuePtr jsNumber(ExecState* exec, long long i);
-        friend JSValuePtr jsNumber(ExecState* exec, unsigned long long i);
-        friend JSValuePtr jsNumber(JSGlobalData* globalData, double d);
-        friend JSValuePtr jsNumber(JSGlobalData* globalData, short i);
-        friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned short i);
-        friend JSValuePtr jsNumber(JSGlobalData* globalData, int i);
-        friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i);
-        friend JSValuePtr jsNumber(JSGlobalData* globalData, long i);
-        friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i);
-        friend JSValuePtr jsNumber(JSGlobalData* globalData, long long i);
-        friend JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i);
-
-#if USE(ALTERNATE_JSIMMEDIATE)
+        friend JSValue jsNumber(ExecState* exec, double d);
+        friend JSValue jsNumber(ExecState*, char i);
+        friend JSValue jsNumber(ExecState*, unsigned char i);
+        friend JSValue jsNumber(ExecState*, short i);
+        friend JSValue jsNumber(ExecState*, unsigned short i);
+        friend JSValue jsNumber(ExecState* exec, int i);
+        friend JSValue jsNumber(ExecState* exec, unsigned i);
+        friend JSValue jsNumber(ExecState* exec, long i);
+        friend JSValue jsNumber(ExecState* exec, unsigned long i);
+        friend JSValue jsNumber(ExecState* exec, long long i);
+        friend JSValue jsNumber(ExecState* exec, unsigned long long i);
+        friend JSValue jsNumber(JSGlobalData* globalData, double d);
+        friend JSValue jsNumber(JSGlobalData* globalData, short i);
+        friend JSValue jsNumber(JSGlobalData* globalData, unsigned short i);
+        friend JSValue jsNumber(JSGlobalData* globalData, int i);
+        friend JSValue jsNumber(JSGlobalData* globalData, unsigned i);
+        friend JSValue jsNumber(JSGlobalData* globalData, long i);
+        friend JSValue jsNumber(JSGlobalData* globalData, unsigned long i);
+        friend JSValue jsNumber(JSGlobalData* globalData, long long i);
+        friend JSValue jsNumber(JSGlobalData* globalData, unsigned long long i);
+
+#if USE(JSVALUE64)
         // If all bits in the mask are set, this indicates an integer number,
         // if any but not all are set this value is a double precision number.
         static const intptr_t TagTypeNumber = 0xffff000000000000ll;
@@ -208,7 +181,7 @@ namespace JSC {
         static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
         static const intptr_t FullTagTypeNull      = TagBitTypeOther;
 
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
         static const int32_t IntegerPayloadShift  = 0;
 #else
         static const int32_t IntegerPayloadShift  = 1;
@@ -219,107 +192,100 @@ namespace JSC {
 
         static const int32_t signBit = 0x80000000;
  
-        static ALWAYS_INLINE bool isImmediate(JSValuePtr v)
+        static ALWAYS_INLINE bool isImmediate(JSValue v)
         {
             return rawValue(v) & TagMask;
         }
         
-        static ALWAYS_INLINE bool isNumber(JSValuePtr v)
+        static ALWAYS_INLINE bool isNumber(JSValue v)
         {
             return rawValue(v) & TagTypeNumber;
         }
 
-        static ALWAYS_INLINE bool isIntegerNumber(JSValuePtr v)
+        static ALWAYS_INLINE bool isIntegerNumber(JSValue v)
         {
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
             return (rawValue(v) & TagTypeNumber) == TagTypeNumber;
 #else
             return isNumber(v);
 #endif
         }
 
-#if USE(ALTERNATE_JSIMMEDIATE)
-        static ALWAYS_INLINE bool isDoubleNumber(JSValuePtr v)
+#if USE(JSVALUE64)
+        static ALWAYS_INLINE bool isDouble(JSValue v)
         {
             return isNumber(v) && !isIntegerNumber(v);
         }
 #endif
 
-        static ALWAYS_INLINE bool isPositiveIntegerNumber(JSValuePtr v)
+        static ALWAYS_INLINE bool isPositiveIntegerNumber(JSValue v)
         {
             // A single mask to check for the sign bit and the number tag all at once.
             return (rawValue(v) & (signBit | TagTypeNumber)) == TagTypeNumber;
         }
         
-        static ALWAYS_INLINE bool isBoolean(JSValuePtr v)
+        static ALWAYS_INLINE bool isBoolean(JSValue v)
         {
             return (rawValue(v) & FullTagTypeMask) == FullTagTypeBool;
         }
         
-        static ALWAYS_INLINE bool isUndefinedOrNull(JSValuePtr v)
+        static ALWAYS_INLINE bool isUndefinedOrNull(JSValue v)
         {
             // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
             return (rawValue(v) & ~ExtendedTagBitUndefined) == FullTagTypeNull;
         }
 
-        static JSValuePtr from(char);
-        static JSValuePtr from(signed char);
-        static JSValuePtr from(unsigned char);
-        static JSValuePtr from(short);
-        static JSValuePtr from(unsigned short);
-        static JSValuePtr from(int);
-        static JSValuePtr from(unsigned);
-        static JSValuePtr from(long);
-        static JSValuePtr from(unsigned long);
-        static JSValuePtr from(long long);
-        static JSValuePtr from(unsigned long long);
-        static JSValuePtr from(double);
+        static JSValue from(char);
+        static JSValue from(signed char);
+        static JSValue from(unsigned char);
+        static JSValue from(short);
+        static JSValue from(unsigned short);
+        static JSValue from(int);
+        static JSValue from(unsigned);
+        static JSValue from(long);
+        static JSValue from(unsigned long);
+        static JSValue from(long long);
+        static JSValue from(unsigned long long);
+        static JSValue from(double);
 
-        static ALWAYS_INLINE bool isEitherImmediate(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE bool isEitherImmediate(JSValue v1, JSValue v2)
         {
             return (rawValue(v1) | rawValue(v2)) & TagMask;
         }
 
-        static ALWAYS_INLINE bool areBothImmediate(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE bool areBothImmediate(JSValue v1, JSValue v2)
         {
             return isImmediate(v1) & isImmediate(v2);
         }
 
-        static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValue v1, JSValue v2)
         {
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
             return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber;
 #else
             return rawValue(v1) & rawValue(v2) & TagTypeNumber;
 #endif
         }
 
-        static double toDouble(JSValuePtr);
-        static bool toBoolean(JSValuePtr);
-        static JSObject* toObject(JSValuePtr, ExecState*);
-        static JSObject* toThisObject(JSValuePtr, ExecState*);
-        static UString toString(JSValuePtr);
-
-        static bool getUInt32(JSValuePtr, uint32_t&);
-        static bool getTruncatedInt32(JSValuePtr, int32_t&);
-        static bool getTruncatedUInt32(JSValuePtr, uint32_t&);
+        static double toDouble(JSValue);
+        static bool toBoolean(JSValue);
 
-        static int32_t getTruncatedInt32(JSValuePtr);
-        static uint32_t getTruncatedUInt32(JSValuePtr);
+        static bool getUInt32(JSValue, uint32_t&);
+        static bool getTruncatedInt32(JSValue, int32_t&);
+        static bool getTruncatedUInt32(JSValue, uint32_t&);
 
-        static JSValuePtr trueImmediate();
-        static JSValuePtr falseImmediate();
-        static JSValuePtr undefinedImmediate();
-        static JSValuePtr nullImmediate();
-        static JSValuePtr zeroImmediate();
-        static JSValuePtr oneImmediate();
+        static int32_t getTruncatedInt32(JSValue);
+        static uint32_t getTruncatedUInt32(JSValue);
 
-        static JSValuePtr impossibleValue();
-        
-        static JSObject* prototype(JSValuePtr, ExecState*);
+        static JSValue trueImmediate();
+        static JSValue falseImmediate();
+        static JSValue undefinedImmediate();
+        static JSValue nullImmediate();
+        static JSValue zeroImmediate();
+        static JSValue oneImmediate();
 
     private:
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
         static const int minImmediateInt = ((-INT_MAX) - 1);
         static const int maxImmediateInt = INT_MAX;
 #else
@@ -328,199 +294,194 @@ namespace JSC {
 #endif
         static const unsigned maxImmediateUInt = maxImmediateInt;
 
-        static ALWAYS_INLINE JSValuePtr makeValue(intptr_t integer)
+        static ALWAYS_INLINE JSValue makeValue(intptr_t integer)
         {
-            return JSValuePtr::makeImmediate(integer);
+            return JSValue::makeImmediate(integer);
         }
 
-        // With USE(ALTERNATE_JSIMMEDIATE) we want the argument to be zero extended, so the
+        // With USE(JSVALUE64) we want the argument to be zero extended, so the
         // integer doesn't interfere with the tag bits in the upper word.  In the default encoding,
         // if intptr_t id larger then int32_t we sign extend the value through the upper word.
-#if USE(ALTERNATE_JSIMMEDIATE)
-        static ALWAYS_INLINE JSValuePtr makeInt(uint32_t value)
+#if USE(JSVALUE64)
+        static ALWAYS_INLINE JSValue makeInt(uint32_t value)
 #else
-        static ALWAYS_INLINE JSValuePtr makeInt(int32_t value)
+        static ALWAYS_INLINE JSValue makeInt(int32_t value)
 #endif
         {
             return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber);
         }
         
-#if USE(ALTERNATE_JSIMMEDIATE)
-        static ALWAYS_INLINE JSValuePtr makeDouble(double value)
+#if USE(JSVALUE64)
+        static ALWAYS_INLINE JSValue makeDouble(double value)
         {
             return makeValue(reinterpretDoubleToIntptr(value) + DoubleEncodeOffset);
         }
 #endif
         
-        static ALWAYS_INLINE JSValuePtr makeBool(bool b)
+        static ALWAYS_INLINE JSValue makeBool(bool b)
         {
             return makeValue((static_cast<intptr_t>(b) << ExtendedPayloadShift) | FullTagTypeBool);
         }
         
-        static ALWAYS_INLINE JSValuePtr makeUndefined()
+        static ALWAYS_INLINE JSValue makeUndefined()
         {
             return makeValue(FullTagTypeUndefined);
         }
         
-        static ALWAYS_INLINE JSValuePtr makeNull()
+        static ALWAYS_INLINE JSValue makeNull()
         {
             return makeValue(FullTagTypeNull);
         }
 
         template<typename T>
-        static JSValuePtr fromNumberOutsideIntegerRange(T);
+        static JSValue fromNumberOutsideIntegerRange(T);
 
-#if USE(ALTERNATE_JSIMMEDIATE)
-        static ALWAYS_INLINE double doubleValue(JSValuePtr v)
+#if USE(JSVALUE64)
+        static ALWAYS_INLINE double doubleValue(JSValue v)
         {
             return reinterpretIntptrToDouble(rawValue(v) - DoubleEncodeOffset);
         }
 #endif
 
-        static ALWAYS_INLINE int32_t intValue(JSValuePtr v)
+        static ALWAYS_INLINE int32_t intValue(JSValue v)
         {
             return static_cast<int32_t>(rawValue(v) >> IntegerPayloadShift);
         }
         
-        static ALWAYS_INLINE uint32_t uintValue(JSValuePtr v)
+        static ALWAYS_INLINE uint32_t uintValue(JSValue v)
         {
             return static_cast<uint32_t>(rawValue(v) >> IntegerPayloadShift);
         }
         
-        static ALWAYS_INLINE bool boolValue(JSValuePtr v)
+        static ALWAYS_INLINE bool boolValue(JSValue v)
         {
             return rawValue(v) & ExtendedPayloadBitBoolValue;
         }
         
-        static ALWAYS_INLINE intptr_t rawValue(JSValuePtr v)
+        static ALWAYS_INLINE intptr_t rawValue(JSValue v)
         {
             return v.immediateValue();
         }
-
-        static double nonInlineNaN();
     };
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::trueImmediate() { return makeBool(true); }
-    ALWAYS_INLINE JSValuePtr JSImmediate::falseImmediate() { return makeBool(false); }
-    ALWAYS_INLINE JSValuePtr JSImmediate::undefinedImmediate() { return makeUndefined(); }
-    ALWAYS_INLINE JSValuePtr JSImmediate::nullImmediate() { return makeNull(); }
-    ALWAYS_INLINE JSValuePtr JSImmediate::zeroImmediate() { return makeInt(0); }
-    ALWAYS_INLINE JSValuePtr JSImmediate::oneImmediate() { return makeInt(1); }
-
-    // This value is impossible because 0x4 is not a valid pointer but a tag of 0 would indicate non-immediate
-    ALWAYS_INLINE JSValuePtr JSImmediate::impossibleValue() { return makeValue(0x4); }
+    ALWAYS_INLINE JSValue JSImmediate::trueImmediate() { return makeBool(true); }
+    ALWAYS_INLINE JSValue JSImmediate::falseImmediate() { return makeBool(false); }
+    ALWAYS_INLINE JSValue JSImmediate::undefinedImmediate() { return makeUndefined(); }
+    ALWAYS_INLINE JSValue JSImmediate::nullImmediate() { return makeNull(); }
+    ALWAYS_INLINE JSValue JSImmediate::zeroImmediate() { return makeInt(0); }
+    ALWAYS_INLINE JSValue JSImmediate::oneImmediate() { return makeInt(1); }
 
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
     inline bool doubleToBoolean(double value)
     {
         return value < 0.0 || value > 0.0;
     }
 
-    ALWAYS_INLINE bool JSImmediate::toBoolean(JSValuePtr v)
+    ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue v)
     {
         ASSERT(isImmediate(v));
         return isNumber(v) ? isIntegerNumber(v) ? v != zeroImmediate()
             : doubleToBoolean(doubleValue(v)) : v == trueImmediate();
     }
 #else
-    ALWAYS_INLINE bool JSImmediate::toBoolean(JSValuePtr v)
+    ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue v)
     {
         ASSERT(isImmediate(v));
         return isIntegerNumber(v) ? v != zeroImmediate() : v == trueImmediate();
     }
 #endif
 
-    ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValuePtr v)
+    ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue v)
     {
         // FIXME: should probably be asserting isPositiveIntegerNumber here.
         ASSERT(isIntegerNumber(v));
         return intValue(v);
     }
 
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
     template<typename T>
-    inline JSValuePtr JSImmediate::fromNumberOutsideIntegerRange(T value)
+    inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value)
     {
         return makeDouble(static_cast<double>(value));
     }
 #else
     template<typename T>
-    inline JSValuePtr JSImmediate::fromNumberOutsideIntegerRange(T)
+    inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T)
     {
-        return noValue();
+        return JSValue();
     }
 #endif
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(char i)
+    ALWAYS_INLINE JSValue JSImmediate::from(char i)
     {
         return makeInt(i);
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(signed char i)
+    ALWAYS_INLINE JSValue JSImmediate::from(signed char i)
     {
         return makeInt(i);
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned char i)
+    ALWAYS_INLINE JSValue JSImmediate::from(unsigned char i)
     {
         return makeInt(i);
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(short i)
+    ALWAYS_INLINE JSValue JSImmediate::from(short i)
     {
         return makeInt(i);
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned short i)
+    ALWAYS_INLINE JSValue JSImmediate::from(unsigned short i)
     {
         return makeInt(i);
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(int i)
+    ALWAYS_INLINE JSValue JSImmediate::from(int i)
     {
-#if !USE(ALTERNATE_JSIMMEDIATE)
+#if !USE(JSVALUE64)
         if ((i < minImmediateInt) | (i > maxImmediateInt))
             return fromNumberOutsideIntegerRange(i);
 #endif
         return makeInt(i);
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned i)
+    ALWAYS_INLINE JSValue JSImmediate::from(unsigned i)
     {
         if (i > maxImmediateUInt)
             return fromNumberOutsideIntegerRange(i);
         return makeInt(i);
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(long i)
+    ALWAYS_INLINE JSValue JSImmediate::from(long i)
     {
         if ((i < minImmediateInt) | (i > maxImmediateInt))
             return fromNumberOutsideIntegerRange(i);
         return makeInt(i);
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long i)
+    ALWAYS_INLINE JSValue JSImmediate::from(unsigned long i)
     {
         if (i > maxImmediateUInt)
             return fromNumberOutsideIntegerRange(i);
         return makeInt(i);
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(long long i)
+    ALWAYS_INLINE JSValue JSImmediate::from(long long i)
     {
         if ((i < minImmediateInt) | (i > maxImmediateInt))
-            return noValue();
+            return JSValue();
         return makeInt(static_cast<intptr_t>(i));
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(unsigned long long i)
+    ALWAYS_INLINE JSValue JSImmediate::from(unsigned long long i)
     {
         if (i > maxImmediateUInt)
             return fromNumberOutsideIntegerRange(i);
         return makeInt(static_cast<intptr_t>(i));
     }
 
-    ALWAYS_INLINE JSValuePtr JSImmediate::from(double d)
+    ALWAYS_INLINE JSValue JSImmediate::from(double d)
     {
         const int intVal = static_cast<int>(d);
 
@@ -531,22 +492,22 @@ namespace JSC {
         return from(intVal);
     }
 
-    ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValuePtr v)
+    ALWAYS_INLINE int32_t JSImmediate::getTruncatedInt32(JSValue v)
     {
         ASSERT(isIntegerNumber(v));
         return intValue(v);
     }
 
-    ALWAYS_INLINE double JSImmediate::toDouble(JSValuePtr v)
+    ALWAYS_INLINE double JSImmediate::toDouble(JSValue v)
     {
         ASSERT(isImmediate(v));
 
         if (isIntegerNumber(v))
             return intValue(v);
 
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
         if (isNumber(v)) {
-            ASSERT(isDoubleNumber(v));
+            ASSERT(isDouble(v));
             return doubleValue(v);
         }
 #else
@@ -560,75 +521,64 @@ namespace JSC {
         return rawValue(v) >> ExtendedPayloadShift;
     }
 
-    ALWAYS_INLINE bool JSImmediate::getUInt32(JSValuePtr v, uint32_t& i)
+    ALWAYS_INLINE bool JSImmediate::getUInt32(JSValue v, uint32_t& i)
     {
         i = uintValue(v);
         return isPositiveIntegerNumber(v);
     }
 
-    ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValuePtr v, int32_t& i)
+    ALWAYS_INLINE bool JSImmediate::getTruncatedInt32(JSValue v, int32_t& i)
     {
         i = intValue(v);
         return isIntegerNumber(v);
     }
 
-    ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValuePtr v, uint32_t& i)
+    ALWAYS_INLINE bool JSImmediate::getTruncatedUInt32(JSValue v, uint32_t& i)
     {
         return getUInt32(v, i);
     }
 
-    inline JSValuePtr js0()
+    inline JSValue::JSValue(JSNullTag)
     {
-        return JSImmediate::zeroImmediate();
+        *this = JSImmediate::nullImmediate();
     }
-
-    inline JSValuePtr jsNull()
+    
+    inline JSValue::JSValue(JSUndefinedTag)
     {
-        return JSImmediate::nullImmediate();
+        *this = JSImmediate::undefinedImmediate();
     }
 
-    inline JSValuePtr jsBoolean(bool b)
+    inline JSValue::JSValue(JSTrueTag)
     {
-        return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate();
+        *this = JSImmediate::trueImmediate();
     }
 
-    inline JSValuePtr jsUndefined()
+    inline JSValue::JSValue(JSFalseTag)
     {
-        return JSImmediate::undefinedImmediate();
+        *this = JSImmediate::falseImmediate();
     }
 
-    inline JSValuePtr jsImpossibleValue()
-    {
-        return JSImmediate::impossibleValue();
-    }
-
-    // These are identical logic to the JSValue functions above, and faster than jsNumber(number).toInt32().
-    int32_t toInt32(double);
-    uint32_t toUInt32(double);
-    int32_t toInt32SlowCase(double, bool& ok);
-    uint32_t toUInt32SlowCase(double, bool& ok);
-
-    inline bool JSValuePtr::isUndefined() const
+    inline bool JSValue::isUndefinedOrNull() const
     {
-        return asValue() == jsUndefined();
+        return JSImmediate::isUndefinedOrNull(asValue());
     }
 
-    inline bool JSValuePtr::isNull() const
+    inline bool JSValue::isBoolean() const
     {
-        return asValue() == jsNull();
+        return JSImmediate::isBoolean(asValue());
     }
 
-    inline bool JSValuePtr::isUndefinedOrNull() const
+    inline bool JSValue::isTrue() const
     {
-        return JSImmediate::isUndefinedOrNull(asValue());
+        return asValue() == JSImmediate::trueImmediate();
     }
 
-    inline bool JSValuePtr::isBoolean() const
+    inline bool JSValue::isFalse() const
     {
-        return JSImmediate::isBoolean(asValue());
+        return asValue() == JSImmediate::falseImmediate();
     }
 
-    inline bool JSValuePtr::getBoolean(bool& v) const
+    inline bool JSValue::getBoolean(bool& v) const
     {
         if (JSImmediate::isBoolean(asValue())) {
             v = JSImmediate::toBoolean(asValue());
@@ -638,194 +588,128 @@ namespace JSC {
         return false;
     }
 
-    inline bool JSValuePtr::getBoolean() const
+    inline bool JSValue::getBoolean() const
     {
         return asValue() == jsBoolean(true);
     }
 
-    ALWAYS_INLINE int32_t JSValuePtr::toInt32(ExecState* exec) const
-    {
-        int32_t i;
-        if (getTruncatedInt32(i))
-            return i;
-        bool ignored;
-        return toInt32SlowCase(toNumber(exec), ignored);
-    }
-
-    inline uint32_t JSValuePtr::toUInt32(ExecState* exec) const
-    {
-        uint32_t i;
-        if (getTruncatedUInt32(i))
-            return i;
-        bool ignored;
-        return toUInt32SlowCase(toNumber(exec), ignored);
-    }
-
-    inline int32_t toInt32(double val)
-    {
-        if (!(val >= -2147483648.0 && val < 2147483648.0)) {
-            bool ignored;
-            return toInt32SlowCase(val, ignored);
-        }
-        return static_cast<int32_t>(val);
-    }
-
-    inline uint32_t toUInt32(double val)
-    {
-        if (!(val >= 0.0 && val < 4294967296.0)) {
-            bool ignored;
-            return toUInt32SlowCase(val, ignored);
-        }
-        return static_cast<uint32_t>(val);
-    }
-
-    inline int32_t JSValuePtr::toInt32(ExecState* exec, bool& ok) const
-    {
-        int32_t i;
-        if (getTruncatedInt32(i)) {
-            ok = true;
-            return i;
-        }
-        return toInt32SlowCase(toNumber(exec), ok);
-    }
-
-    inline uint32_t JSValuePtr::toUInt32(ExecState* exec, bool& ok) const
-    {
-        uint32_t i;
-        if (getTruncatedUInt32(i)) {
-            ok = true;
-            return i;
-        }
-        return toUInt32SlowCase(toNumber(exec), ok);
-    }
-
-    inline bool JSValuePtr::isCell() const
+    inline bool JSValue::isCell() const
     {
         return !JSImmediate::isImmediate(asValue());
     }
 
-    inline bool JSValuePtr::isInt32Fast() const
+    inline bool JSValue::isInt32() const
     {
         return JSImmediate::isIntegerNumber(asValue());
     }
 
-    inline int32_t JSValuePtr::getInt32Fast() const
+    inline int32_t JSValue::asInt32() const
     {
-        ASSERT(isInt32Fast());
+        ASSERT(isInt32());
         return JSImmediate::getTruncatedInt32(asValue());
     }
 
-    inline bool JSValuePtr::isUInt32Fast() const
+    inline bool JSValue::isUInt32() const
     {
         return JSImmediate::isPositiveIntegerNumber(asValue());
     }
 
-    inline uint32_t JSValuePtr::getUInt32Fast() const
+    inline uint32_t JSValue::asUInt32() const
     {
-        ASSERT(isUInt32Fast());
+        ASSERT(isUInt32());
         return JSImmediate::getTruncatedUInt32(asValue());
     }
 
-    inline JSValuePtr JSValuePtr::makeInt32Fast(int32_t i)
-    {
-        return JSImmediate::from(i);
-    }
-
-    inline bool JSValuePtr::areBothInt32Fast(JSValuePtr v1, JSValuePtr v2)
-    {
-        return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
-    }
-
     class JSFastMath {
     public:
-        static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE bool canDoFastBitwiseOperations(JSValue v1, JSValue v2)
         {
             return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
         }
 
-        static ALWAYS_INLINE JSValuePtr equal(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE JSValue equal(JSValue v1, JSValue v2)
         {
             ASSERT(canDoFastBitwiseOperations(v1, v2));
             return jsBoolean(v1 == v2);
         }
 
-        static ALWAYS_INLINE JSValuePtr notEqual(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE JSValue notEqual(JSValue v1, JSValue v2)
         {
             ASSERT(canDoFastBitwiseOperations(v1, v2));
             return jsBoolean(v1 != v2);
         }
 
-        static ALWAYS_INLINE JSValuePtr andImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE JSValue andImmediateNumbers(JSValue v1, JSValue v2)
         {
             ASSERT(canDoFastBitwiseOperations(v1, v2));
             return JSImmediate::makeValue(JSImmediate::rawValue(v1) & JSImmediate::rawValue(v2));
         }
 
-        static ALWAYS_INLINE JSValuePtr xorImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE JSValue xorImmediateNumbers(JSValue v1, JSValue v2)
         {
             ASSERT(canDoFastBitwiseOperations(v1, v2));
             return JSImmediate::makeValue((JSImmediate::rawValue(v1) ^ JSImmediate::rawValue(v2)) | JSImmediate::TagTypeNumber);
         }
 
-        static ALWAYS_INLINE JSValuePtr orImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE JSValue orImmediateNumbers(JSValue v1, JSValue v2)
         {
             ASSERT(canDoFastBitwiseOperations(v1, v2));
             return JSImmediate::makeValue(JSImmediate::rawValue(v1) | JSImmediate::rawValue(v2));
         }
 
-        static ALWAYS_INLINE bool canDoFastRshift(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE bool canDoFastRshift(JSValue v1, JSValue v2)
         {
             return JSImmediate::areBothImmediateIntegerNumbers(v1, v2);
         }
 
-        static ALWAYS_INLINE bool canDoFastUrshift(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE bool canDoFastUrshift(JSValue v1, JSValue v2)
         {
             return JSImmediate::areBothImmediateIntegerNumbers(v1, v2) && !(JSImmediate::rawValue(v1) & JSImmediate::signBit);
         }
 
-        static ALWAYS_INLINE JSValuePtr rightShiftImmediateNumbers(JSValuePtr val, JSValuePtr shift)
+        static ALWAYS_INLINE JSValue rightShiftImmediateNumbers(JSValue val, JSValue shift)
         {
             ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift));
-#if USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE64)
             return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeNumber);
 #else
             return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeNumber);
 #endif
         }
 
-        static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v)
+        static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue v)
         {
             // Number is non-negative and an operation involving two of these can't overflow.
             // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
             return (JSImmediate::rawValue(v) & (JSImmediate::TagTypeNumber + (JSImmediate::signBit | (JSImmediate::signBit >> 1)))) == JSImmediate::TagTypeNumber;
         }
 
-        static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue v1, JSValue v2)
         {
             // Number is non-negative and an operation involving two of these can't overflow.
             // Checking for allowed negative numbers takes more time than it's worth on SunSpider.
             return canDoFastAdditiveOperations(v1) && canDoFastAdditiveOperations(v2);
         }
 
-        static ALWAYS_INLINE JSValuePtr addImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE JSValue addImmediateNumbers(JSValue v1, JSValue v2)
         {
             ASSERT(canDoFastAdditiveOperations(v1, v2));
             return JSImmediate::makeValue(JSImmediate::rawValue(v1) + JSImmediate::rawValue(v2) - JSImmediate::TagTypeNumber);
         }
 
-        static ALWAYS_INLINE JSValuePtr subImmediateNumbers(JSValuePtr v1, JSValuePtr v2)
+        static ALWAYS_INLINE JSValue subImmediateNumbers(JSValue v1, JSValue v2)
         {
             ASSERT(canDoFastAdditiveOperations(v1, v2));
             return JSImmediate::makeValue(JSImmediate::rawValue(v1) - JSImmediate::rawValue(v2) + JSImmediate::TagTypeNumber);
         }
 
-        static ALWAYS_INLINE JSValuePtr incImmediateNumber(JSValuePtr v)
+        static ALWAYS_INLINE JSValue incImmediateNumber(JSValue v)
         {
             ASSERT(canDoFastAdditiveOperations(v));
             return JSImmediate::makeValue(JSImmediate::rawValue(v) + (1 << JSImmediate::IntegerPayloadShift));
         }
 
-        static ALWAYS_INLINE JSValuePtr decImmediateNumber(JSValuePtr v)
+        static ALWAYS_INLINE JSValue decImmediateNumber(JSValue v)
         {
             ASSERT(canDoFastAdditiveOperations(v));
             return JSImmediate::makeValue(JSImmediate::rawValue(v) - (1 << JSImmediate::IntegerPayloadShift));
@@ -834,4 +718,6 @@ namespace JSC {
 
 } // namespace JSC
 
+#endif // !USE(JSVALUE32_64)
+
 #endif // JSImmediate_h
index 67edfd18b974886a0b38365e7e481968166f9328..937dc2b9f7de9f5df101ea18bdb2b5bee5617ab4 100644 (file)
@@ -37,13 +37,13 @@ namespace JSC {
 ASSERT_CLASS_FITS_IN_CELL(JSNotAnObject);
 
 // JSValue methods
-JSValuePtr JSNotAnObject::toPrimitive(ExecState* exec, PreferredPrimitiveType) const
+JSValue JSNotAnObject::toPrimitive(ExecState* exec, PreferredPrimitiveType) const
 {
     ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
     return m_exception;
 }
 
-bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValuePtr&)
+bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValue&)
 {
     ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
     return false;
@@ -94,12 +94,12 @@ bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&)
     return false;
 }
 
-void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValuePtr, PutPropertySlot&)
+void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue, PutPropertySlot&)
 {
     ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
 }
 
-void JSNotAnObject::put(ExecState* exec, unsigned, JSValuePtr)
+void JSNotAnObject::put(ExecState* exec, unsigned, JSValue)
 {
     ASSERT_UNUSED(exec, exec->hadException() && exec->exception() == m_exception);
 }
index c69593f4769acb3cef3d679b6bbc790bd41a8a5a..a8e36bd21dbc96c9b90dc12a45ad1d6b4245845b 100644 (file)
@@ -60,15 +60,15 @@ namespace JSC {
         {
         }
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
             return Structure::create(prototype, TypeInfo(ObjectType));
         }
 
      private:
         // JSValue methods
-        virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
-        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&);
+        virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
         virtual UString toString(ExecState*) const;
@@ -81,8 +81,8 @@ namespace JSC {
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
 
-        virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
-        virtual void put(ExecState*, unsigned propertyName, JSValuePtr);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+        virtual void put(ExecState*, unsigned propertyName, JSValue);
 
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
index dd965d5ea071448ce8b9b9c9ab638226c7123562..0654da75ea5ec6959eb2b31d622bd5a912de90e4 100644 (file)
 #include "config.h"
 #include "JSNumberCell.h"
 
+#if USE(JSVALUE32)
+
 #include "NumberObject.h"
 #include "UString.h"
 
 namespace JSC {
 
-#if !USE(ALTERNATE_JSIMMEDIATE)
-
-JSValuePtr JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValue JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     return const_cast<JSNumberCell*>(this);
 }
 
-bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value)
+bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
 {
     number = m_value;
     value = this;
@@ -82,45 +82,36 @@ bool JSNumberCell::getUInt32(uint32_t& uint32) const
     return uint32 == m_value;
 }
 
-bool JSNumberCell::getTruncatedInt32(int32_t& int32) const
-{
-    if (!(m_value >= -2147483648.0 && m_value < 2147483648.0))
-        return false;
-    int32 = static_cast<int32_t>(m_value);
-    return true;
-}
-
-bool JSNumberCell::getTruncatedUInt32(uint32_t& uint32) const
-{
-    if (!(m_value >= 0.0 && m_value < 4294967296.0))
-        return false;
-    uint32 = static_cast<uint32_t>(m_value);
-    return true;
-}
-
-JSValuePtr JSNumberCell::getJSNumber()
+JSValue JSNumberCell::getJSNumber()
 {
     return this;
 }
 
-JSValuePtr jsNumberCell(ExecState* exec, double d)
+JSValue jsNumberCell(ExecState* exec, double d)
 {
     return new (exec) JSNumberCell(exec, d);
 }
 
-JSValuePtr jsNumberCell(JSGlobalData* globalData, double d)
+JSValue jsNumberCell(JSGlobalData* globalData, double d)
 {
     return new (globalData) JSNumberCell(globalData, d);
 }
 
-#else
+} // namespace JSC
 
-JSValuePtr jsNumberCell(ExecState*, double)
+#else // USE(JSVALUE32)
+
+// Keep our exported symbols lists happy.
+namespace JSC {
+
+JSValue jsNumberCell(ExecState*, double);
+
+JSValue jsNumberCell(ExecState*, double)
 {
     ASSERT_NOT_REACHED();
-    return noValue();
+    return JSValue();
 }
 
-#endif
-
 } // namespace JSC
+
+#endif // USE(JSVALUE32)
index d2377aa515cc45dd119a708a71c781b1d950e4f0..04cccefecb794160ecbf8f3a2d7e4f36fad98204 100644 (file)
@@ -35,9 +35,8 @@ namespace JSC {
     extern const double NaN;
     extern const double Inf;
 
-    JSValuePtr jsNumberCell(ExecState*, double);
-
-#if !USE(ALTERNATE_JSIMMEDIATE)
+#if USE(JSVALUE32)
+    JSValue jsNumberCell(ExecState*, double);
 
     class Identifier;
     class JSCell;
@@ -50,13 +49,14 @@ namespace JSC {
 
     class JSNumberCell : public JSCell {
         friend class JIT;
-        friend JSValuePtr jsNumberCell(JSGlobalData*, double);
-        friend JSValuePtr jsNumberCell(ExecState*, double);
+        friend JSValue jsNumberCell(JSGlobalData*, double);
+        friend JSValue jsNumberCell(ExecState*, double);
+
     public:
         double value() const { return m_value; }
 
-        virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
-        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
+        virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
         virtual UString toString(ExecState*) const;
@@ -64,7 +64,7 @@ namespace JSC {
 
         virtual UString toThisString(ExecState*) const;
         virtual JSObject* toThisObject(ExecState*) const;
-        virtual JSValuePtr getJSNumber();
+        virtual JSValue getJSNumber();
 
         void* operator new(size_t size, ExecState* exec)
         {
@@ -84,7 +84,7 @@ namespace JSC {
     #endif
         }
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
+        static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, NeedsThisConversion)); }
 
     private:
         JSNumberCell(JSGlobalData* globalData, double value)
@@ -100,312 +100,249 @@ namespace JSC {
         }
 
         virtual bool getUInt32(uint32_t&) const;
-        virtual bool getTruncatedInt32(int32_t&) const;
-        virtual bool getTruncatedUInt32(uint32_t&) const;
 
         double m_value;
     };
 
-    JSValuePtr jsNumberCell(JSGlobalData*, double);
+    JSValue jsNumberCell(JSGlobalData*, double);
 
-    inline bool isNumberCell(JSValuePtr v)
+    inline bool isNumberCell(JSValue v)
     {
         return v.isCell() && v.asCell()->isNumber();
     }
 
-    inline JSNumberCell* asNumberCell(JSValuePtr v)
+    inline JSNumberCell* asNumberCell(JSValue v)
     {
         ASSERT(isNumberCell(v));
         return static_cast<JSNumberCell*>(v.asCell());
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, double d)
-    {
-        JSValuePtr v = JSImmediate::from(d);
-        return v ? v : jsNumberCell(exec, d);
-    }
-
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, int i)
-    {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(exec, i);
-    }
-
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned i)
-    {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(exec, i);
-    }
-
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long i)
-    {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(exec, i);
-    }
-
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long i)
+    inline JSValue::JSValue(ExecState* exec, double d)
     {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(exec, i);
+        JSValue v = JSImmediate::from(d);
+        *this = v ? v : jsNumberCell(exec, d);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, long long i)
+    inline JSValue::JSValue(ExecState* exec, int i)
     {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(exec, static_cast<double>(i));
+        JSValue v = JSImmediate::from(i);
+        *this = v ? v : jsNumberCell(exec, i);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState* exec, unsigned long long i)
+    inline JSValue::JSValue(ExecState* exec, unsigned i)
     {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(exec, static_cast<double>(i));
+        JSValue v = JSImmediate::from(i);
+        *this = v ? v : jsNumberCell(exec, i);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, double d)
+    inline JSValue::JSValue(ExecState* exec, long i)
     {
-        JSValuePtr v = JSImmediate::from(d);
-        return v ? v : jsNumberCell(globalData, d);
+        JSValue v = JSImmediate::from(i);
+        *this = v ? v : jsNumberCell(exec, i);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, int i)
+    inline JSValue::JSValue(ExecState* exec, unsigned long i)
     {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(globalData, i);
+        JSValue v = JSImmediate::from(i);
+        *this = v ? v : jsNumberCell(exec, i);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned i)
+    inline JSValue::JSValue(ExecState* exec, long long i)
     {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(globalData, i);
+        JSValue v = JSImmediate::from(i);
+        *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long i)
+    inline JSValue::JSValue(ExecState* exec, unsigned long long i)
     {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(globalData, i);
+        JSValue v = JSImmediate::from(i);
+        *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long i)
+    inline JSValue::JSValue(JSGlobalData* globalData, double d)
     {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(globalData, i);
+        JSValue v = JSImmediate::from(d);
+        *this = v ? v : jsNumberCell(globalData, d);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, long long i)
+    inline JSValue::JSValue(JSGlobalData* globalData, int i)
     {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+        JSValue v = JSImmediate::from(i);
+        *this = v ? v : jsNumberCell(globalData, i);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData* globalData, unsigned long long i)
+    inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
     {
-        JSValuePtr v = JSImmediate::from(i);
-        return v ? v : jsNumberCell(globalData, static_cast<double>(i));
+        JSValue v = JSImmediate::from(i);
+        *this = v ? v : jsNumberCell(globalData, i);
     }
 
-    inline bool JSValuePtr::isDoubleNumber() const
+    inline bool JSValue::isDouble() const
     {
         return isNumberCell(asValue());
     }
 
-    inline double JSValuePtr::getDoubleNumber() const
+    inline double JSValue::asDouble() const
     {
         return asNumberCell(asValue())->value();
     }
 
-    inline bool JSValuePtr::isNumber() const
+    inline bool JSValue::isNumber() const
     {
-        return JSImmediate::isNumber(asValue()) || isDoubleNumber();
+        return JSImmediate::isNumber(asValue()) || isDouble();
     }
 
-    inline double JSValuePtr::uncheckedGetNumber() const
+    inline double JSValue::uncheckedGetNumber() const
     {
         ASSERT(isNumber());
-        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : getDoubleNumber();
+        return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asDouble();
     }
 
-#else
+#endif // USE(JSVALUE32)
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, double d)
+#if USE(JSVALUE64)
+    inline JSValue::JSValue(ExecState*, double d)
     {
-        JSValuePtr v = JSImmediate::from(d);
+        JSValue v = JSImmediate::from(d);
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, int i)
+    inline JSValue::JSValue(ExecState*, int i)
     {
-        JSValuePtr v = JSImmediate::from(i);
+        JSValue v = JSImmediate::from(i);
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned i)
+    inline JSValue::JSValue(ExecState*, unsigned i)
     {
-        JSValuePtr v = JSImmediate::from(i);
+        JSValue v = JSImmediate::from(i);
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long i)
+    inline JSValue::JSValue(ExecState*, long i)
     {
-        JSValuePtr v = JSImmediate::from(i);
+        JSValue v = JSImmediate::from(i);
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long i)
+    inline JSValue::JSValue(ExecState*, unsigned long i)
     {
-        JSValuePtr v = JSImmediate::from(i);
+        JSValue v = JSImmediate::from(i);
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, long long i)
+    inline JSValue::JSValue(ExecState*, long long i)
     {
-        JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+        JSValue v = JSImmediate::from(static_cast<double>(i));
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned long long i)
+    inline JSValue::JSValue(ExecState*, unsigned long long i)
     {
-        JSValuePtr v = JSImmediate::from(static_cast<double>(i));
+        JSValue v = JSImmediate::from(static_cast<double>(i));
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, double d)
+    inline JSValue::JSValue(JSGlobalData*, double d)
     {
-        JSValuePtr v = JSImmediate::from(d);
+        JSValue v = JSImmediate::from(d);
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, int i)
+    inline JSValue::JSValue(JSGlobalData*, int i)
     {
-        JSValuePtr v = JSImmediate::from(i);
+        JSValue v = JSImmediate::from(i);
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned i)
+    inline JSValue::JSValue(JSGlobalData*, unsigned i)
     {
-        JSValuePtr v = JSImmediate::from(i);
+        JSValue v = JSImmediate::from(i);
         ASSERT(v);
-        return v;
+        *this = v;
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long i)
+    inline bool JSValue::isDouble() const
     {
-        JSValuePtr v = JSImmediate::from(i);
-        ASSERT(v);
-        return v;
+        return JSImmediate::isDouble(asValue());
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long i)
-    {
-        JSValuePtr v = JSImmediate::from(i);
-        ASSERT(v);
-        return v;
-    }
-
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, long long i)
-    {
-        JSValuePtr v = JSImmediate::from(static_cast<double>(i));
-        ASSERT(v);
-        return v;
-    }
-
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned long long i)
-    {
-        JSValuePtr v = JSImmediate::from(static_cast<double>(i));
-        ASSERT(v);
-        return v;
-    }
-
-    inline bool JSValuePtr::isDoubleNumber() const
-    {
-        return JSImmediate::isDoubleNumber(asValue());
-    }
-
-    inline double JSValuePtr::getDoubleNumber() const
+    inline double JSValue::asDouble() const
     {
         return JSImmediate::doubleValue(asValue());
     }
 
-    inline bool JSValuePtr::isNumber() const
+    inline bool JSValue::isNumber() const
     {
         return JSImmediate::isNumber(asValue());
     }
 
-    inline double JSValuePtr::uncheckedGetNumber() const
+    inline double JSValue::uncheckedGetNumber() const
     {
         ASSERT(isNumber());
         return JSImmediate::toDouble(asValue());
     }
 
-#endif
+#endif // USE(JSVALUE64)
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, char i)
-    {
-        ASSERT(JSImmediate::from(i));
-        return JSImmediate::from(i);
-    }
+#if USE(JSVALUE32) || USE(JSVALUE64)
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned char i)
+    inline JSValue::JSValue(ExecState*, char i)
     {
         ASSERT(JSImmediate::from(i));
-        return JSImmediate::from(i);
+        *this = JSImmediate::from(i);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, short i)
+    inline JSValue::JSValue(ExecState*, unsigned char i)
     {
         ASSERT(JSImmediate::from(i));
-        return JSImmediate::from(i);
+        *this = JSImmediate::from(i);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(ExecState*, unsigned short i)
+    inline JSValue::JSValue(ExecState*, short i)
     {
         ASSERT(JSImmediate::from(i));
-        return JSImmediate::from(i);
+        *this = JSImmediate::from(i);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, short i)
+    inline JSValue::JSValue(ExecState*, unsigned short i)
     {
         ASSERT(JSImmediate::from(i));
-        return JSImmediate::from(i);
+        *this = JSImmediate::from(i);
     }
 
-    ALWAYS_INLINE JSValuePtr jsNumber(JSGlobalData*, unsigned short i)
-    {
-        ASSERT(JSImmediate::from(i));
-        return JSImmediate::from(i);
-    }
-
-    inline JSValuePtr jsNaN(ExecState* exec)
+    inline JSValue jsNaN(ExecState* exec)
     {
         return jsNumber(exec, NaN);
     }
 
-    inline JSValuePtr jsNaN(JSGlobalData* globalData)
+    inline JSValue jsNaN(JSGlobalData* globalData)
     {
         return jsNumber(globalData, NaN);
     }
 
     // --- JSValue inlines ----------------------------
 
-    ALWAYS_INLINE JSValuePtr JSValuePtr::toJSNumber(ExecState* exec) const
+    ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
     {
         return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
     }
 
-    inline bool JSValuePtr::getNumber(double &result) const
+    inline bool JSValue::getNumber(double &result) const
     {
-        if (isInt32Fast())
-            result = getInt32Fast();
-        else if (LIKELY(isDoubleNumber()))
-            result = getDoubleNumber();
+        if (isInt32())
+            result = asInt32();
+        else if (LIKELY(isDouble()))
+            result = asDouble();
         else {
             ASSERT(!isNumber());
             return false;
@@ -413,36 +350,7 @@ namespace JSC {
         return true;
     }
 
-    inline bool JSValuePtr::numberToInt32(int32_t& arg)
-    {
-        if (isInt32Fast())
-            arg = getInt32Fast();
-        else if (LIKELY(isDoubleNumber()))
-            arg = JSC::toInt32(getDoubleNumber());
-        else {
-            ASSERT(!isNumber());
-            return false;
-        }
-        return true;
-    }
-
-    inline bool JSValuePtr::numberToUInt32(uint32_t& arg)
-    {
-        if (isUInt32Fast())
-            arg = getUInt32Fast();
-        else if (LIKELY(isDoubleNumber()))
-            arg = JSC::toUInt32(getDoubleNumber());
-        else if (isInt32Fast()) {
-            // FIXME: I think this case can be merged with the uint case; toUInt32SlowCase
-            // on a negative value is equivalent to simple static_casting.
-            bool ignored;
-            arg = toUInt32SlowCase(getInt32Fast(), ignored);
-        } else {
-            ASSERT(!isNumber());
-            return false;
-        }
-        return true;
-    }
+#endif // USE(JSVALUE32) || USE(JSVALUE64)
 
 } // namespace JSC
 
diff --git a/runtime/JSONObject.cpp b/runtime/JSONObject.cpp
new file mode 100644 (file)
index 0000000..4a89c55
--- /dev/null
@@ -0,0 +1,766 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "JSONObject.h"
+
+#include "BooleanObject.h"
+#include "Error.h"
+#include "ExceptionHelpers.h"
+#include "JSArray.h"
+#include "LiteralParser.h"
+#include "PropertyNameArray.h"
+#include <wtf/MathExtras.h>
+
+namespace JSC {
+
+ASSERT_CLASS_FITS_IN_CELL(JSONObject);
+
+static JSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState*, JSObject*, JSValue, const ArgList&);
+
+}
+
+#include "JSONObject.lut.h"
+
+namespace JSC {
+
+// PropertyNameForFunctionCall objects must be on the stack, since the JSValue that they create is not marked.
+class PropertyNameForFunctionCall {
+public:
+    PropertyNameForFunctionCall(const Identifier&);
+    PropertyNameForFunctionCall(unsigned);
+
+    JSValue value(ExecState*) const;
+
+private:
+    const Identifier* m_identifier;
+    unsigned m_number;
+    mutable JSValue m_value;
+};
+
+class Stringifier : Noncopyable {
+public:
+    Stringifier(ExecState*, JSValue replacer, JSValue space);
+    ~Stringifier();
+    JSValue stringify(JSValue);
+
+    void mark();
+
+private:
+    typedef UString StringBuilder;
+
+    class Holder {
+    public:
+        Holder(JSObject*);
+
+        JSObject* object() const { return m_object; }
+
+        bool appendNextProperty(Stringifier&, StringBuilder&);
+
+    private:
+        JSObject* const m_object;
+        const bool m_isArray;
+        bool m_isJSArray;
+        unsigned m_index;
+        unsigned m_size;
+        RefPtr<PropertyNameArrayData> m_propertyNames;
+    };
+
+    friend class Holder;
+
+    static void appendQuotedString(StringBuilder&, const UString&);
+
+    JSValue toJSON(JSValue, const PropertyNameForFunctionCall&);
+
+    enum StringifyResult { StringifyFailed, StringifySucceeded, StringifyFailedDueToUndefinedValue };
+    StringifyResult appendStringifiedValue(StringBuilder&, JSValue, JSObject* holder, const PropertyNameForFunctionCall&);
+
+    bool willIndent() const;
+    void indent();
+    void unindent();
+    void startNewLine(StringBuilder&) const;
+
+    Stringifier* const m_nextStringifierToMark;
+    ExecState* const m_exec;
+    const JSValue m_replacer;
+    bool m_usingArrayReplacer;
+    PropertyNameArray m_arrayReplacerPropertyNames;
+    CallType m_replacerCallType;
+    CallData m_replacerCallData;
+    const UString m_gap;
+
+    HashSet<JSObject*> m_holderCycleDetector;
+    Vector<Holder, 16> m_holderStack;
+    UString m_repeatedGap;
+    UString m_indent;
+};
+
+// ------------------------------ helper functions --------------------------------
+
+static inline JSValue unwrapBoxedPrimitive(JSValue value)
+{
+    if (!value.isObject())
+        return value;
+    if (!asObject(value)->inherits(&NumberObject::info) && !asObject(value)->inherits(&StringObject::info) && !asObject(value)->inherits(&BooleanObject::info))
+        return value;
+    return static_cast<JSWrapperObject*>(asObject(value))->internalValue();
+}
+
+static inline UString gap(JSValue space)
+{
+    space = unwrapBoxedPrimitive(space);
+
+    // If the space value is a number, create a gap string with that number of spaces.
+    double spaceCount;
+    if (space.getNumber(spaceCount)) {
+        const int maxSpaceCount = 100;
+        int count;
+        if (spaceCount > maxSpaceCount)
+            count = maxSpaceCount;
+        else if (!(spaceCount > 0))
+            count = 0;
+        else
+            count = static_cast<int>(spaceCount);
+        UChar spaces[maxSpaceCount];
+        for (int i = 0; i < count; ++i)
+            spaces[i] = ' ';
+        return UString(spaces, count);
+    }
+
+    // If the space value is a string, use it as the gap string, otherwise use no gap string.
+    return space.getString();
+}
+
+// ------------------------------ PropertyNameForFunctionCall --------------------------------
+
+inline PropertyNameForFunctionCall::PropertyNameForFunctionCall(const Identifier& identifier)
+    : m_identifier(&identifier)
+{
+}
+
+inline PropertyNameForFunctionCall::PropertyNameForFunctionCall(unsigned number)
+    : m_identifier(0)
+    , m_number(number)
+{
+}
+
+JSValue PropertyNameForFunctionCall::value(ExecState* exec) const
+{
+    if (!m_value) {
+        if (m_identifier)
+            m_value = jsString(exec, m_identifier->ustring());
+        else
+            m_value = jsNumber(exec, m_number);
+    }
+    return m_value;
+}
+
+// ------------------------------ Stringifier --------------------------------
+
+Stringifier::Stringifier(ExecState* exec, JSValue replacer, JSValue space)
+    : m_nextStringifierToMark(exec->globalData().firstStringifierToMark)
+    , m_exec(exec)
+    , m_replacer(replacer)
+    , m_usingArrayReplacer(false)
+    , m_arrayReplacerPropertyNames(exec)
+    , m_replacerCallType(CallTypeNone)
+    , m_gap(gap(space))
+{
+    exec->globalData().firstStringifierToMark = this;
+
+    if (!m_replacer.isObject())
+        return;
+
+    if (asObject(m_replacer)->inherits(&JSArray::info)) {
+        m_usingArrayReplacer = true;
+        JSObject* array = asObject(m_replacer);
+        unsigned length = array->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
+        for (unsigned i = 0; i < length; ++i) {
+            JSValue name = array->get(exec, i);
+            if (exec->hadException())
+                break;
+            UString propertyName;
+            if (!name.getString(propertyName))
+                continue;
+            if (exec->hadException())
+                return;
+            m_arrayReplacerPropertyNames.add(Identifier(exec, propertyName));
+        }
+        return;
+    }
+
+    m_replacerCallType = asObject(m_replacer)->getCallData(m_replacerCallData);
+}
+
+Stringifier::~Stringifier()
+{
+    ASSERT(m_exec->globalData().firstStringifierToMark == this);
+    m_exec->globalData().firstStringifierToMark = m_nextStringifierToMark;
+}
+
+void Stringifier::mark()
+{
+    for (Stringifier* stringifier = this; stringifier; stringifier = stringifier->m_nextStringifierToMark) {
+        size_t size = m_holderStack.size();
+        for (size_t i = 0; i < size; ++i) {
+            JSObject* object = m_holderStack[i].object();
+            if (!object->marked())
+                object->mark();
+        }
+    }
+}
+
+JSValue Stringifier::stringify(JSValue value)
+{
+    JSObject* object = constructEmptyObject(m_exec);
+    if (m_exec->hadException())
+        return jsNull();
+
+    PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier);
+    object->putDirect(m_exec->globalData().propertyNames->emptyIdentifier, value);
+
+    StringBuilder result;
+    if (appendStringifiedValue(result, value, object, emptyPropertyName) != StringifySucceeded)
+        return jsUndefined();
+    if (m_exec->hadException())
+        return jsNull();
+
+    return jsString(m_exec, result);
+}
+
+void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value)
+{
+    int length = value.size();
+
+    // String length plus 2 for quote marks plus 8 so we can accomodate a few escaped characters.
+    builder.reserveCapacity(builder.size() + length + 2 + 8);
+
+    builder.append('"');
+
+    const UChar* data = value.data();
+    for (int i = 0; i < length; ++i) {
+        int start = i;
+        while (i < length && (data[i] > 0x1F && data[i] != '"' && data[i] != '\\'))
+            ++i;
+        builder.append(data + start, i - start);
+        if (i >= length)
+            break;
+        switch (data[i]) {
+            case '\t':
+                builder.append('\\');
+                builder.append('t');
+                break;
+            case '\r':
+                builder.append('\\');
+                builder.append('r');
+                break;
+            case '\n':
+                builder.append('\\');
+                builder.append('n');
+                break;
+            case '\f':
+                builder.append('\\');
+                builder.append('f');
+                break;
+            case '\b':
+                builder.append('\\');
+                builder.append('b');
+                break;
+            case '"':
+                builder.append('\\');
+                builder.append('"');
+                break;
+            case '\\':
+                builder.append('\\');
+                builder.append('\\');
+                break;
+            default:
+                static const char hexDigits[] = "0123456789abcdef";
+                UChar ch = data[i];
+                UChar hex[] = { '\\', 'u', hexDigits[(ch >> 12) & 0xF], hexDigits[(ch >> 8) & 0xF], hexDigits[(ch >> 4) & 0xF], hexDigits[ch & 0xF] };
+                builder.append(hex, sizeof(hex) / sizeof(UChar));
+                break;
+        }
+    }
+
+    builder.append('"');
+}
+
+inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionCall& propertyName)
+{
+    ASSERT(!m_exec->hadException());
+    if (!value.isObject() || !asObject(value)->hasProperty(m_exec, m_exec->globalData().propertyNames->toJSON))
+        return value;
+
+    JSValue toJSONFunction = asObject(value)->get(m_exec, m_exec->globalData().propertyNames->toJSON);
+    if (m_exec->hadException())
+        return jsNull();
+
+    if (!toJSONFunction.isObject())
+        return value;
+
+    JSObject* object = asObject(toJSONFunction);
+    CallData callData;
+    CallType callType = object->getCallData(callData);
+    if (callType == CallTypeNone)
+        return value;
+
+    JSValue list[] = { propertyName.value(m_exec) };
+    ArgList args(list, sizeof(list) / sizeof(JSValue));
+    return call(m_exec, object, callType, callData, value, args);
+}
+
+Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& builder, JSValue value, JSObject* holder, const PropertyNameForFunctionCall& propertyName)
+{
+    // Call the toJSON function.
+    value = toJSON(value, propertyName);
+    if (m_exec->hadException())
+        return StringifyFailed;
+    if (value.isUndefined() && !holder->inherits(&JSArray::info))
+        return StringifyFailedDueToUndefinedValue;
+
+    // Call the replacer function.
+    if (m_replacerCallType != CallTypeNone) {
+        JSValue list[] = { propertyName.value(m_exec), value };
+        ArgList args(list, sizeof(list) / sizeof(JSValue));
+        value = call(m_exec, m_replacer, m_replacerCallType, m_replacerCallData, holder, args);
+        if (m_exec->hadException())
+            return StringifyFailed;
+    }
+
+    if (value.isNull()) {
+        builder.append("null");
+        return StringifySucceeded;
+    }
+
+    value = unwrapBoxedPrimitive(value);
+
+    if (value.isBoolean()) {
+        builder.append(value.getBoolean() ? "true" : "false");
+        return StringifySucceeded;
+    }
+
+    UString stringValue;
+    if (value.getString(stringValue)) {
+        appendQuotedString(builder, stringValue);
+        return StringifySucceeded;
+    }
+
+    double numericValue;
+    if (value.getNumber(numericValue)) {
+        if (!isfinite(numericValue))
+            builder.append("null");
+        else
+            builder.append(UString::from(numericValue));
+        return StringifySucceeded;
+    }
+
+    if (!value.isObject())
+        return StringifyFailed;
+
+    JSObject* object = asObject(value);
+
+    // Handle cycle detection, and put the holder on the stack.
+    if (!m_holderCycleDetector.add(object).second) {
+        throwError(m_exec, TypeError);
+        return StringifyFailed;
+    }
+    bool holderStackWasEmpty = m_holderStack.isEmpty();
+    m_holderStack.append(object);
+    if (!holderStackWasEmpty)
+        return StringifySucceeded;
+
+    // If this is the outermost call, then loop to handle everything on the holder stack.
+    TimeoutChecker localTimeoutChecker(m_exec->globalData().timeoutChecker);
+    localTimeoutChecker.reset();
+    unsigned tickCount = localTimeoutChecker.ticksUntilNextCheck();
+    do {
+        while (m_holderStack.last().appendNextProperty(*this, builder)) {
+            if (m_exec->hadException())
+                return StringifyFailed;
+            if (!--tickCount) {
+                if (localTimeoutChecker.didTimeOut(m_exec)) {
+                    m_exec->setException(createInterruptedExecutionException(&m_exec->globalData()));
+                    return StringifyFailed;
+                }
+                tickCount = localTimeoutChecker.ticksUntilNextCheck();
+            }
+        }
+        m_holderCycleDetector.remove(m_holderStack.last().object());
+        m_holderStack.removeLast();
+    } while (!m_holderStack.isEmpty());
+    return StringifySucceeded;
+}
+
+inline bool Stringifier::willIndent() const
+{
+    return !m_gap.isEmpty();
+}
+
+inline void Stringifier::indent()
+{
+    // Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent.
+    int newSize = m_indent.size() + m_gap.size();
+    if (newSize > m_repeatedGap.size())
+        m_repeatedGap.append(m_gap);
+    ASSERT(newSize <= m_repeatedGap.size());
+    m_indent = m_repeatedGap.substr(0, newSize);
+}
+
+inline void Stringifier::unindent()
+{
+    ASSERT(m_indent.size() >= m_gap.size());
+    m_indent = m_repeatedGap.substr(0, m_indent.size() - m_gap.size());
+}
+
+inline void Stringifier::startNewLine(StringBuilder& builder) const
+{
+    if (m_gap.isEmpty())
+        return;
+    builder.append('\n');
+    builder.append(m_indent);
+}
+
+inline Stringifier::Holder::Holder(JSObject* object)
+    : m_object(object)
+    , m_isArray(object->inherits(&JSArray::info))
+    , m_index(0)
+{
+}
+
+bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBuilder& builder)
+{
+    ASSERT(m_index <= m_size);
+
+    ExecState* exec = stringifier.m_exec;
+
+    // First time through, initialize.
+    if (!m_index) {
+        if (m_isArray) {
+            m_isJSArray = isJSArray(&exec->globalData(), m_object);
+            m_size = m_object->get(exec, exec->globalData().propertyNames->length).toUInt32(exec);
+            builder.append('[');
+        } else {
+            if (stringifier.m_usingArrayReplacer)
+                m_propertyNames = stringifier.m_arrayReplacerPropertyNames.data();
+            else {
+                PropertyNameArray objectPropertyNames(exec);
+                m_object->getPropertyNames(exec, objectPropertyNames);
+                m_propertyNames = objectPropertyNames.releaseData();
+            }
+            m_size = m_propertyNames->propertyNameVector().size();
+            builder.append('{');
+        }
+        stringifier.indent();
+    }
+
+    // Last time through, finish up and return false.
+    if (m_index == m_size) {
+        stringifier.unindent();
+        if (m_size && builder[builder.size() - 1] != '{')
+            stringifier.startNewLine(builder);
+        builder.append(m_isArray ? ']' : '}');
+        return false;
+    }
+
+    // Handle a single element of the array or object.
+    unsigned index = m_index++;
+    unsigned rollBackPoint = 0;
+    StringifyResult stringifyResult;
+    if (m_isArray) {
+        // Get the value.
+        JSValue value;
+        if (m_isJSArray && asArray(m_object)->canGetIndex(index))
+            value = asArray(m_object)->getIndex(index);
+        else {
+            PropertySlot slot(m_object);
+            if (!m_object->getOwnPropertySlot(exec, index, slot))
+                slot.setUndefined();
+            if (exec->hadException())
+                return false;
+            value = slot.getValue(exec, index);
+        }
+
+        // Append the separator string.
+        if (index)
+            builder.append(',');
+        stringifier.startNewLine(builder);
+
+        // Append the stringified value.
+        stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object, index);
+    } else {
+        // Get the value.
+        PropertySlot slot(m_object);
+        Identifier& propertyName = m_propertyNames->propertyNameVector()[index];
+        if (!m_object->getOwnPropertySlot(exec, propertyName, slot))
+            return true;
+        JSValue value = slot.getValue(exec, propertyName);
+        if (exec->hadException())
+            return false;
+
+        rollBackPoint = builder.size();
+
+        // Append the separator string.
+        if (builder[rollBackPoint - 1] != '{')
+            builder.append(',');
+        stringifier.startNewLine(builder);
+
+        // Append the property name.
+        appendQuotedString(builder, propertyName.ustring());
+        builder.append(':');
+        if (stringifier.willIndent())
+            builder.append(' ');
+
+        // Append the stringified value.
+        stringifyResult = stringifier.appendStringifiedValue(builder, value, m_object, propertyName);
+    }
+
+    // From this point on, no access to the this pointer or to any members, because the
+    // Holder object may have moved if the call to stringify pushed a new Holder onto
+    // m_holderStack.
+
+    switch (stringifyResult) {
+        case StringifyFailed:
+            builder.append("null");
+            break;
+        case StringifySucceeded:
+            break;
+        case StringifyFailedDueToUndefinedValue:
+            // This only occurs when get an undefined value for an object property.
+            // In this case we don't want the separator and property name that we
+            // already appended, so roll back.
+            builder = builder.substr(0, rollBackPoint);
+            break;
+    }
+
+    return true;
+}
+
+// ------------------------------ JSONObject --------------------------------
+
+const ClassInfo JSONObject::info = { "JSON", 0, 0, ExecState::jsonTable };
+
+/* Source for JSONObject.lut.h
+@begin jsonTable
+  parse         JSONProtoFuncParse             DontEnum|Function 1
+  stringify     JSONProtoFuncStringify         DontEnum|Function 1
+@end
+*/
+
+// ECMA 15.8
+
+bool JSONObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    const HashEntry* entry = ExecState::jsonTable(exec)->entry(exec, propertyName);
+    if (!entry)
+        return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+
+    ASSERT(entry->attributes() & Function);
+    setUpStaticFunctionSlot(exec, entry, this, propertyName, slot);
+    return true;
+}
+
+void JSONObject::markStringifiers(Stringifier* stringifier)
+{
+    stringifier->mark();
+}
+
+class Walker {
+public:
+    Walker(ExecState* exec, JSObject* function, CallType callType, CallData callData)
+        : m_exec(exec)
+        , m_function(function)
+        , m_callType(callType)
+        , m_callData(callData)
+    {
+    }
+    JSValue walk(JSValue unfiltered);
+private:
+    JSValue callReviver(JSValue property, JSValue unfiltered)
+    {
+        JSValue args[] = { property, unfiltered };
+        ArgList argList(args, 2);
+        return call(m_exec, m_function, m_callType, m_callData, jsNull(), argList);
+    }
+
+    friend class Holder;
+
+    ExecState* m_exec;
+    JSObject* m_function;
+    CallType m_callType;
+    CallData m_callData;
+};
+    
+enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember, 
+                                 ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember };
+NEVER_INLINE JSValue Walker::walk(JSValue unfiltered)
+{
+    Vector<PropertyNameArray, 16> propertyStack;
+    Vector<uint32_t, 16> indexStack;
+    Vector<JSObject*, 16> objectStack;
+    Vector<JSArray*, 16> arrayStack;
+    
+    Vector<WalkerState, 16> stateStack;
+    WalkerState state = StateUnknown;
+    JSValue inValue = unfiltered;
+    JSValue outValue = jsNull();
+    while (1) {
+        switch (state) {
+            arrayStartState:
+            case ArrayStartState: {
+                ASSERT(inValue.isObject());
+                ASSERT(isJSArray(&m_exec->globalData(), asObject(inValue)));
+                JSArray* array = asArray(inValue);
+                arrayStack.append(array);
+                indexStack.append(0);
+                // fallthrough
+            }
+            arrayStartVisitMember:
+            case ArrayStartVisitMember: {
+                JSArray* array = arrayStack.last();
+                uint32_t index = indexStack.last();
+                if (index == array->length()) {
+                    outValue = array;
+                    arrayStack.removeLast();
+                    indexStack.removeLast();
+                    break;
+                }
+                inValue = array->getIndex(index);
+                if (inValue.isObject()) {
+                    stateStack.append(ArrayEndVisitMember);
+                    goto stateUnknown;
+                } else
+                    outValue = inValue;
+                // fallthrough
+            }
+            case ArrayEndVisitMember: {
+                JSArray* array = arrayStack.last();
+                array->setIndex(indexStack.last(), callReviver(jsString(m_exec, UString::from(indexStack.last())), outValue));
+                if (m_exec->hadException())
+                    return jsNull();
+                indexStack.last()++;
+                goto arrayStartVisitMember;
+            }
+            objectStartState:
+            case ObjectStartState: {
+                ASSERT(inValue.isObject());
+                ASSERT(!isJSArray(&m_exec->globalData(), asObject(inValue)));
+                JSObject* object = asObject(inValue);
+                objectStack.append(object);
+                indexStack.append(0);
+                propertyStack.append(PropertyNameArray(m_exec));
+                object->getPropertyNames(m_exec, propertyStack.last());
+                // fallthrough
+            }
+            objectStartVisitMember:
+            case ObjectStartVisitMember: {
+                JSObject* object = objectStack.last();
+                uint32_t index = indexStack.last();
+                PropertyNameArray& properties = propertyStack.last();
+                if (index == properties.size()) {
+                    outValue = object;
+                    objectStack.removeLast();
+                    indexStack.removeLast();
+                    propertyStack.removeLast();
+                    break;
+                }
+                PropertySlot slot;
+                object->getOwnPropertySlot(m_exec, properties[index], slot);
+                inValue = slot.getValue(m_exec, properties[index]);
+                ASSERT(!m_exec->hadException());
+                if (inValue.isObject()) {
+                    stateStack.append(ObjectEndVisitMember);
+                    goto stateUnknown;
+                } else
+                    outValue = inValue;
+                // fallthrough
+            }
+            case ObjectEndVisitMember: {
+                JSObject* object = objectStack.last();
+                Identifier prop = propertyStack.last()[indexStack.last()];
+                PutPropertySlot slot;
+                object->put(m_exec, prop, callReviver(jsString(m_exec, prop.ustring()), outValue), slot);
+                if (m_exec->hadException())
+                    return jsNull();
+                indexStack.last()++;
+                goto objectStartVisitMember;
+            }
+            stateUnknown:
+            case StateUnknown:
+                if (!inValue.isObject()) {
+                    outValue = inValue;
+                    break;
+                }
+                if (isJSArray(&m_exec->globalData(), asObject(inValue)))
+                    goto arrayStartState;
+                goto objectStartState;
+        }
+        if (stateStack.isEmpty())
+            break;
+        state = stateStack.last();
+        stateStack.removeLast();
+    }
+    return callReviver(jsEmptyString(m_exec), outValue);
+}
+
+// ECMA-262 v5 15.12.2
+JSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+    if (args.isEmpty())
+        return throwError(exec, GeneralError, "JSON.parse requires at least one parameter");
+    JSValue value = args.at(0);
+    UString source = value.toString(exec);
+    if (exec->hadException())
+        return jsNull();
+    
+    LiteralParser jsonParser(exec, source, LiteralParser::StrictJSON);
+    JSValue unfiltered = jsonParser.tryLiteralParse();
+    if (!unfiltered)
+        return throwError(exec, SyntaxError, "Unable to parse JSON string");
+    
+    if (args.size() < 2)
+        return unfiltered;
+    
+    JSValue function = args.at(1);
+    CallData callData;
+    CallType callType = function.getCallData(callData);
+    if (callType == CallTypeNone)
+        return unfiltered;
+    return Walker(exec, asObject(function), callType, callData).walk(unfiltered);
+}
+
+// ECMA-262 v5 15.12.3
+JSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec, JSObject*, JSValue, const ArgList& args)
+{
+    if (args.isEmpty())
+        return throwError(exec, GeneralError, "No input to stringify");
+    JSValue value = args.at(0);
+    JSValue replacer = args.at(1);
+    JSValue space = args.at(2);
+    return Stringifier(exec, replacer, space).stringify(value);
+}
+
+} // namespace JSC
diff --git a/runtime/JSONObject.h b/runtime/JSONObject.h
new file mode 100644 (file)
index 0000000..8d5364a
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef JSONObject_h
+#define JSONObject_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+    class Stringifier;
+
+    class JSONObject : public JSObject {
+    public:
+        JSONObject(PassRefPtr<Structure> structure)
+            : JSObject(structure)
+        {
+        }
+
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
+        {
+            return Structure::create(prototype, TypeInfo(ObjectType));
+        }
+
+        static void markStringifiers(Stringifier*);
+
+    private:
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+    };
+
+} // namespace JSC
+
+#endif // JSONObject_h
index e9e95f663556c47d185194dec13c49e4c6df434e..b13f143a6ec0834e47a95968c554c59a8739d51b 100644 (file)
@@ -69,9 +69,11 @@ void JSObject::mark()
     JSCell::mark();
     m_structure->mark();
 
+    PropertyStorage storage = propertyStorage();
+
     size_t storageSize = m_structure->propertyStorageSize();
     for (size_t i = 0; i < storageSize; ++i) {
-        JSValuePtr v = m_propertyStorage[i];
+        JSValue v = JSValue::decode(storage[i]);
         if (!v.marked())
             v.mark();
     }
@@ -98,7 +100,7 @@ static void throwSetterError(ExecState* exec)
 }
 
 // ECMA 8.6.2.2
-void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     ASSERT(value);
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -108,7 +110,7 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr v
         if (!value.isObject() && !value.isNull())
             return;
 
-        JSValuePtr nextPrototypeValue = value;
+        JSValue nextPrototypeValue = value;
         while (nextPrototypeValue && nextPrototypeValue.isObject()) {
             JSObject* nextPrototype = asObject(nextPrototypeValue)->unwrappedObject();
             if (nextPrototype == this) {
@@ -123,21 +125,22 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr v
     }
 
     // Check if there are any setters or getters in the prototype chain
-    JSValuePtr prototype;
+    JSValue prototype;
     for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
         prototype = obj->prototype();
         if (prototype.isNull()) {
-            putDirect(propertyName, value, 0, true, slot);
+            putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
             return;
         }
     }
     
     unsigned attributes;
-    if ((m_structure->get(propertyName, attributes) != WTF::notFound) && attributes & ReadOnly)
+    JSCell* specificValue;
+    if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly)
         return;
 
     for (JSObject* obj = this; ; obj = asObject(prototype)) {
-        if (JSValuePtr gs = obj->getDirect(propertyName)) {
+        if (JSValue gs = obj->getDirect(propertyName)) {
             if (gs.isGetterSetter()) {
                 JSObject* setterFunc = asGetterSetter(gs)->setter();        
                 if (!setterFunc) {
@@ -147,7 +150,7 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr v
                 
                 CallData callData;
                 CallType callType = setterFunc->getCallData(callData);
-                ArgList args;
+                MarkedArgumentBuffer args;
                 args.append(value);
                 call(exec, setterFunc, callType, callData, this, args);
                 return;
@@ -163,22 +166,27 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr v
             break;
     }
 
-    putDirect(propertyName, value, 0, true, slot);
+    putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
     return;
 }
 
-void JSObject::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
+void JSObject::put(ExecState* exec, unsigned propertyName, JSValue value)
 {
     PutPropertySlot slot;
     put(exec, Identifier::from(exec, propertyName), value, slot);
 }
 
-void JSObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
 {
-    putDirect(propertyName, value, attributes);
+    putDirectInternal(exec->globalData(), propertyName, value, attributes, checkReadOnly, slot);
 }
 
-void JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValuePtr value, unsigned attributes)
+void JSObject::putWithAttributes(ExecState* exec, const Identifier& propertyName, JSValue value, unsigned attributes)
+{
+    putDirectInternal(exec->globalData(), propertyName, value, attributes);
+}
+
+void JSObject::putWithAttributes(ExecState* exec, unsigned propertyName, JSValue value, unsigned attributes)
 {
     putWithAttributes(exec, Identifier::from(exec, propertyName), value, attributes);
 }
@@ -199,7 +207,8 @@ bool JSObject::hasProperty(ExecState* exec, unsigned propertyName) const
 bool JSObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
 {
     unsigned attributes;
-    if (m_structure->get(propertyName, attributes) != WTF::notFound) {
+    JSCell* specificValue;
+    if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) {
         if ((attributes & DontDelete))
             return false;
         removeDirect(propertyName);
@@ -226,9 +235,9 @@ bool JSObject::deleteProperty(ExecState* exec, unsigned propertyName)
     return deleteProperty(exec, Identifier::from(exec, propertyName));
 }
 
-static ALWAYS_INLINE JSValuePtr callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
+static ALWAYS_INLINE JSValue callDefaultValueFunction(ExecState* exec, const JSObject* object, const Identifier& propertyName)
 {
-    JSValuePtr function = object->get(exec, propertyName);
+    JSValue function = object->get(exec, propertyName);
     CallData callData;
     CallType callType = function.getCallData(callData);
     if (callType == CallTypeNone)
@@ -239,16 +248,16 @@ static ALWAYS_INLINE JSValuePtr callDefaultValueFunction(ExecState* exec, const
     if (exec->hadException())
         return exec->exception();
 
-    JSValuePtr result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
+    JSValue result = call(exec, function, callType, callData, const_cast<JSObject*>(object), exec->emptyList());
     ASSERT(!result.isGetterSetter());
     if (exec->hadException())
         return exec->exception();
     if (result.isObject())
-        return noValue();
+        return JSValue();
     return result;
 }
 
-bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValuePtr& result)
+bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValue& result)
 {
     result = defaultValue(exec, PreferNumber);
     number = result.toNumber(exec);
@@ -256,18 +265,18 @@ bool JSObject::getPrimitiveNumber(ExecState* exec, double& number, JSValuePtr& r
 }
 
 // ECMA 8.6.2.6
-JSValuePtr JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
+JSValue JSObject::defaultValue(ExecState* exec, PreferredPrimitiveType hint) const
 {
     // Must call toString first for Date objects.
     if ((hint == PreferString) || (hint != PreferNumber && prototype() == exec->lexicalGlobalObject()->datePrototype())) {
-        JSValuePtr value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
+        JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
         if (value)
             return value;
         value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
         if (value)
             return value;
     } else {
-        JSValuePtr value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
+        JSValue value = callDefaultValueFunction(exec, this, exec->propertyNames().valueOf);
         if (value)
             return value;
         value = callDefaultValueFunction(exec, this, exec->propertyNames().toString);
@@ -293,7 +302,7 @@ const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, const Identifi
 
 void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSObject* getterFunction)
 {
-    JSValuePtr object = getDirect(propertyName);
+    JSValue object = getDirect(propertyName);
     if (object && object.isGetterSetter()) {
         ASSERT(m_structure->hasGetterSetterProperties());
         asGetterSetter(object)->setGetter(getterFunction);
@@ -302,7 +311,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO
 
     PutPropertySlot slot;
     GetterSetter* getterSetter = new (exec) GetterSetter;
-    putDirect(propertyName, getterSetter, None, true, slot);
+    putDirectInternal(exec->globalData(), propertyName, getterSetter, Getter, true, slot);
 
     // putDirect will change our Structure if we add a new property. For
     // getters and setters, though, we also need to change our Structure
@@ -320,7 +329,7 @@ void JSObject::defineGetter(ExecState* exec, const Identifier& propertyName, JSO
 
 void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSObject* setterFunction)
 {
-    JSValuePtr object = getDirect(propertyName);
+    JSValue object = getDirect(propertyName);
     if (object && object.isGetterSetter()) {
         ASSERT(m_structure->hasGetterSetterProperties());
         asGetterSetter(object)->setSetter(setterFunction);
@@ -329,7 +338,7 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
 
     PutPropertySlot slot;
     GetterSetter* getterSetter = new (exec) GetterSetter;
-    putDirect(propertyName, getterSetter, None, true, slot);
+    putDirectInternal(exec->globalData(), propertyName, getterSetter, Setter, true, slot);
 
     // putDirect will change our Structure if we add a new property. For
     // getters and setters, though, we also need to change our Structure
@@ -345,11 +354,11 @@ void JSObject::defineSetter(ExecState* exec, const Identifier& propertyName, JSO
     getterSetter->setSetter(setterFunction);
 }
 
-JSValuePtr JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
+JSValue JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
 {
     JSObject* object = this;
     while (true) {
-        if (JSValuePtr value = object->getDirect(propertyName)) {
+        if (JSValue value = object->getDirect(propertyName)) {
             if (!value.isGetterSetter())
                 return jsUndefined();
             JSObject* functionObject = asGetterSetter(value)->getter();
@@ -364,11 +373,11 @@ JSValuePtr JSObject::lookupGetter(ExecState*, const Identifier& propertyName)
     }
 }
 
-JSValuePtr JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
+JSValue JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
 {
     JSObject* object = this;
     while (true) {
-        if (JSValuePtr value = object->getDirect(propertyName)) {
+        if (JSValue value = object->getDirect(propertyName)) {
             if (!value.isGetterSetter())
                 return jsUndefined();
             JSObject* functionObject = asGetterSetter(value)->setter();
@@ -383,16 +392,16 @@ JSValuePtr JSObject::lookupSetter(ExecState*, const Identifier& propertyName)
     }
 }
 
-bool JSObject::hasInstance(ExecState* exec, JSValuePtr value, JSValuePtr proto)
+bool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue proto)
 {
+    if (!value.isObject())
+        return false;
+
     if (!proto.isObject()) {
         throwError(exec, TypeError, "instanceof called on an object with an invalid prototype property.");
         return false;
     }
 
-    if (!value.isObject())
-        return false;
-
     JSObject* object = asObject(value);
     while ((object = object->prototype().getObject())) {
         if (proto == object)
@@ -411,7 +420,8 @@ bool JSObject::propertyIsEnumerable(ExecState* exec, const Identifier& propertyN
 
 bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
 {
-    if (m_structure->get(propertyName, attributes) != WTF::notFound)
+    JSCell* specificValue;
+    if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound)
         return true;
     
     // Look in the static hashtable of properties
@@ -424,6 +434,19 @@ bool JSObject::getPropertyAttributes(ExecState* exec, const Identifier& property
     return false;
 }
 
+bool JSObject::getPropertySpecificValue(ExecState*, const Identifier& propertyName, JSCell*& specificValue) const
+{
+    unsigned attributes;
+    if (m_structure->get(propertyName, attributes, specificValue) != WTF::notFound)
+        return true;
+
+    // This could be a function within the static table? - should probably
+    // also look in the hash?  This currently should not be a problem, since
+    // we've currently always call 'get' first, which should have populated
+    // the normal storage.
+    return false;
+}
+
 void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
 {
     m_structure->getEnumerablePropertyNames(exec, propertyNames, this);
@@ -436,7 +459,7 @@ bool JSObject::toBoolean(ExecState*) const
 
 double JSObject::toNumber(ExecState* exec) const
 {
-    JSValuePtr primitive = toPrimitive(exec, PreferNumber);
+    JSValue primitive = toPrimitive(exec, PreferNumber);
     if (exec->hadException()) // should be picked up soon in Nodes.cpp
         return 0.0;
     return primitive.toNumber(exec);
@@ -444,7 +467,7 @@ double JSObject::toNumber(ExecState* exec) const
 
 UString JSObject::toString(ExecState* exec) const
 {
-    JSValuePtr primitive = toPrimitive(exec, PreferString);
+    JSValue primitive = toPrimitive(exec, PreferString);
     if (exec->hadException())
         return "";
     return primitive.toString(exec);
@@ -468,30 +491,30 @@ JSObject* JSObject::unwrappedObject()
 void JSObject::removeDirect(const Identifier& propertyName)
 {
     size_t offset;
-    if (m_structure->isDictionary()) {
+    if (m_structure->isUncacheableDictionary()) {
         offset = m_structure->removePropertyWithoutTransition(propertyName);
         if (offset != WTF::notFound)
-            m_propertyStorage[offset] = jsUndefined();
+            putDirectOffset(offset, jsUndefined());
         return;
     }
 
     RefPtr<Structure> structure = Structure::removePropertyTransition(m_structure, propertyName, offset);
-    if (offset != WTF::notFound)
-        m_propertyStorage[offset] = jsUndefined();
     setStructure(structure.release());
+    if (offset != WTF::notFound)
+        putDirectOffset(offset, jsUndefined());
 }
 
 void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr)
 {
-    putDirect(Identifier(exec, function->name(&exec->globalData())), function, attr);
+    putDirectFunction(Identifier(exec, function->name(&exec->globalData())), function, attr);
 }
 
 void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr)
 {
-    putDirectWithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr);
+    putDirectFunctionWithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr);
 }
 
-NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValuePtr* location)
+NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue* location)
 {
     if (JSObject* getterFunction = asGetterSetter(*location)->getter())
         slot.setGetterSlot(getterFunction);
index 20242ce1137aaf27f4bf1776c661e093dc94e2db..ac4706fb931b04f5ebc0243a186bea1b229e5634 100644 (file)
 #include "PutPropertySlot.h"
 #include "ScopeChain.h"
 #include "Structure.h"
+#include "JSGlobalData.h"
+#include <wtf/StdLibExtras.h>
 
 namespace JSC {
 
+    inline JSCell* getJSFunction(JSGlobalData& globalData, JSValue value)
+    {
+        if (value.isCell() && (value.asCell()->vptr() == globalData.jsFunctionVPtr))
+            return value.asCell();
+        return 0;
+    }
+
     class InternalFunction;
     class PropertyNameArray;
     class Structure;
@@ -49,9 +58,12 @@ namespace JSC {
         DontEnum     = 1 << 2,  // property doesn't appear in (for .. in ..)
         DontDelete   = 1 << 3,  // property can't be deleted
         Function     = 1 << 4,  // property is a function - only used by static hashtables
+        Getter       = 1 << 5,  // property is a getter
+        Setter       = 1 << 6   // property is a setter
     };
 
-    typedef JSValuePtr* PropertyStorage;
+    typedef EncodedJSValue* PropertyStorage;
+    typedef const EncodedJSValue* ConstPropertyStorage;
 
     class JSObject : public JSCell {
         friend class BatchedTransitionOptimizer;
@@ -69,18 +81,16 @@ namespace JSC {
 
         bool inherits(const ClassInfo* classInfo) const { return JSCell::isObject(classInfo); }
 
-        JSValuePtr prototype() const;
-        void setPrototype(JSValuePtr prototype);
+        JSValue prototype() const;
+        void setPrototype(JSValue prototype);
         
         void setStructure(PassRefPtr<Structure>);
         Structure* inheritorID();
 
-        PropertyStorage& propertyStorage() { return m_propertyStorage; }
-
         virtual UString className() const;
 
-        JSValuePtr get(ExecState*, const Identifier& propertyName) const;
-        JSValuePtr get(ExecState*, unsigned propertyName) const;
+        JSValue get(ExecState*, const Identifier& propertyName) const;
+        JSValue get(ExecState*, unsigned propertyName) const;
 
         bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
@@ -88,11 +98,12 @@ namespace JSC {
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
 
-        virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&);
-        virtual void put(ExecState*, unsigned propertyName, JSValuePtr value);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&);
+        virtual void put(ExecState*, unsigned propertyName, JSValue value);
 
-        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes);
-        virtual void putWithAttributes(ExecState*, unsigned propertyName, JSValuePtr value, unsigned attributes);
+        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot);
+        virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes);
+        virtual void putWithAttributes(ExecState*, unsigned propertyName, JSValue value, unsigned attributes);
 
         bool propertyIsEnumerable(ExecState*, const Identifier& propertyName) const;
 
@@ -103,14 +114,14 @@ namespace JSC {
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
 
-        virtual JSValuePtr defaultValue(ExecState*, PreferredPrimitiveType) const;
+        virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const;
 
-        virtual bool hasInstance(ExecState*, JSValuePtr, JSValuePtr prototypeProperty);
+        virtual bool hasInstance(ExecState*, JSValue, JSValue prototypeProperty);
 
         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
-        virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
-        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
+        virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
         virtual UString toString(ExecState*) const;
@@ -120,34 +131,31 @@ namespace JSC {
         virtual JSObject* unwrappedObject();
 
         virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
+        bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const;
 
         // This get function only looks at the property map.
-        JSValuePtr getDirect(const Identifier& propertyName) const
+        JSValue getDirect(const Identifier& propertyName) const
         {
             size_t offset = m_structure->get(propertyName);
-            return offset != WTF::notFound ? m_propertyStorage[offset] : noValue();
+            return offset != WTF::notFound ? getDirectOffset(offset) : JSValue();
         }
 
-        JSValuePtr* getDirectLocation(const Identifier& propertyName)
+        JSValue* getDirectLocation(const Identifier& propertyName)
         {
             size_t offset = m_structure->get(propertyName);
             return offset != WTF::notFound ? locationForOffset(offset) : 0;
         }
 
-        JSValuePtr* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
+        JSValue* getDirectLocation(const Identifier& propertyName, unsigned& attributes)
         {
-            size_t offset = m_structure->get(propertyName, attributes);
+            JSCell* specificFunction;
+            size_t offset = m_structure->get(propertyName, attributes, specificFunction);
             return offset != WTF::notFound ? locationForOffset(offset) : 0;
         }
 
-        size_t offsetForLocation(JSValuePtr* location)
-        {
-            return location - m_propertyStorage;
-        }
-
-        JSValuePtr* locationForOffset(size_t offset)
+        size_t offsetForLocation(JSValue* location) const
         {
-            return &m_propertyStorage[offset];
+            return location - reinterpret_cast<const JSValue*>(propertyStorage());
         }
 
         void transitionTo(Structure*);
@@ -156,22 +164,27 @@ namespace JSC {
         bool hasCustomProperties() { return !m_structure->isEmpty(); }
         bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
 
-        void putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr = 0);
-        void putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+        void putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+        void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0);
+
+        void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
+        void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
         void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0);
-        void putDirectWithoutTransition(const Identifier& propertyName, JSValuePtr value, unsigned attr = 0);
+
+        void putDirectWithoutTransition(const Identifier& propertyName, JSValue value, unsigned attr = 0);
+        void putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
         void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr = 0);
 
         // Fast access to known property offsets.
-        JSValuePtr getDirectOffset(size_t offset) { return m_propertyStorage[offset]; }
-        void putDirectOffset(size_t offset, JSValuePtr value) { m_propertyStorage[offset] = value; }
+        JSValue getDirectOffset(size_t offset) const { return JSValue::decode(propertyStorage()[offset]); }
+        void putDirectOffset(size_t offset, JSValue value) { propertyStorage()[offset] = JSValue::encode(value); }
 
-        void fillGetterPropertySlot(PropertySlot&, JSValuePtr* location);
+        void fillGetterPropertySlot(PropertySlot&, JSValue* location);
 
         virtual void defineGetter(ExecState*, const Identifier& propertyName, JSObject* getterFunction);
         virtual void defineSetter(ExecState*, const Identifier& propertyName, JSObject* setterFunction);
-        virtual JSValuePtr lookupGetter(ExecState*, const Identifier& propertyName);
-        virtual JSValuePtr lookupSetter(ExecState*, const Identifier& propertyName);
+        virtual JSValue lookupGetter(ExecState*, const Identifier& propertyName);
+        virtual JSValue lookupSetter(ExecState*, const Identifier& propertyName);
 
         virtual bool isGlobalObject() const { return false; }
         virtual bool isVariableObject() const { return false; }
@@ -181,36 +194,55 @@ namespace JSC {
 
         void allocatePropertyStorage(size_t oldSize, size_t newSize);
         void allocatePropertyStorageInline(size_t oldSize, size_t newSize);
-        bool usingInlineStorage() const { return m_propertyStorage == m_inlineStorage; }
+        bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
 
-        static const size_t inlineStorageCapacity = 2;
+        static const size_t inlineStorageCapacity = sizeof(EncodedJSValue) == 2 * sizeof(void*) ? 4 : 3;
         static const size_t nonInlineBaseStorageCapacity = 16;
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
             return Structure::create(prototype, TypeInfo(ObjectType, HasStandardGetOwnPropertySlot));
         }
 
-    protected:
-        bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
+        void flattenDictionaryObject()
+        {
+            m_structure->flattenDictionaryStructure(this);
+        }
 
     private:
+        ConstPropertyStorage propertyStorage() const { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
+        PropertyStorage propertyStorage() { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
+
+        const JSValue* locationForOffset(size_t offset) const
+        {
+            return reinterpret_cast<const JSValue*>(&propertyStorage()[offset]);
+        }
+
+        JSValue* locationForOffset(size_t offset)
+        {
+            return reinterpret_cast<JSValue*>(&propertyStorage()[offset]);
+        }
+
+        void putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*);
+        void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+        void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr = 0);
+
         bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
 
         const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
         Structure* createInheritorID();
 
-        RefPtr<Structure> m_inheritorID;
+        union {
+            PropertyStorage m_externalStorage;
+            EncodedJSValue m_inlineStorage[inlineStorageCapacity];
+        };
 
-        PropertyStorage m_propertyStorage;        
-        JSValuePtr m_inlineStorage[inlineStorageCapacity];
+        RefPtr<Structure> m_inheritorID;
     };
+    
+JSObject* constructEmptyObject(ExecState*);
 
-    JSObject* asObject(JSValuePtr);
-
-    JSObject* constructEmptyObject(ExecState*);
-
-inline JSObject* asObject(JSValuePtr value)
+inline JSObject* asObject(JSValue value)
 {
     ASSERT(asCell(value)->isObject());
     return static_cast<JSObject*>(asCell(value));
@@ -218,28 +250,30 @@ inline JSObject* asObject(JSValuePtr value)
 
 inline JSObject::JSObject(PassRefPtr<Structure> structure)
     : JSCell(structure.releaseRef()) // ~JSObject balances this ref()
-    , m_propertyStorage(m_inlineStorage)
 {
     ASSERT(m_structure);
     ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity);
     ASSERT(m_structure->isEmpty());
     ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
+#if USE(JSVALUE64) || USE(JSVALUE32_64)
+    ASSERT(OBJECT_OFFSETOF(JSObject, m_inlineStorage) % sizeof(double) == 0);
+#endif
 }
 
 inline JSObject::~JSObject()
 {
     ASSERT(m_structure);
-    if (m_propertyStorage != m_inlineStorage)
-        delete [] m_propertyStorage;
+    if (!isUsingInlineStorage())
+        delete [] m_externalStorage;
     m_structure->deref();
 }
 
-inline JSValuePtr JSObject::prototype() const
+inline JSValue JSObject::prototype() const
 {
     return m_structure->storedPrototype();
 }
 
-inline void JSObject::setPrototype(JSValuePtr prototype)
+inline void JSObject::setPrototype(JSValue prototype)
 {
     ASSERT(prototype);
     RefPtr<Structure> newStructure = Structure::changePrototypeTransition(m_structure, prototype);
@@ -259,6 +293,11 @@ inline Structure* JSObject::inheritorID()
     return createInheritorID();
 }
 
+inline bool Structure::isUsingInlineStorage() const
+{
+    return (propertyStorageCapacity() == JSObject::inlineStorageCapacity);
+}
+
 inline bool JSCell::isObject(const ClassInfo* info) const
 {
     for (const ClassInfo* ci = classInfo(); ci; ci = ci->parentClass) {
@@ -269,14 +308,14 @@ inline bool JSCell::isObject(const ClassInfo* info) const
 }
 
 // this method is here to be after the inline declaration of JSCell::isObject
-inline bool JSValuePtr::isObject(const ClassInfo* classInfo) const
+inline bool JSValue::isObject(const ClassInfo* classInfo) const
 {
     return isCell() && asCell()->isObject(classInfo);
 }
 
 ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 {
-    if (JSValuePtr* location = getDirectLocation(propertyName)) {
+    if (JSValue* location = getDirectLocation(propertyName)) {
         if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter())
             fillGetterPropertySlot(slot, location);
         else
@@ -293,30 +332,6 @@ ALWAYS_INLINE bool JSObject::inlineGetOwnPropertySlot(ExecState* exec, const Ide
     return false;
 }
 
-ALWAYS_INLINE bool JSObject::getOwnPropertySlotForWrite(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
-{
-    unsigned attributes;
-    if (JSValuePtr* location = getDirectLocation(propertyName, attributes)) {
-        if (m_structure->hasGetterSetterProperties() && location[0].isGetterSetter()) {
-            slotIsWriteable = false;
-            fillGetterPropertySlot(slot, location);
-        } else {
-            slotIsWriteable = !(attributes & ReadOnly);
-            slot.setValueSlot(this, location, offsetForLocation(location));
-        }
-        return true;
-    }
-
-    // non-standard Netscape extension
-    if (propertyName == exec->propertyNames().underscoreProto) {
-        slot.setValue(prototype());
-        slotIsWriteable = false;
-        return true;
-    }
-
-    return false;
-}
-
 // It may seem crazy to inline a function this large, especially a virtual function,
 // but it makes a big difference to property lookup that derived classes can inline their
 // base class call to this.
@@ -340,7 +355,7 @@ inline bool JSObject::getPropertySlot(ExecState* exec, const Identifier& propert
     while (true) {
         if (object->fastGetOwnPropertySlot(exec, propertyName, slot))
             return true;
-        JSValuePtr prototype = object->prototype();
+        JSValue prototype = object->prototype();
         if (!prototype.isObject())
             return false;
         object = asObject(prototype);
@@ -353,14 +368,14 @@ inline bool JSObject::getPropertySlot(ExecState* exec, unsigned propertyName, Pr
     while (true) {
         if (object->getOwnPropertySlot(exec, propertyName, slot))
             return true;
-        JSValuePtr prototype = object->prototype();
+        JSValue prototype = object->prototype();
         if (!prototype.isObject())
             return false;
         object = asObject(prototype);
     }
 }
 
-inline JSValuePtr JSObject::get(ExecState* exec, const Identifier& propertyName) const
+inline JSValue JSObject::get(ExecState* exec, const Identifier& propertyName) const
 {
     PropertySlot slot(this);
     if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
@@ -369,7 +384,7 @@ inline JSValuePtr JSObject::get(ExecState* exec, const Identifier& propertyName)
     return jsUndefined();
 }
 
-inline JSValuePtr JSObject::get(ExecState* exec, unsigned propertyName) const
+inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const
 {
     PropertySlot slot(this);
     if (const_cast<JSObject*>(this)->getPropertySlot(exec, propertyName, slot))
@@ -378,80 +393,150 @@ inline JSValuePtr JSObject::get(ExecState* exec, unsigned propertyName) const
     return jsUndefined();
 }
 
-inline void JSObject::putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attr)
-{
-    PutPropertySlot slot;
-    putDirect(propertyName, value, attr, false, slot);
-}
-
-inline void JSObject::putDirect(const Identifier& propertyName, JSValuePtr value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)
 {
+    ASSERT(value);
     ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
     if (m_structure->isDictionary()) {
         unsigned currentAttributes;
-        size_t offset = m_structure->get(propertyName, currentAttributes);
+        JSCell* currentSpecificFunction;
+        size_t offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
         if (offset != WTF::notFound) {
+            if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
+                m_structure->despecifyDictionaryFunction(propertyName);
             if (checkReadOnly && currentAttributes & ReadOnly)
                 return;
-            m_propertyStorage[offset] = value;
-            slot.setExistingProperty(this, offset);
+            putDirectOffset(offset, value);
+            if (!specificFunction && !currentSpecificFunction)
+                slot.setExistingProperty(this, offset);
             return;
         }
 
         size_t currentCapacity = m_structure->propertyStorageCapacity();
-        offset = m_structure->addPropertyWithoutTransition(propertyName, attributes);
+        offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, specificFunction);
         if (currentCapacity != m_structure->propertyStorageCapacity())
             allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
 
         ASSERT(offset < m_structure->propertyStorageCapacity());
-        m_propertyStorage[offset] = value;
-        slot.setNewProperty(this, offset);
+        putDirectOffset(offset, value);
+        // See comment on setNewProperty call below.
+        if (!specificFunction)
+            slot.setNewProperty(this, offset);
         return;
     }
 
     size_t offset;
     size_t currentCapacity = m_structure->propertyStorageCapacity();
-    if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, offset)) {
+    if (RefPtr<Structure> structure = Structure::addPropertyTransitionToExistingStructure(m_structure, propertyName, attributes, specificFunction, offset)) {    
         if (currentCapacity != structure->propertyStorageCapacity())
             allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
 
         ASSERT(offset < structure->propertyStorageCapacity());
-        m_propertyStorage[offset] = value;
-        slot.setNewProperty(this, offset);
-        slot.setWasTransition(true);
         setStructure(structure.release());
+        putDirectOffset(offset, value);
+        // See comment on setNewProperty call below.
+        if (!specificFunction)
+            slot.setNewProperty(this, offset);
         return;
     }
 
     unsigned currentAttributes;
-    offset = m_structure->get(propertyName, currentAttributes);
+    JSCell* currentSpecificFunction;
+    offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
     if (offset != WTF::notFound) {
         if (checkReadOnly && currentAttributes & ReadOnly)
             return;
-        m_propertyStorage[offset] = value;
+
+        if (currentSpecificFunction && (specificFunction != currentSpecificFunction)) {
+            setStructure(Structure::despecifyFunctionTransition(m_structure, propertyName));
+            putDirectOffset(offset, value);
+            // Function transitions are not currently cachable, so leave the slot in an uncachable state.
+            return;
+        }
+        putDirectOffset(offset, value);
         slot.setExistingProperty(this, offset);
         return;
     }
 
-    RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, offset);
+    // If we have a specific function, we may have got to this point if there is
+    // already a transition with the correct property name and attributes, but
+    // specialized to a different function.  In this case we just want to give up
+    // and despecialize the transition.
+    // In this case we clear the value of specificFunction which will result
+    // in us adding a non-specific transition, and any subsequent lookup in
+    // Structure::addPropertyTransitionToExistingStructure will just use that.
+    if (specificFunction && m_structure->hasTransition(propertyName, attributes))
+        specificFunction = 0;
+
+    RefPtr<Structure> structure = Structure::addPropertyTransition(m_structure, propertyName, attributes, specificFunction, offset);
+
     if (currentCapacity != structure->propertyStorageCapacity())
         allocatePropertyStorage(currentCapacity, structure->propertyStorageCapacity());
 
     ASSERT(offset < structure->propertyStorageCapacity());
-    m_propertyStorage[offset] = value;
-    slot.setNewProperty(this, offset);
-    slot.setWasTransition(true);
     setStructure(structure.release());
+    putDirectOffset(offset, value);
+    // Function transitions are not currently cachable, so leave the slot in an uncachable state.
+    if (!specificFunction)
+        slot.setNewProperty(this, offset);
+}
+
+inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+{
+    ASSERT(value);
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+    putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
 }
 
-inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
+{
+    PutPropertySlot slot;
+    putDirectInternal(propertyName, value, attributes, false, slot, getJSFunction(globalData, value));
+}
+
+inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+{
+    ASSERT(value);
+    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
+
+    putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0);
+}
+
+inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes)
+{
+    PutPropertySlot slot;
+    putDirectInternal(propertyName, value, attributes, false, slot, 0);
+}
+
+inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+{
+    putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, value);
+}
+
+inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr)
+{
+    PutPropertySlot slot;
+    putDirectInternal(propertyName, value, attr, false, slot, value);
+}
+
+inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValue value, unsigned attributes)
+{
+    size_t currentCapacity = m_structure->propertyStorageCapacity();
+    size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, 0);
+    if (currentCapacity != m_structure->propertyStorageCapacity())
+        allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
+    putDirectOffset(offset, value);
+}
+
+inline void JSObject::putDirectFunctionWithoutTransition(const Identifier& propertyName, JSCell* value, unsigned attributes)
 {
     size_t currentCapacity = m_structure->propertyStorageCapacity();
-    size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes);
+    size_t offset = m_structure->addPropertyWithoutTransition(propertyName, attributes, value);
     if (currentCapacity != m_structure->propertyStorageCapacity())
         allocatePropertyStorage(currentCapacity, m_structure->propertyStorageCapacity());
-    m_propertyStorage[offset] = value;
+    putDirectOffset(offset, value);
 }
 
 inline void JSObject::transitionTo(Structure* newStructure)
@@ -461,21 +546,23 @@ inline void JSObject::transitionTo(Structure* newStructure)
     setStructure(newStructure);
 }
 
-inline JSValuePtr JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
+inline JSValue JSObject::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
 {
     return defaultValue(exec, preferredType);
 }
 
-inline JSValuePtr JSValuePtr::get(ExecState* exec, const Identifier& propertyName) const
+inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName) const
 {
     PropertySlot slot(asValue());
     return get(exec, propertyName, slot);
 }
 
-inline JSValuePtr JSValuePtr::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
+inline JSValue JSValue::get(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) const
 {
     if (UNLIKELY(!isCell())) {
-        JSObject* prototype = JSImmediate::prototype(asValue(), exec);
+        JSObject* prototype = synthesizePrototype(exec);
+        if (propertyName == exec->propertyNames().underscoreProto)
+            return prototype;
         if (!prototype->getPropertySlot(exec, propertyName, slot))
             return jsUndefined();
         return slot.getValue(exec, propertyName);
@@ -485,23 +572,23 @@ inline JSValuePtr JSValuePtr::get(ExecState* exec, const Identifier& propertyNam
         if (cell->fastGetOwnPropertySlot(exec, propertyName, slot))
             return slot.getValue(exec, propertyName);
         ASSERT(cell->isObject());
-        JSValuePtr prototype = static_cast<JSObject*>(cell)->prototype();
+        JSValue prototype = static_cast<JSObject*>(cell)->prototype();
         if (!prototype.isObject())
             return jsUndefined();
         cell = asObject(prototype);
     }
 }
 
-inline JSValuePtr JSValuePtr::get(ExecState* exec, unsigned propertyName) const
+inline JSValue JSValue::get(ExecState* exec, unsigned propertyName) const
 {
     PropertySlot slot(asValue());
     return get(exec, propertyName, slot);
 }
 
-inline JSValuePtr JSValuePtr::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
+inline JSValue JSValue::get(ExecState* exec, unsigned propertyName, PropertySlot& slot) const
 {
     if (UNLIKELY(!isCell())) {
-        JSObject* prototype = JSImmediate::prototype(asValue(), exec);
+        JSObject* prototype = synthesizePrototype(exec);
         if (!prototype->getPropertySlot(exec, propertyName, slot))
             return jsUndefined();
         return slot.getValue(exec, propertyName);
@@ -511,26 +598,26 @@ inline JSValuePtr JSValuePtr::get(ExecState* exec, unsigned propertyName, Proper
         if (cell->getOwnPropertySlot(exec, propertyName, slot))
             return slot.getValue(exec, propertyName);
         ASSERT(cell->isObject());
-        JSValuePtr prototype = static_cast<JSObject*>(cell)->prototype();
+        JSValue prototype = static_cast<JSObject*>(cell)->prototype();
         if (!prototype.isObject())
             return jsUndefined();
         cell = prototype.asCell();
     }
 }
 
-inline void JSValuePtr::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     if (UNLIKELY(!isCell())) {
-        JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value, slot);
+        synthesizeObject(exec)->put(exec, propertyName, value, slot);
         return;
     }
     asCell()->put(exec, propertyName, value, slot);
 }
 
-inline void JSValuePtr::put(ExecState* exec, unsigned propertyName, JSValuePtr value)
+inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
 {
     if (UNLIKELY(!isCell())) {
-        JSImmediate::toObject(asValue(), exec)->put(exec, propertyName, value);
+        synthesizeObject(exec)->put(exec, propertyName, value);
         return;
     }
     asCell()->put(exec, propertyName, value);
@@ -540,14 +627,20 @@ ALWAYS_INLINE void JSObject::allocatePropertyStorageInline(size_t oldSize, size_
 {
     ASSERT(newSize > oldSize);
 
-    JSValuePtr* oldPropertyStorage = m_propertyStorage;
-    m_propertyStorage = new JSValuePtr[newSize];
+    // It's important that this function not rely on m_structure, since
+    // we might be in the middle of a transition.
+    bool wasInline = (oldSize == JSObject::inlineStorageCapacity);
+
+    PropertyStorage oldPropertyStorage = (wasInline ? m_inlineStorage : m_externalStorage);
+    PropertyStorage newPropertyStorage = new EncodedJSValue[newSize];
 
     for (unsigned i = 0; i < oldSize; ++i)
-        m_propertyStorage[i] = oldPropertyStorage[i];
+       newPropertyStorage[i] = oldPropertyStorage[i];
 
-    if (oldPropertyStorage != m_inlineStorage)
+    if (!wasInline)
         delete [] oldPropertyStorage;
+
+    m_externalStorage = newPropertyStorage;
 }
 
 } // namespace JSC
index ec8efea6c693e97b1ffb4f6a7d0879c5786aad98..8c7b53d5319bb0d4e6d05d71f66d3240308d015a 100644 (file)
@@ -37,13 +37,13 @@ JSPropertyNameIterator::~JSPropertyNameIterator()
 {
 }
 
-JSValuePtr JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValue JSPropertyNameIterator::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     ASSERT_NOT_REACHED();
-    return noValue();
+    return JSValue();
 }
 
-bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValuePtr&)
+bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValue&)
 {
     ASSERT_NOT_REACHED();
     return false;
index ebb81b3925d510b83175112a10f3d23c15b2a900..9817c075792008e518092f71960d206ece99c224 100644 (file)
@@ -40,12 +40,12 @@ namespace JSC {
 
     class JSPropertyNameIterator : public JSCell {
     public:
-        static JSPropertyNameIterator* create(ExecState*, JSValuePtr);
+        static JSPropertyNameIterator* create(ExecState*, JSValue);
 
         virtual ~JSPropertyNameIterator();
 
-        virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
-        virtual bool getPrimitiveNumber(ExecState*, double&, JSValuePtr&);
+        virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double&, JSValue&);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
         virtual UString toString(ExecState*) const;
@@ -53,7 +53,7 @@ namespace JSC {
 
         virtual void mark();
 
-        JSValuePtr next(ExecState*);
+        JSValue next(ExecState*);
         void invalidate();
 
     private:
@@ -83,7 +83,7 @@ inline JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, PassRefP
 {
 }
 
-inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValuePtr v)
+inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue v)
 {
     if (v.isUndefinedOrNull())
         return new (exec) JSPropertyNameIterator;
@@ -94,10 +94,10 @@ inline JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, J
     return new (exec) JSPropertyNameIterator(o, propertyNames.releaseData());
 }
 
-inline JSValuePtr JSPropertyNameIterator::next(ExecState* exec)
+inline JSValue JSPropertyNameIterator::next(ExecState* exec)
 {
     if (m_position == m_end)
-        return noValue();
+        return JSValue();
 
     if (m_data->cachedStructure() == m_object->structure() && m_data->cachedPrototypeChain() == m_object->structure()->prototypeChain(exec))
         return jsOwnedString(exec, (*m_position++).ustring());
@@ -108,7 +108,7 @@ inline JSValuePtr JSPropertyNameIterator::next(ExecState* exec)
         m_position++;
     } while (m_position != m_end);
 
-    return noValue();
+    return JSValue();
 }
 
 } // namespace JSC
index 4196822b7291292de4a5e028f76d2b138be0951a..85907c825a6598b50d074babedc722746a995bb0 100644 (file)
@@ -44,7 +44,7 @@ JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
     return exec->globalThisValue();
 }
 
-void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValuePtr value, PutPropertySlot&)
+void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&)
 {
     if (symbolTablePut(propertyName, value))
         return;
@@ -52,7 +52,7 @@ void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValu
     ASSERT_NOT_REACHED();
 }
 
-void JSStaticScopeObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+void JSStaticScopeObject::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue value, unsigned attributes)
 {
     if (symbolTablePutWithAttributes(propertyName, value, attributes))
         return;
@@ -76,9 +76,4 @@ inline bool JSStaticScopeObject::getOwnPropertySlot(ExecState*, const Identifier
     return symbolTableGet(propertyName, slot);
 }
 
-inline bool JSStaticScopeObject::getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
-{
-    return symbolTableGet(propertyName, slot, slotIsWriteable);
-}
-
 }
index e1400b770dee29002f9da761cf0918b3ceae1beb..2caf540a816e33fea69cc40b3ea70a79826f4694 100644 (file)
@@ -43,7 +43,7 @@ namespace JSC{
         };
         
     public:
-        JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValuePtr value, unsigned attributes)
+        JSStaticScopeObject(ExecState* exec, const Identifier& ident, JSValue value, unsigned attributes)
             : JSVariableObject(exec->globalData().staticScopeStructure, new JSStaticScopeObjectData())
         {
             d()->registerStore = value;
@@ -54,11 +54,10 @@ namespace JSC{
         bool isDynamicScope() const;
         virtual JSObject* toThisObject(ExecState*) const;
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
-        virtual void put(ExecState*, const Identifier&, JSValuePtr, PutPropertySlot&);
-        void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes);
+        virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
+        void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
+        static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(ObjectType, NeedsThisConversion)); }
 
     private:
         JSStaticScopeObjectData* d() { return static_cast<JSStaticScopeObjectData*>(JSVariableObject::d); }
index 48391de1f9edbdaa7e4e88f52be611429cf7d9ea..86f95e0dbd62e1f2c3339adb627b313215d11da6 100644 (file)
 
 namespace JSC {
 
-JSValuePtr JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
+JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     return const_cast<JSString*>(this);
 }
 
-bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value)
+bool JSString::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
 {
     value = this;
     number = m_value.toDouble();
@@ -88,9 +88,13 @@ bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNam
     // This function should only be called by JSValue::get.
     if (getStringPropertySlot(exec, propertyName, slot))
         return true;
+    if (propertyName == exec->propertyNames().underscoreProto) {
+        slot.setValue(exec->lexicalGlobalObject()->stringPrototype());
+        return true;
+    }
     slot.setBase(this);
     JSObject* object;
-    for (JSValuePtr prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) {
+    for (JSValue prototype = exec->lexicalGlobalObject()->stringPrototype(); !prototype.isNull(); prototype = object->prototype()) {
         object = asObject(prototype);
         if (object->getOwnPropertySlot(exec, propertyName, slot))
             return true;
index e4baa73aba9809c7c753808f5fad107899304c40..ade3c3b9968055f3dfdb75605f1604eef2dd3bf8 100644 (file)
@@ -23,8 +23,8 @@
 #ifndef JSString_h
 #define JSString_h
 
-#include "CommonIdentifiers.h"
 #include "CallFrame.h"
+#include "CommonIdentifiers.h"
 #include "Identifier.h"
 #include "JSNumberCell.h"
 #include "PropertySlot.h"
@@ -60,7 +60,7 @@ namespace JSC {
 
     class JSString : public JSCell {
         friend class JIT;
-        friend class Interpreter;
+        friend class VPtrSet;
 
     public:
         JSString(JSGlobalData* globalData, const UString& value)
@@ -90,7 +90,7 @@ namespace JSC {
         bool canGetIndex(unsigned i) { return i < static_cast<unsigned>(m_value.size()); }
         JSString* getIndex(JSGlobalData*, unsigned);
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
+        static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, NeedsThisConversion)); }
 
     private:
         enum VPtrStealingHackType { VPtrStealingHack };
@@ -99,8 +99,8 @@ namespace JSC {
         {
         }
 
-        virtual JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType) const;
-        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr& value);
+        virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
+        virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
         virtual bool toBoolean(ExecState*) const;
         virtual double toNumber(ExecState*) const;
         virtual JSObject* toObject(ExecState*) const;
@@ -117,9 +117,9 @@ namespace JSC {
         UString m_value;
     };
 
-    JSString* asString(JSValuePtr);
+    JSString* asString(JSValue);
 
-    inline JSString* asString(JSValuePtr value)
+    inline JSString* asString(JSValue value)
     {
         ASSERT(asCell(value)->isString());
         return static_cast<JSString*>(asCell(value));
@@ -202,11 +202,13 @@ namespace JSC {
         return false;
     }
 
+    inline bool isJSString(JSGlobalData* globalData, JSValue v) { return v.isCell() && v.asCell()->vptr() == globalData->jsStringVPtr; }
+
     // --- JSValue inlines ----------------------------
 
-    inline JSString* JSValuePtr::toThisJSString(ExecState* exec)
+    inline JSString* JSValue::toThisJSString(ExecState* exec)
     {
-        return JSImmediate::isImmediate(asValue()) ? jsString(exec, JSImmediate::toString(asValue())) : asCell()->toThisJSString(exec);
+        return isCell() ? asCell()->toThisJSString(exec) : jsString(exec, toString(exec));
     }
 
 } // namespace JSC
index f549bff5da6695fb3cb469b9bfcbb6d549e4c45a..39a4093d46b637ecd437774488f694705c5e3bba 100644 (file)
 #include "config.h"
 #include "JSValue.h"
 
+#include "BooleanConstructor.h"
+#include "BooleanPrototype.h"
+#include "ExceptionHelpers.h"
+#include "JSGlobalObject.h"
 #include "JSFunction.h"
+#include "JSNotAnObject.h"
+#include "NumberObject.h"
 #include <wtf/MathExtras.h>
+#include <wtf/StringExtras.h>
 
 namespace JSC {
 
 static const double D32 = 4294967296.0;
 
 // ECMA 9.4
-double JSValuePtr::toInteger(ExecState* exec) const
+double JSValue::toInteger(ExecState* exec) const
 {
-    if (isInt32Fast())
-        return getInt32Fast();
+    if (isInt32())
+        return asInt32();
     double d = toNumber(exec);
     return isnan(d) ? 0.0 : trunc(d);
 }
 
-double JSValuePtr::toIntegerPreserveNaN(ExecState* exec) const
+double JSValue::toIntegerPreserveNaN(ExecState* exec) const
 {
-    if (isInt32Fast())
-        return getInt32Fast();
+    if (isInt32())
+        return asInt32();
     return trunc(toNumber(exec));
 }
 
+JSObject* JSValue::toObjectSlowCase(ExecState* exec) const
+{
+    ASSERT(!isCell());
+
+    if (isInt32() || isDouble())
+        return constructNumber(exec, asValue());
+    if (isTrue() || isFalse())
+        return constructBooleanFromImmediateBoolean(exec, asValue());
+    ASSERT(isUndefinedOrNull());
+    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull());
+    exec->setException(exception);
+    return new (exec) JSNotAnObject(exec, exception);
+}
+
+JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const
+{
+    ASSERT(!isCell());
+
+    if (isInt32() || isDouble())
+        return constructNumber(exec, asValue());
+    if (isTrue() || isFalse())
+        return constructBooleanFromImmediateBoolean(exec, asValue());
+    ASSERT(isUndefinedOrNull());
+    return exec->globalThisValue();
+}
+
+JSObject* JSValue::synthesizeObject(ExecState* exec) const
+{
+    ASSERT(!isCell());
+    if (isNumber())
+        return constructNumber(exec, asValue());
+    if (isBoolean())
+        return constructBooleanFromImmediateBoolean(exec, asValue());
+    
+    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull());
+    exec->setException(exception);
+    return new (exec) JSNotAnObject(exec, exception);
+}
+
+JSObject* JSValue::synthesizePrototype(ExecState* exec) const
+{
+    ASSERT(!isCell());
+    if (isNumber())
+        return exec->lexicalGlobalObject()->numberPrototype();
+    if (isBoolean())
+        return exec->lexicalGlobalObject()->booleanPrototype();
+
+    JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull());
+    exec->setException(exception);
+    return new (exec) JSNotAnObject(exec, exception);
+}
+
+#ifndef NDEBUG
+char* JSValue::description()
+{
+    static const size_t size = 32;
+    static char description[size];
+    if (isInt32())
+        snprintf(description, size, "Int32: %d", asInt32());
+    else if (isDouble())
+        snprintf(description, size, "Double: %lf", asDouble());
+    else if (isCell())
+        snprintf(description, size, "Cell: %p", asCell());
+    else if (isTrue())
+        snprintf(description, size, "True");
+    else if (isFalse())
+        snprintf(description, size, "False");
+    else if (isNull())
+        snprintf(description, size, "Null");
+    else {
+        ASSERT(isUndefined());
+        snprintf(description, size, "Undefined");
+    }
+
+    return description;
+}
+#endif
+
 int32_t toInt32SlowCase(double d, bool& ok)
 {
     ok = true;
@@ -84,4 +169,9 @@ uint32_t toUInt32SlowCase(double d, bool& ok)
     return static_cast<uint32_t>(d32);
 }
 
+NEVER_INLINE double nonInlineNaN()
+{
+    return std::numeric_limits<double>::quiet_NaN();
+}
+
 } // namespace JSC
index 1172a1bc03187c2b42f19700f371fd52f10cce07..cbf8fc54880da6f344fe762094737bf56f09b4f2 100644 (file)
 
 #include "CallData.h"
 #include "ConstructData.h"
+#include <math.h>
+#include <wtf/AlwaysInline.h>
+#include <wtf/Assertions.h>
+#include <wtf/HashTraits.h>
+#include <wtf/MathExtras.h>
 
 namespace JSC {
 
     class Identifier;
     class JSCell;
+    class JSGlobalData;
+    class JSImmediate;
     class JSObject;
     class JSString;
     class PropertySlot;
@@ -44,62 +51,74 @@ namespace JSC {
 
     enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
 
-    class JSImmediate;
-    class JSValueEncodedAsPointer;
+#if USE(JSVALUE32_64)
+    typedef int64_t EncodedJSValue;
+#else
+    typedef void* EncodedJSValue;
+#endif
 
-    class JSValuePtr {
-        friend class JSImmediate;
+    double nonInlineNaN();
+    int32_t toInt32SlowCase(double, bool& ok);
+    uint32_t toUInt32SlowCase(double, bool& ok);
 
-        static JSValuePtr makeImmediate(intptr_t value)
-        {
-            return JSValuePtr(reinterpret_cast<JSCell*>(value));
-        }
+    class JSValue {
+        friend class JSImmediate;
+        friend struct EncodedJSValueHashTraits;
+        friend class JIT;
+        friend class JITStubs;
+        friend class JITStubCall;
 
-        intptr_t immediateValue()
-        {
-            return reinterpret_cast<intptr_t>(m_ptr);
-        }
-        
     public:
-        JSValuePtr()
-            : m_ptr(0)
-        {
-        }
-
-        JSValuePtr(JSCell* ptr)
-            : m_ptr(ptr)
-        {
-        }
-
-        JSValuePtr(const JSCell* ptr)
-            : m_ptr(const_cast<JSCell*>(ptr))
-        {
-        }
-
-        operator bool() const
-        {
-            return m_ptr;
-        }
-
-        bool operator==(const JSValuePtr other) const
-        {
-            return m_ptr == other.m_ptr;
-        }
-
-        bool operator!=(const JSValuePtr other) const
-        {
-            return m_ptr != other.m_ptr;
-        }
-
-        static JSValueEncodedAsPointer* encode(JSValuePtr value)
-        {
-            return reinterpret_cast<JSValueEncodedAsPointer*>(value.m_ptr);
-        }
-
-        static JSValuePtr decode(JSValueEncodedAsPointer* ptr)
-        {
-            return JSValuePtr(reinterpret_cast<JSCell*>(ptr));
-        }
+        static EncodedJSValue encode(JSValue value);
+        static JSValue decode(EncodedJSValue ptr);
+#if !USE(JSVALUE32_64)
+    private:
+        static JSValue makeImmediate(intptr_t value);
+        intptr_t immediateValue();
+    public:
+#endif
+        enum JSNullTag { JSNull };
+        enum JSUndefinedTag { JSUndefined };
+        enum JSTrueTag { JSTrue };
+        enum JSFalseTag { JSFalse };
+
+        JSValue();
+        JSValue(JSNullTag);
+        JSValue(JSUndefinedTag);
+        JSValue(JSTrueTag);
+        JSValue(JSFalseTag);
+        JSValue(JSCell* ptr);
+        JSValue(const JSCell* ptr);
+
+        // Numbers
+        JSValue(ExecState*, double);
+        JSValue(ExecState*, char);
+        JSValue(ExecState*, unsigned char);
+        JSValue(ExecState*, short);
+        JSValue(ExecState*, unsigned short);
+        JSValue(ExecState*, int);
+        JSValue(ExecState*, unsigned);
+        JSValue(ExecState*, long);
+        JSValue(ExecState*, unsigned long);
+        JSValue(ExecState*, long long);
+        JSValue(ExecState*, unsigned long long);
+        JSValue(JSGlobalData*, double);
+        JSValue(JSGlobalData*, int);
+        JSValue(JSGlobalData*, unsigned);
+
+        operator bool() const;
+        bool operator==(const JSValue& other) const;
+        bool operator!=(const JSValue& other) const;
+
+        bool isInt32() const;
+        bool isUInt32() const;
+        bool isDouble() const;
+        bool isTrue() const;
+        bool isFalse() const;
+
+        int32_t asInt32() const;
+        uint32_t asUInt32() const;
+        double asDouble() const;
 
         // Querying the type.
         bool isUndefined() const;
@@ -126,43 +145,27 @@ namespace JSC {
 
         // Extracting integer values.
         bool getUInt32(uint32_t&) const;
-        bool getTruncatedInt32(int32_t&) const;
-        bool getTruncatedUInt32(uint32_t&) const;
         
         // Basic conversions.
-        JSValuePtr toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
-        bool getPrimitiveNumber(ExecState*, double& number, JSValuePtr&);
+        JSValue toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
+        bool getPrimitiveNumber(ExecState*, double& number, JSValue&);
 
         bool toBoolean(ExecState*) const;
 
         // toNumber conversion is expected to be side effect free if an exception has
         // been set in the ExecState already.
         double toNumber(ExecState*) const;
-        JSValuePtr toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
+        JSValue toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
         UString toString(ExecState*) const;
         JSObject* toObject(ExecState*) const;
 
         // Integer conversions.
-        // 'x.numberToInt32(output)' is equivalent to 'x.isNumber() && x.toInt32(output)'
         double toInteger(ExecState*) const;
         double toIntegerPreserveNaN(ExecState*) const;
         int32_t toInt32(ExecState*) const;
         int32_t toInt32(ExecState*, bool& ok) const;
-        bool numberToInt32(int32_t& arg);
         uint32_t toUInt32(ExecState*) const;
         uint32_t toUInt32(ExecState*, bool& ok) const;
-        bool numberToUInt32(uint32_t& arg);
-
-        // Fast integer operations; these values return results where the value is trivially available
-        // in a convenient form, for use in optimizations.  No assumptions should be made based on the
-        // results of these operations, for example !isInt32Fast() does not necessarily indicate the
-        // result of getNumber will not be 0.
-        bool isInt32Fast() const;
-        int32_t getInt32Fast() const;
-        bool isUInt32Fast() const;
-        uint32_t getUInt32Fast() const;
-        static JSValuePtr makeInt32Fast(int32_t);
-        static bool areBothInt32Fast(JSValuePtr, JSValuePtr);
 
         // Floating point conversions (this is a convenience method for webcore;
         // signle precision float is not a representation used in JS or JSC).
@@ -173,49 +176,632 @@ namespace JSC {
         bool marked() const;
 
         // Object operations, with the toObject operation included.
-        JSValuePtr get(ExecState*, const Identifier& propertyName) const;
-        JSValuePtr get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
-        JSValuePtr get(ExecState*, unsigned propertyName) const;
-        JSValuePtr get(ExecState*, unsigned propertyName, PropertySlot&) const;
-        void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
-        void put(ExecState*, unsigned propertyName, JSValuePtr);
+        JSValue get(ExecState*, const Identifier& propertyName) const;
+        JSValue get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
+        JSValue get(ExecState*, unsigned propertyName) const;
+        JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
+        void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+        void put(ExecState*, unsigned propertyName, JSValue);
 
         bool needsThisConversion() const;
         JSObject* toThisObject(ExecState*) const;
         UString toThisString(ExecState*) const;
         JSString* toThisJSString(ExecState*);
 
-        static bool equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2);
-        static bool equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2);
-        static bool equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2);
-        static bool strictEqual(JSValuePtr v1, JSValuePtr v2);
-        static bool strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2);
-        static bool strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2);
+        static bool equal(ExecState* exec, JSValue v1, JSValue v2);
+        static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
+        static bool equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2);
+        static bool strictEqual(JSValue v1, JSValue v2);
+        static bool strictEqualSlowCase(JSValue v1, JSValue v2);
+        static bool strictEqualSlowCaseInline(JSValue v1, JSValue v2);
 
-        JSValuePtr getJSNumber(); // noValue() if this is not a JSNumber or number object
+        JSValue getJSNumber(); // JSValue() if this is not a JSNumber or number object
 
         bool isCell() const;
         JSCell* asCell() const;
 
+#ifndef NDEBUG
+        char* description();
+#endif
+
     private:
-        inline const JSValuePtr asValue() const { return *this; }
+        enum HashTableDeletedValueTag { HashTableDeletedValue };
+        JSValue(HashTableDeletedValueTag);
+
+        inline const JSValue asValue() const { return *this; }
+        JSObject* toObjectSlowCase(ExecState*) const;
+        JSObject* toThisObjectSlowCase(ExecState*) const;
+
+        enum { Int32Tag =        0xffffffff };
+        enum { CellTag =         0xfffffffe };
+        enum { TrueTag =         0xfffffffd };
+        enum { FalseTag =        0xfffffffc };
+        enum { NullTag =         0xfffffffb };
+        enum { UndefinedTag =    0xfffffffa };
+        enum { DeletedValueTag = 0xfffffff9 };
+
+        enum { LowestTag =  DeletedValueTag };
+
+        uint32_t tag() const;
+        int32_t payload() const;
+
+        JSObject* synthesizePrototype(ExecState*) const;
+        JSObject* synthesizeObject(ExecState*) const;
+
+#if USE(JSVALUE32_64)
+        union {
+            EncodedJSValue asEncodedJSValue;
+            double asDouble;
+#if PLATFORM(BIG_ENDIAN)
+            struct {
+                int32_t tag;
+                int32_t payload;
+            } asBits;
+#else
+            struct {
+                int32_t payload;
+                int32_t tag;
+            } asBits;
+#endif
+        } u;
+#else // USE(JSVALUE32_64)
+        JSCell* m_ptr;
+#endif // USE(JSVALUE32_64)
+    };
 
-        bool isDoubleNumber() const;
-        double getDoubleNumber() const;
+#if USE(JSVALUE32_64)
+    typedef IntHash<EncodedJSValue> EncodedJSValueHash;
 
-        JSCell* m_ptr;
+    struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
+        static const bool emptyValueIsZero = false;
+        static EncodedJSValue emptyValue() { return JSValue::encode(JSValue()); }
+        static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
+        static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
     };
+#else
+    typedef PtrHash<EncodedJSValue> EncodedJSValueHash;
+
+    struct EncodedJSValueHashTraits : HashTraits<EncodedJSValue> {
+        static void constructDeletedValue(EncodedJSValue& slot) { slot = JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
+        static bool isDeletedValue(EncodedJSValue value) { return value == JSValue::encode(JSValue(JSValue::HashTableDeletedValue)); }
+    };
+#endif
+
+    // Stand-alone helper functions.
+    inline JSValue jsNull()
+    {
+        return JSValue(JSValue::JSNull);
+    }
+
+    inline JSValue jsUndefined()
+    {
+        return JSValue(JSValue::JSUndefined);
+    }
+
+    inline JSValue jsBoolean(bool b)
+    {
+        return b ? JSValue(JSValue::JSTrue) : JSValue(JSValue::JSFalse);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, double d)
+    {
+        return JSValue(exec, d);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, char i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned char i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, short i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned short i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, int i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, long long i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(ExecState* exec, unsigned long long i)
+    {
+        return JSValue(exec, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, double d)
+    {
+        return JSValue(globalData, d);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, int i)
+    {
+        return JSValue(globalData, i);
+    }
+
+    ALWAYS_INLINE JSValue jsNumber(JSGlobalData* globalData, unsigned i)
+    {
+        return JSValue(globalData, i);
+    }
+
+    inline bool operator==(const JSValue a, const JSCell* b) { return a == JSValue(b); }
+    inline bool operator==(const JSCell* a, const JSValue b) { return JSValue(a) == b; }
+
+    inline bool operator!=(const JSValue a, const JSCell* b) { return a != JSValue(b); }
+    inline bool operator!=(const JSCell* a, const JSValue b) { return JSValue(a) != b; }
+
+    inline int32_t toInt32(double val)
+    {
+        if (!(val >= -2147483648.0 && val < 2147483648.0)) {
+            bool ignored;
+            return toInt32SlowCase(val, ignored);
+        }
+        return static_cast<int32_t>(val);
+    }
+
+    inline uint32_t toUInt32(double val)
+    {
+        if (!(val >= 0.0 && val < 4294967296.0)) {
+            bool ignored;
+            return toUInt32SlowCase(val, ignored);
+        }
+        return static_cast<uint32_t>(val);
+    }
+
+    ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
+    {
+        if (isInt32())
+            return asInt32();
+        bool ignored;
+        return toInt32SlowCase(toNumber(exec), ignored);
+    }
+
+    inline uint32_t JSValue::toUInt32(ExecState* exec) const
+    {
+        if (isUInt32())
+            return asInt32();
+        bool ignored;
+        return toUInt32SlowCase(toNumber(exec), ignored);
+    }
+
+    inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
+    {
+        if (isInt32()) {
+            ok = true;
+            return asInt32();
+        }
+        return toInt32SlowCase(toNumber(exec), ok);
+    }
+
+    inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
+    {
+        if (isUInt32()) {
+            ok = true;
+            return asInt32();
+        }
+        return toUInt32SlowCase(toNumber(exec), ok);
+    }
+
+#if USE(JSVALUE32_64)
+    inline JSValue jsNaN(ExecState* exec)
+    {
+        return JSValue(exec, nonInlineNaN());
+    }
+
+    // JSValue member functions.
+    inline EncodedJSValue JSValue::encode(JSValue value)
+    {
+        return value.u.asEncodedJSValue;
+    }
+
+    inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
+    {
+        JSValue v;
+        v.u.asEncodedJSValue = encodedJSValue;
+        return v;
+    }
+
+    inline JSValue::JSValue()
+    {
+        u.asBits.tag = CellTag;
+        u.asBits.payload = 0;
+    }
+
+    inline JSValue::JSValue(JSNullTag)
+    {
+        u.asBits.tag = NullTag;
+        u.asBits.payload = 0;
+    }
+    
+    inline JSValue::JSValue(JSUndefinedTag)
+    {
+        u.asBits.tag = UndefinedTag;
+        u.asBits.payload = 0;
+    }
+    
+    inline JSValue::JSValue(JSTrueTag)
+    {
+        u.asBits.tag = TrueTag;
+        u.asBits.payload = 0;
+    }
+    
+    inline JSValue::JSValue(JSFalseTag)
+    {
+        u.asBits.tag = FalseTag;
+        u.asBits.payload = 0;
+    }
+
+    inline JSValue::JSValue(HashTableDeletedValueTag)
+    {
+        u.asBits.tag = DeletedValueTag;
+        u.asBits.payload = 0;
+    }
+
+    inline JSValue::JSValue(JSCell* ptr)
+    {
+        u.asBits.tag = CellTag;
+        u.asBits.payload = reinterpret_cast<int32_t>(ptr);
+    }
+
+    inline JSValue::JSValue(const JSCell* ptr)
+    {
+        u.asBits.tag = CellTag;
+        u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
+    }
+
+    inline JSValue::operator bool() const
+    {
+        return u.asBits.payload || tag() != CellTag;
+    }
+
+    inline bool JSValue::operator==(const JSValue& other) const
+    {
+        return u.asEncodedJSValue == other.u.asEncodedJSValue;
+    }
+
+    inline bool JSValue::operator!=(const JSValue& other) const
+    {
+        return u.asEncodedJSValue != other.u.asEncodedJSValue;
+    }
+
+    inline bool JSValue::isUndefined() const
+    {
+        return tag() == UndefinedTag;
+    }
+
+    inline bool JSValue::isNull() const
+    {
+        return tag() == NullTag;
+    }
+
+    inline bool JSValue::isUndefinedOrNull() const
+    {
+        return isUndefined() || isNull();
+    }
+
+    inline bool JSValue::isCell() const
+    {
+        return tag() == CellTag;
+    }
+
+    inline bool JSValue::isInt32() const
+    {
+        return tag() == Int32Tag;
+    }
+
+    inline bool JSValue::isUInt32() const
+    {
+        return tag() == Int32Tag && asInt32() > -1;
+    }
+
+    inline bool JSValue::isDouble() const
+    {
+        return tag() < LowestTag;
+    }
+
+    inline bool JSValue::isTrue() const
+    {
+        return tag() == TrueTag;
+    }
+
+    inline bool JSValue::isFalse() const
+    {
+        return tag() == FalseTag;
+    }
+
+    inline uint32_t JSValue::tag() const
+    {
+        return u.asBits.tag;
+    }
+    
+    inline int32_t JSValue::payload() const
+    {
+        return u.asBits.payload;
+    }
+    
+    inline int32_t JSValue::asInt32() const
+    {
+        ASSERT(isInt32());
+        return u.asBits.payload;
+    }
+    
+    inline uint32_t JSValue::asUInt32() const
+    {
+        ASSERT(isUInt32());
+        return u.asBits.payload;
+    }
+    
+    inline double JSValue::asDouble() const
+    {
+        ASSERT(isDouble());
+        return u.asDouble;
+    }
+    
+    ALWAYS_INLINE JSCell* JSValue::asCell() const
+    {
+        ASSERT(isCell());
+        return reinterpret_cast<JSCell*>(u.asBits.payload);
+    }
+
+    inline JSValue::JSValue(ExecState* exec, double d)
+    {
+        const int32_t asInt32 = static_cast<int32_t>(d);
+        if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
+            u.asDouble = d;
+            return;
+        }
+        *this = JSValue(exec, static_cast<int32_t>(d));
+    }
+
+    inline JSValue::JSValue(ExecState* exec, char i)
+    {
+        *this = JSValue(exec, static_cast<int32_t>(i));
+    }
+
+    inline JSValue::JSValue(ExecState* exec, unsigned char i)
+    {
+        *this = JSValue(exec, static_cast<int32_t>(i));
+    }
+
+    inline JSValue::JSValue(ExecState* exec, short i)
+    {
+        *this = JSValue(exec, static_cast<int32_t>(i));
+    }
+
+    inline JSValue::JSValue(ExecState* exec, unsigned short i)
+    {
+        *this = JSValue(exec, static_cast<int32_t>(i));
+    }
+
+    inline JSValue::JSValue(ExecState*, int i)
+    {
+        u.asBits.tag = Int32Tag;
+        u.asBits.payload = i;
+    }
+
+    inline JSValue::JSValue(ExecState* exec, unsigned i)
+    {
+        if (static_cast<int32_t>(i) < 0) {
+            *this = JSValue(exec, static_cast<double>(i));
+            return;
+        }
+        *this = JSValue(exec, static_cast<int32_t>(i));
+    }
+
+    inline JSValue::JSValue(ExecState* exec, long i)
+    {
+        if (static_cast<int32_t>(i) != i) {
+            *this = JSValue(exec, static_cast<double>(i));
+            return;
+        }
+        *this = JSValue(exec, static_cast<int32_t>(i));
+    }
+
+    inline JSValue::JSValue(ExecState* exec, unsigned long i)
+    {
+        if (static_cast<uint32_t>(i) != i) {
+            *this = JSValue(exec, static_cast<double>(i));
+            return;
+        }
+        *this = JSValue(exec, static_cast<uint32_t>(i));
+    }
+
+    inline JSValue::JSValue(ExecState* exec, long long i)
+    {
+        if (static_cast<int32_t>(i) != i) {
+            *this = JSValue(exec, static_cast<double>(i));
+            return;
+        }
+        *this = JSValue(exec, static_cast<int32_t>(i));
+    }
 
-    inline JSValuePtr noValue()
+    inline JSValue::JSValue(ExecState* exec, unsigned long long i)
     {
-        return JSValuePtr();
+        if (static_cast<uint32_t>(i) != i) {
+            *this = JSValue(exec, static_cast<double>(i));
+            return;
+        }
+        *this = JSValue(exec, static_cast<uint32_t>(i));
     }
 
-    inline bool operator==(const JSValuePtr a, const JSCell* b) { return a == JSValuePtr(b); }
-    inline bool operator==(const JSCell* a, const JSValuePtr b) { return JSValuePtr(a) == b; }
+    inline JSValue::JSValue(JSGlobalData* globalData, double d)
+    {
+        const int32_t asInt32 = static_cast<int32_t>(d);
+        if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
+            u.asDouble = d;
+            return;
+        }
+        *this = JSValue(globalData, static_cast<int32_t>(d));
+    }
+    
+    inline JSValue::JSValue(JSGlobalData*, int i)
+    {
+        u.asBits.tag = Int32Tag;
+        u.asBits.payload = i;
+    }
+    
+    inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
+    {
+        if (static_cast<int32_t>(i) < 0) {
+            *this = JSValue(globalData, static_cast<double>(i));
+            return;
+        }
+        *this = JSValue(globalData, static_cast<int32_t>(i));
+    }
 
-    inline bool operator!=(const JSValuePtr a, const JSCell* b) { return a != JSValuePtr(b); }
-    inline bool operator!=(const JSCell* a, const JSValuePtr b) { return JSValuePtr(a) != b; }
+    inline bool JSValue::isNumber() const
+    {
+        return isInt32() || isDouble();
+    }
+
+    inline bool JSValue::isBoolean() const
+    {
+        return isTrue() || isFalse();
+    }
+
+    inline bool JSValue::getBoolean(bool& v) const
+    {
+        if (isTrue()) {
+            v = true;
+            return true;
+        }
+        if (isFalse()) {
+            v = false;
+            return true;
+        }
+        
+        return false;
+    }
+
+    inline bool JSValue::getBoolean() const
+    {
+        ASSERT(isBoolean());
+        return tag() == TrueTag;
+    }
+
+    inline double JSValue::uncheckedGetNumber() const
+    {
+        ASSERT(isNumber());
+        return isInt32() ? asInt32() : asDouble();
+    }
+
+    ALWAYS_INLINE JSValue JSValue::toJSNumber(ExecState* exec) const
+    {
+        return isNumber() ? asValue() : jsNumber(exec, this->toNumber(exec));
+    }
+
+    inline bool JSValue::getNumber(double& result) const
+    {
+        if (isInt32()) {
+            result = asInt32();
+            return true;
+        }
+        if (isDouble()) {
+            result = asDouble();
+            return true;
+        }
+        return false;
+    }
+
+#else // USE(JSVALUE32_64)
+
+    // JSValue member functions.
+    inline EncodedJSValue JSValue::encode(JSValue value)
+    {
+        return reinterpret_cast<EncodedJSValue>(value.m_ptr);
+    }
+
+    inline JSValue JSValue::decode(EncodedJSValue ptr)
+    {
+        return JSValue(reinterpret_cast<JSCell*>(ptr));
+    }
+
+    inline JSValue JSValue::makeImmediate(intptr_t value)
+    {
+        return JSValue(reinterpret_cast<JSCell*>(value));
+    }
+
+    inline intptr_t JSValue::immediateValue()
+    {
+        return reinterpret_cast<intptr_t>(m_ptr);
+    }
+    
+    // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page.
+    inline JSValue::JSValue()
+        : m_ptr(0)
+    {
+    }
+
+    // 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page.
+    inline JSValue::JSValue(HashTableDeletedValueTag)
+        : m_ptr(reinterpret_cast<JSCell*>(0x4))
+    {
+    }
+
+    inline JSValue::JSValue(JSCell* ptr)
+        : m_ptr(ptr)
+    {
+    }
+
+    inline JSValue::JSValue(const JSCell* ptr)
+        : m_ptr(const_cast<JSCell*>(ptr))
+    {
+    }
+
+    inline JSValue::operator bool() const
+    {
+        return m_ptr;
+    }
+
+    inline bool JSValue::operator==(const JSValue& other) const
+    {
+        return m_ptr == other.m_ptr;
+    }
+
+    inline bool JSValue::operator!=(const JSValue& other) const
+    {
+        return m_ptr != other.m_ptr;
+    }
+
+    inline bool JSValue::isUndefined() const
+    {
+        return asValue() == jsUndefined();
+    }
+
+    inline bool JSValue::isNull() const
+    {
+        return asValue() == jsNull();
+    }
+#endif // USE(JSVALUE32_64)
 
 } // namespace JSC
 
index 9bf5c4f6015fc4689c0ddea6d85f5baa99d685b7..b969da5e48bddcf031c09fee10a54f744e9df92e 100644 (file)
@@ -46,7 +46,7 @@ namespace JSC {
     public:
         SymbolTable& symbolTable() const { return *d->symbolTable; }
 
-        virtual void putWithAttributes(ExecState*, const Identifier&, JSValuePtr, unsigned attributes) = 0;
+        virtual void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes) = 0;
 
         virtual bool deleteProperty(ExecState*, const Identifier&);
         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
@@ -90,8 +90,8 @@ namespace JSC {
 
         bool symbolTableGet(const Identifier&, PropertySlot&);
         bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
-        bool symbolTablePut(const Identifier&, JSValuePtr);
-        bool symbolTablePutWithAttributes(const Identifier&, JSValuePtr, unsigned attributes);
+        bool symbolTablePut(const Identifier&, JSValue);
+        bool symbolTablePutWithAttributes(const Identifier&, JSValue, unsigned attributes);
 
         JSVariableObjectData* d;
     };
@@ -117,7 +117,7 @@ namespace JSC {
         return false;
     }
 
-    inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValuePtr value)
+    inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue value)
     {
         ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
@@ -130,7 +130,7 @@ namespace JSC {
         return true;
     }
 
-    inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValuePtr value, unsigned attributes)
+    inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue value, unsigned attributes)
     {
         ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
 
index 7381128d89f378392a62e29e5d07528aaaf77741..2a2e3c6ffdddabf0be3da80fb60f62b220c24455 100644 (file)
@@ -33,22 +33,21 @@ namespace JSC {
         explicit JSWrapperObject(PassRefPtr<Structure>);
 
     public:
-        JSValuePtr internalValue() const { return m_internalValue; }
-        void setInternalValue(JSValuePtr);
+        JSValue internalValue() const { return m_internalValue; }
+        void setInternalValue(JSValue);
         
         virtual void mark();
         
     private:
-        JSValuePtr m_internalValue;
+        JSValue m_internalValue;
     };
     
     inline JSWrapperObject::JSWrapperObject(PassRefPtr<Structure> structure)
         : JSObject(structure)
-        , m_internalValue(noValue())
     {
     }
     
-    inline void JSWrapperObject::setInternalValue(JSValuePtr value)
+    inline void JSWrapperObject::setInternalValue(JSValue value)
     {
         ASSERT(value);
         ASSERT(!value.isObject());
diff --git a/runtime/LiteralParser.cpp b/runtime/LiteralParser.cpp
new file mode 100644 (file)
index 0000000..798013a
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "LiteralParser.h"
+
+#include "JSArray.h"
+#include "JSString.h"
+#include "Lexer.h"
+#include <wtf/ASCIICType.h>
+#include <wtf/dtoa.h>
+
+namespace JSC {
+
+LiteralParser::TokenType LiteralParser::Lexer::lex(LiteralParserToken& token)
+{
+    while (m_ptr < m_end && isASCIISpace(*m_ptr))
+        ++m_ptr;
+
+    ASSERT(m_ptr <= m_end);
+    if (m_ptr >= m_end) {
+        token.type = TokEnd;
+        token.start = token.end = m_ptr;
+        return TokEnd;
+    }
+    token.type = TokError;
+    token.start = m_ptr;
+    switch (*m_ptr) {
+        case '[':
+            token.type = TokLBracket;
+            token.end = ++m_ptr;
+            return TokLBracket;
+        case ']':
+            token.type = TokRBracket;
+            token.end = ++m_ptr;
+            return TokRBracket;
+        case '(':
+            token.type = TokLParen;
+            token.end = ++m_ptr;
+            return TokLBracket;
+        case ')':
+            token.type = TokRParen;
+            token.end = ++m_ptr;
+            return TokRBracket;
+        case '{':
+            token.type = TokLBrace;
+            token.end = ++m_ptr;
+            return TokLBrace;
+        case '}':
+            token.type = TokRBrace;
+            token.end = ++m_ptr;
+            return TokRBrace;
+        case ',':
+            token.type = TokComma;
+            token.end = ++m_ptr;
+            return TokComma;
+        case ':':
+            token.type = TokColon;
+            token.end = ++m_ptr;
+            return TokColon;
+        case '"':
+            if (m_mode == StrictJSON)
+                return lexString<StrictJSON>(token);
+            return lexString<NonStrictJSON>(token);
+        case 't':
+            if (m_end - m_ptr >= 4 && m_ptr[1] == 'r' && m_ptr[2] == 'u' && m_ptr[3] == 'e') {
+                m_ptr += 4;
+                token.type = TokTrue;
+                token.end = m_ptr;
+                return TokTrue;
+            }
+            break;
+        case 'f':
+            if (m_end - m_ptr >= 5 && m_ptr[1] == 'a' && m_ptr[2] == 'l' && m_ptr[3] == 's' && m_ptr[4] == 'e') {
+                m_ptr += 5;
+                token.type = TokFalse;
+                token.end = m_ptr;
+                return TokFalse;
+            }
+            break;
+        case 'n':
+            if (m_end - m_ptr >= 4 && m_ptr[1] == 'u' && m_ptr[2] == 'l' && m_ptr[3] == 'l') {
+                m_ptr += 4;
+                token.type = TokNull;
+                token.end = m_ptr;
+                return TokNull;
+            }
+            break;    
+        case '-':
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+            return lexNumber(token);
+    }
+    return TokError;
+}
+
+template <LiteralParser::ParserMode mode> static inline bool isSafeStringCharacter(UChar c)
+{
+    return (c >= ' ' && (mode == LiteralParser::StrictJSON || c <= 0xff) && c != '\\' && c != '"') || c == '\t';
+}
+
+template <LiteralParser::ParserMode mode> LiteralParser::TokenType LiteralParser::Lexer::lexString(LiteralParserToken& token)
+{
+    ++m_ptr;
+    const UChar* runStart;
+    token.stringToken = UString();
+    do {
+        runStart = m_ptr;
+        while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr))
+            ++m_ptr;
+        if (runStart < m_ptr)
+            token.stringToken.append(runStart, m_ptr - runStart);
+        if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') {
+            ++m_ptr;
+            if (m_ptr >= m_end)
+                return TokError;
+            switch (*m_ptr) {
+                case '"':
+                    token.stringToken.append('"');
+                    m_ptr++;
+                    break;
+                case '\\':
+                    token.stringToken.append('\\');
+                    m_ptr++;
+                    break;
+                case '/':
+                    token.stringToken.append('/');
+                    m_ptr++;
+                    break;
+                case 'b':
+                    token.stringToken.append('\b');
+                    m_ptr++;
+                    break;
+                case 'f':
+                    token.stringToken.append('\f');
+                    m_ptr++;
+                    break;
+                case 'n':
+                    token.stringToken.append('\n');
+                    m_ptr++;
+                    break;
+                case 'r':
+                    token.stringToken.append('\r');
+                    m_ptr++;
+                    break;
+                case 't':
+                    token.stringToken.append('\t');
+                    m_ptr++;
+                    break;
+
+                case 'u':
+                    if ((m_end - m_ptr) < 5) // uNNNN == 5 characters
+                        return TokError;
+                    for (int i = 1; i < 5; i++) {
+                        if (!isASCIIHexDigit(m_ptr[i]))
+                            return TokError;
+                    }
+                    token.stringToken.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4]));
+                    m_ptr += 5;
+                    break;
+
+                default:
+                    return TokError;
+            }
+        }
+    } while ((mode == StrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != '"');
+
+    if (m_ptr >= m_end || *m_ptr != '"')
+        return TokError;
+
+    token.type = TokString;
+    token.end = ++m_ptr;
+    return TokString;
+}
+
+LiteralParser::TokenType LiteralParser::Lexer::lexNumber(LiteralParserToken& token)
+{
+    // ES5 and json.org define numbers as
+    // number
+    //     int
+    //     int frac? exp?
+    //
+    // int
+    //     -? 0
+    //     -? digit1-9 digits?
+    //
+    // digits
+    //     digit digits?
+    //
+    // -?(0 | [1-9][0-9]*) ('.' [0-9]+)? ([eE][+-]? [0-9]+)?
+
+    if (m_ptr < m_end && *m_ptr == '-') // -?
+        ++m_ptr;
+    
+    // (0 | [1-9][0-9]*)
+    if (m_ptr < m_end && *m_ptr == '0') // 0
+        ++m_ptr;
+    else if (m_ptr < m_end && *m_ptr >= '1' && *m_ptr <= '9') { // [1-9]
+        ++m_ptr;
+        // [0-9]*
+        while (m_ptr < m_end && isASCIIDigit(*m_ptr))
+            ++m_ptr;
+    } else
+        return TokError;
+
+    // ('.' [0-9]+)?
+    if (m_ptr < m_end && *m_ptr == '.') {
+        ++m_ptr;
+        // [0-9]+
+        if (m_ptr >= m_end || !isASCIIDigit(*m_ptr))
+            return TokError;
+
+        ++m_ptr;
+        while (m_ptr < m_end && isASCIIDigit(*m_ptr))
+            ++m_ptr;
+    }
+
+    //  ([eE][+-]? [0-9]+)?
+    if (m_ptr < m_end && (*m_ptr == 'e' || *m_ptr == 'E')) { // [eE]
+        ++m_ptr;
+
+        // [-+]?
+        if (m_ptr < m_end && (*m_ptr == '-' || *m_ptr == '+'))
+            ++m_ptr;
+
+        // [0-9]+
+        if (m_ptr >= m_end || !isASCIIDigit(*m_ptr))
+            return TokError;
+        
+        ++m_ptr;
+        while (m_ptr < m_end && isASCIIDigit(*m_ptr))
+            ++m_ptr;
+    }
+    
+    token.type = TokNumber;
+    token.end = m_ptr;
+    Vector<char, 64> buffer(token.end - token.start + 1);
+    int i;
+    for (i = 0; i < token.end - token.start; i++) {
+        ASSERT(static_cast<char>(token.start[i]) == token.start[i]);
+        buffer[i] = static_cast<char>(token.start[i]);
+    }
+    buffer[i] = 0;
+    char* end;
+    token.numberToken = WTF::strtod(buffer.data(), &end);
+    ASSERT(buffer.data() + (token.end - token.start) == end);
+    return TokNumber;
+}
+
+JSValue LiteralParser::parse(ParserState initialState)
+{
+    ParserState state = initialState;
+    MarkedArgumentBuffer objectStack;
+    JSValue lastValue;
+    Vector<ParserState, 16> stateStack;
+    Vector<Identifier, 16> identifierStack;
+    while (1) {
+        switch(state) {
+            startParseArray:
+            case StartParseArray: {
+                JSArray* array = constructEmptyArray(m_exec);
+                objectStack.append(array);
+                // fallthrough
+            }
+            doParseArrayStartExpression:
+            case DoParseArrayStartExpression: {
+                if (m_lexer.next() == TokRBracket) {
+                    m_lexer.next();
+                    lastValue = objectStack.last();
+                    objectStack.removeLast();
+                    break;
+                }
+
+                stateStack.append(DoParseArrayEndExpression);
+                goto startParseExpression;
+            }
+            case DoParseArrayEndExpression: {
+                 asArray(objectStack.last())->push(m_exec, lastValue);
+                
+                if (m_lexer.currentToken().type == TokComma)
+                    goto doParseArrayStartExpression;
+
+                if (m_lexer.currentToken().type != TokRBracket)
+                    return JSValue();
+                
+                m_lexer.next();
+                lastValue = objectStack.last();
+                objectStack.removeLast();
+                break;
+            }
+            startParseObject:
+            case StartParseObject: {
+                JSObject* object = constructEmptyObject(m_exec);
+                objectStack.append(object);
+
+                TokenType type = m_lexer.next();
+                if (type == TokString) {
+                    Lexer::LiteralParserToken identifierToken = m_lexer.currentToken();
+
+                    // Check for colon
+                    if (m_lexer.next() != TokColon)
+                        return JSValue();
+                    
+                    m_lexer.next();
+                    identifierStack.append(Identifier(m_exec, identifierToken.stringToken));
+                    stateStack.append(DoParseObjectEndExpression);
+                    goto startParseExpression;
+                } else if (type != TokRBrace) 
+                    return JSValue();
+                m_lexer.next();
+                lastValue = objectStack.last();
+                objectStack.removeLast();
+                break;
+            }
+            doParseObjectStartExpression:
+            case DoParseObjectStartExpression: {
+                TokenType type = m_lexer.next();
+                if (type != TokString)
+                    return JSValue();
+                Lexer::LiteralParserToken identifierToken = m_lexer.currentToken();
+
+                // Check for colon
+                if (m_lexer.next() != TokColon)
+                    return JSValue();
+
+                m_lexer.next();
+                identifierStack.append(Identifier(m_exec, identifierToken.stringToken));
+                stateStack.append(DoParseObjectEndExpression);
+                goto startParseExpression;
+            }
+            case DoParseObjectEndExpression:
+            {
+                asObject(objectStack.last())->putDirect(identifierStack.last(), lastValue);
+                identifierStack.removeLast();
+                if (m_lexer.currentToken().type == TokComma)
+                    goto doParseObjectStartExpression;
+                if (m_lexer.currentToken().type != TokRBrace)
+                    return JSValue();
+                m_lexer.next();
+                lastValue = objectStack.last();
+                objectStack.removeLast();
+                break;
+            }
+            startParseExpression:
+            case StartParseExpression: {
+                switch (m_lexer.currentToken().type) {
+                    case TokLBracket:
+                        goto startParseArray;
+                    case TokLBrace:
+                        goto startParseObject;
+                    case TokString: {
+                        Lexer::LiteralParserToken stringToken = m_lexer.currentToken();
+                        m_lexer.next();
+                        lastValue = jsString(m_exec, stringToken.stringToken);
+                        break;
+                    }
+                    case TokNumber: {
+                        Lexer::LiteralParserToken numberToken = m_lexer.currentToken();
+                        m_lexer.next();
+                        lastValue = jsNumber(m_exec, numberToken.numberToken);
+                        break;
+                    }
+                    case TokNull:
+                        m_lexer.next();
+                        lastValue = jsNull();
+                        break;
+
+                    case TokTrue:
+                        m_lexer.next();
+                        lastValue = jsBoolean(true);
+                        break;
+
+                    case TokFalse:
+                        m_lexer.next();
+                        lastValue = jsBoolean(false);
+                        break;
+
+                    default:
+                        // Error
+                        return JSValue();
+                }
+                break;
+            }
+            case StartParseStatement: {
+                switch (m_lexer.currentToken().type) {
+                    case TokLBracket:
+                    case TokNumber:
+                    case TokString:
+                        goto startParseExpression;
+
+                    case TokLParen: {
+                        m_lexer.next();
+                        stateStack.append(StartParseStatementEndStatement);
+                        goto startParseExpression;
+                    }
+                    default:
+                        return JSValue();
+                }
+            }
+            case StartParseStatementEndStatement: {
+                ASSERT(stateStack.isEmpty());
+                if (m_lexer.currentToken().type != TokRParen)
+                    return JSValue();
+                if (m_lexer.next() == TokEnd)
+                    return lastValue;
+                return JSValue();
+            }
+            default:
+                ASSERT_NOT_REACHED();
+        }
+        if (stateStack.isEmpty())
+            return lastValue;
+        state = stateStack.last();
+        stateStack.removeLast();
+        continue;
+    }
+}
+
+}
diff --git a/runtime/LiteralParser.h b/runtime/LiteralParser.h
new file mode 100644 (file)
index 0000000..bceee7c
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef LiteralParser_h
+#define LiteralParser_h
+
+#include "JSGlobalObjectFunctions.h"
+#include "JSValue.h"
+#include "UString.h"
+
+namespace JSC {
+
+    class LiteralParser {
+    public:
+        typedef enum { StrictJSON, NonStrictJSON } ParserMode;
+        LiteralParser(ExecState* exec, const UString& s, ParserMode mode)
+            : m_exec(exec)
+            , m_lexer(s, mode)
+            , m_mode(mode)
+        {
+        }
+        
+        JSValue tryLiteralParse()
+        {
+            m_lexer.next();
+            JSValue result = parse(m_mode == StrictJSON ? StartParseExpression : StartParseStatement);
+            if (m_lexer.currentToken().type != TokEnd)
+                return JSValue();
+            return result;
+        }
+    private:
+        enum ParserState { StartParseObject, StartParseArray, StartParseExpression, 
+                           StartParseStatement, StartParseStatementEndStatement, 
+                           DoParseObjectStartExpression, DoParseObjectEndExpression,
+                           DoParseArrayStartExpression, DoParseArrayEndExpression };
+        enum TokenType { TokLBracket, TokRBracket, TokLBrace, TokRBrace, 
+                         TokString, TokIdentifier, TokNumber, TokColon, 
+                         TokLParen, TokRParen, TokComma, TokTrue, TokFalse,
+                         TokNull, TokEnd, TokError };
+
+        class Lexer {
+        public:
+            struct LiteralParserToken {
+                TokenType type;
+                const UChar* start;
+                const UChar* end;
+                UString stringToken;
+                double numberToken;
+            };
+            Lexer(const UString& s, ParserMode mode)
+                : m_string(s)
+                , m_mode(mode)
+                , m_ptr(s.data())
+                , m_end(s.data() + s.size())
+            {
+            }
+            
+            TokenType next()
+            {
+                return lex(m_currentToken);
+            }
+            
+            const LiteralParserToken& currentToken()
+            {
+                return m_currentToken;
+            }
+            
+        private:
+            TokenType lex(LiteralParserToken&);
+            template <ParserMode parserMode> TokenType lexString(LiteralParserToken&);
+            TokenType lexNumber(LiteralParserToken&);
+            LiteralParserToken m_currentToken;
+            UString m_string;
+            ParserMode m_mode;
+            const UChar* m_ptr;
+            const UChar* m_end;
+        };
+        
+        class StackGuard;
+        JSValue parse(ParserState);
+
+        ExecState* m_exec;
+        LiteralParser::Lexer m_lexer;
+        ParserMode m_mode;
+    };
+}
+
+#endif
index 98133a8a044a7a355f86298e3735a7600450f6ad..8359ff7f6602aa7acc4ddfb5f4117a24038f065e 100644 (file)
 #include "config.h"
 #include "Lookup.h"
 
+#include "JSFunction.h"
 #include "PrototypeFunction.h"
 
 namespace JSC {
 
 void HashTable::createTable(JSGlobalData* globalData) const
 {
-#if ENABLE(PERFECT_HASH_SIZE)
-    ASSERT(!table);
-    HashEntry* entries = new HashEntry[hashSizeMask + 1];
-    for (int i = 0; i <= hashSizeMask; ++i)
-        entries[i].setKey(0);
-    for (int i = 0; values[i].key; ++i) {
-        UString::Rep* identifier = Identifier::add(globalData, values[i].key).releaseRef();
-        int hashIndex = identifier->computedHash() & hashSizeMask;
-        ASSERT(!entries[hashIndex].key());
-        entries[hashIndex].initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
-    }
-    table = entries;
-#else
     ASSERT(!table);
     int linkIndex = compactHashSizeMask + 1;
     HashEntry* entries = new HashEntry[compactSize];
@@ -61,17 +49,12 @@ void HashTable::createTable(JSGlobalData* globalData) const
         entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
     }
     table = entries;
-#endif
 }
 
 void HashTable::deleteTable() const
 {
     if (table) {
-#if ENABLE(PERFECT_HASH_SIZE)
-        int max = hashSizeMask + 1;
-#else
         int max = compactSize;
-#endif
         for (int i = 0; i != max; ++i) {
             if (UString::Rep* key = table[i].key())
                 key->deref();
@@ -84,11 +67,12 @@ void HashTable::deleteTable() const
 void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject* thisObj, const Identifier& propertyName, PropertySlot& slot)
 {
     ASSERT(entry->attributes() & Function);
-    JSValuePtr* location = thisObj->getDirectLocation(propertyName);
+    JSValue* location = thisObj->getDirectLocation(propertyName);
 
     if (!location) {
-        PrototypeFunction* function = new (exec) PrototypeFunction(exec, entry->functionLength(), propertyName, entry->function());
-        thisObj->putDirect(propertyName, function, entry->attributes());
+        InternalFunction* function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function());
+
+        thisObj->putDirectFunction(propertyName, function, entry->attributes());
         location = thisObj->getDirectLocation(propertyName);
     }
 
index 55c3221b0f498f9d9f187f105895cb0a86a51d2c..167f2bc03018005828c5a555eb8ef0c6b2560e67 100644 (file)
 
 #include "CallFrame.h"
 #include "Identifier.h"
-#include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSObject.h"
 #include "PropertySlot.h"
 #include <stdio.h>
 #include <wtf/Assertions.h>
 
-// Set ENABLE_PERFECT_HASH_SIZE to 0 to save memory at the
-// cost of speed.  Test your platform as results may vary.
-#define ENABLE_PERFECT_HASH_SIZE 1
+// Bug #26843: Work around Metrowerks compiler bug
+#if COMPILER(WINSCW)
+#define JSC_CONST_HASHTABLE
+#else
+#define JSC_CONST_HASHTABLE const
+#endif
 
 namespace JSC {
 
@@ -45,9 +47,9 @@ namespace JSC {
     };
 
     // FIXME: There is no reason this get function can't be simpler.
-    // ie. typedef JSValuePtr (*GetFunction)(ExecState*, JSObject* baseObject)
+    // ie. typedef JSValue (*GetFunction)(ExecState*, JSObject* baseObject)
     typedef PropertySlot::GetValueFunc GetFunction;
-    typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValuePtr value);
+    typedef void (*PutFunction)(ExecState*, JSObject* baseObject, JSValue value);
 
     class HashEntry {
     public:
@@ -57,9 +59,7 @@ namespace JSC {
             m_attributes = attributes;
             m_u.store.value1 = v1;
             m_u.store.value2 = v2;
-#if !ENABLE(PERFECT_HASH_SIZE)
             m_next = 0;
-#endif
         }
 
         void setKey(UString::Rep* key) { m_key = key; }
@@ -75,10 +75,8 @@ namespace JSC {
 
         intptr_t lexerValue() const { ASSERT(!m_attributes); return m_u.lexer.value; }
 
-#if !ENABLE(PERFECT_HASH_SIZE)
         void setNext(HashEntry *next) { m_next = next; }
         HashEntry* next() const { return m_next; }
-#endif
 
     private:
         UString::Rep* m_key;
@@ -103,18 +101,14 @@ namespace JSC {
             } lexer;
         } m_u;
 
-#if !ENABLE(PERFECT_HASH_SIZE)
         HashEntry* m_next;
-#endif
     };
 
     struct HashTable {
-#if ENABLE(PERFECT_HASH_SIZE)
-        int hashSizeMask; // Precomputed size for the hash table (minus 1).
-#else
+
         int compactSize;
         int compactHashSizeMask;
-#endif
+
         const HashTableValue* values; // Fixed values generated by script.
         mutable const HashEntry* table; // Table allocated at runtime.
 
@@ -148,13 +142,6 @@ namespace JSC {
     private:
         ALWAYS_INLINE const HashEntry* entry(const Identifier& identifier) const
         {
-#if ENABLE(PERFECT_HASH_SIZE)
-            ASSERT(table);
-            const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & hashSizeMask];
-            if (entry->key() != identifier.ustring().rep())
-                return 0;
-            return entry;
-#else
             ASSERT(table);
 
             const HashEntry* entry = &table[identifier.ustring().rep()->computedHash() & compactHashSizeMask];
@@ -169,7 +156,6 @@ namespace JSC {
             } while (entry);
 
             return 0;
-#endif
         }
 
         // Convert the hash table keys to identifiers.
@@ -243,16 +229,19 @@ namespace JSC {
      * is found it sets the value and returns true, else it returns false.
      */
     template <class ThisImp>
-    inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, const HashTable* table, ThisImp* thisObj)
+    inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValue value, const HashTable* table, ThisImp* thisObj)
     {
         const HashEntry* entry = table->entry(exec, propertyName);
 
         if (!entry)
             return false;
 
-        if (entry->attributes() & Function) // function: put as override property
-            thisObj->putDirect(propertyName, value);
-        else if (!(entry->attributes() & ReadOnly))
+        if (entry->attributes() & Function) { // function: put as override property
+            if (LIKELY(value.isCell()))
+                thisObj->putDirectFunction(propertyName, value.asCell());
+            else
+                thisObj->putDirect(propertyName, value);
+        } else if (!(entry->attributes() & ReadOnly))
             entry->propertyPutter()(exec, thisObj, value);
 
         return true;
@@ -265,7 +254,7 @@ namespace JSC {
      * then it calls put() on the ParentImp class.
      */
     template <class ThisImp, class ParentImp>
-    inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValuePtr value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)
+    inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)
     {
         if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj))
             thisObj->ParentImp::put(exec, propertyName, value, slot); // not found: forward to parent
index f9b76530ce63a7a388f60d1e53114cb3b91bc69a..2572bc9ac079aab44841e194ad8aac9e49b25b56 100644 (file)
@@ -33,24 +33,24 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(MathObject);
 
-static JSValuePtr mathProtoFuncAbs(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncACos(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncASin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncATan(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncATan2(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncCeil(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncCos(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncExp(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncFloor(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncLog(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncMax(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncMin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncPow(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncRandom(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncRound(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncSin(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncSqrt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr mathProtoFuncTan(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncACos(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncASin(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncATan(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncCos(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncExp(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncLog(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncMax(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncMin(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL mathProtoFuncTan(ExecState*, JSObject*, JSValue, const ArgList&);
 
 }
 
@@ -115,62 +115,62 @@ bool MathObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
 
 // ------------------------------ Functions --------------------------------
 
-JSValuePtr mathProtoFuncAbs(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncAbs(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, fabs(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, fabs(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncACos(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncACos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, acos(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, acos(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncASin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncASin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, asin(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, asin(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncATan(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncATan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, atan(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, atan(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncATan2(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncATan2(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, atan2(args.at(exec, 0).toNumber(exec), args.at(exec, 1).toNumber(exec)));
+    return jsNumber(exec, atan2(args.at(0).toNumber(exec), args.at(1).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncCeil(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncCeil(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, ceil(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, ceil(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncCos(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncCos(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, cos(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, cos(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncExp(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncExp(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, exp(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, exp(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncFloor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncFloor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, floor(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, floor(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncLog(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncLog(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, log(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, log(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncMax(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncMax(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     unsigned argsCount = args.size();
     double result = -Inf;
     for (unsigned k = 0; k < argsCount; ++k) {
-        double val = args.at(exec, k).toNumber(exec);
+        double val = args.at(k).toNumber(exec);
         if (isnan(val)) {
             result = NaN;
             break;
@@ -181,12 +181,12 @@ JSValuePtr mathProtoFuncMax(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
     return jsNumber(exec, result);
 }
 
-JSValuePtr mathProtoFuncMin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncMin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     unsigned argsCount = args.size();
     double result = +Inf;
     for (unsigned k = 0; k < argsCount; ++k) {
-        double val = args.at(exec, k).toNumber(exec);
+        double val = args.at(k).toNumber(exec);
         if (isnan(val)) {
             result = NaN;
             break;
@@ -197,12 +197,12 @@ JSValuePtr mathProtoFuncMin(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
     return jsNumber(exec, result);
 }
 
-JSValuePtr mathProtoFuncPow(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     // ECMA 15.8.2.1.13
 
-    double arg = args.at(exec, 0).toNumber(exec);
-    double arg2 = args.at(exec, 1).toNumber(exec);
+    double arg = args.at(0).toNumber(exec);
+    double arg2 = args.at(1).toNumber(exec);
 
     if (isnan(arg2))
         return jsNaN(exec);
@@ -211,32 +211,32 @@ JSValuePtr mathProtoFuncPow(ExecState* exec, JSObject*, JSValuePtr, const ArgLis
     return jsNumber(exec, pow(arg, arg2));
 }
 
-JSValuePtr mathProtoFuncRandom(ExecState* exec, JSObject*, JSValuePtr, const ArgList&)
+JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, const ArgList&)
 {
     return jsNumber(exec, WTF::weakRandomNumber());
 }
 
-JSValuePtr mathProtoFuncRound(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    double arg = args.at(exec, 0).toNumber(exec);
+    double arg = args.at(0).toNumber(exec);
     if (signbit(arg) && arg >= -0.5)
          return jsNumber(exec, -0.0);
     return jsNumber(exec, floor(arg + 0.5));
 }
 
-JSValuePtr mathProtoFuncSin(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, sin(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, sin(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, sqrt(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, sqrt(args.at(0).toNumber(exec)));
 }
 
-JSValuePtr mathProtoFuncTan(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+JSValue JSC_HOST_CALL mathProtoFuncTan(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, tan(args.at(exec, 0).toNumber(exec)));
+    return jsNumber(exec, tan(args.at(0).toNumber(exec)));
 }
 
 } // namespace JSC
index d6163fdb3a5ee7e2c2a24f9faf55835b478893cb..3557d1ecaa7c04ce5c58dd9fb45aef8373524c6a 100644 (file)
@@ -34,7 +34,7 @@ namespace JSC {
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
             return Structure::create(prototype, TypeInfo(ObjectType));
         }
index eee989074397fa764a69513dbfd042d355859bc9..0205fc55d4cc796f708a629e50f4e125ef4a2116 100644 (file)
@@ -43,8 +43,8 @@ NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, PassRefPtr<Struc
 ErrorInstance* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
 {
     ErrorInstance* object = new (exec) ErrorInstance(m_errorStructure);
-    if (!args.at(exec, 0).isUndefined())
-        object->putDirect(exec->propertyNames().message, jsString(exec, args.at(exec, 0).toString(exec)));
+    if (!args.at(0).isUndefined())
+        object->putDirect(exec->propertyNames().message, jsString(exec, args.at(0).toString(exec)));
     return object;
 }
 
@@ -58,8 +58,8 @@ ConstructType NativeErrorConstructor::getConstructData(ConstructData& constructD
     constructData.native.function = constructWithNativeErrorConstructor;
     return ConstructTypeHost;
 }
-
-static JSValuePtr callNativeErrorConstructor(ExecState* exec, JSObject* constructor, JSValuePtr, const ArgList& args)
+    
+static JSValue JSC_HOST_CALL callNativeErrorConstructor(ExecState* exec, JSObject* constructor, JSValue, const ArgList& args)
 {
     return static_cast<NativeErrorConstructor*>(constructor)->construct(exec, args);
 }
diff --git a/runtime/NativeFunctionWrapper.h b/runtime/NativeFunctionWrapper.h
new file mode 100644 (file)
index 0000000..d4eeb3b
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef NativeFunctionWrapper_h
+#define NativeFunctionWrapper_h
+
+namespace JSC {
+#if ENABLE(JIT) && ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
+    class JSFunction;
+    typedef JSFunction NativeFunctionWrapper;
+#else
+    class PrototypeFunction;
+    typedef PrototypeFunction NativeFunctionWrapper;
+#endif
+}
+
+#endif
index caa4a704b371b6e402169ef75479535ceebdef08..2840bf0b2cf2ac754859b105fa3b3982378987c5 100644 (file)
@@ -29,11 +29,11 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(NumberConstructor);
 
-static JSValuePtr numberConstructorNaNValue(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr numberConstructorNegInfinity(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr numberConstructorPosInfinity(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr numberConstructorMaxValue(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr numberConstructorMinValue(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue numberConstructorNaNValue(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue numberConstructorNegInfinity(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue numberConstructorPosInfinity(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue numberConstructorMaxValue(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue numberConstructorMinValue(ExecState*, const Identifier&, const PropertySlot&);
 
 } // namespace JSC
 
@@ -68,27 +68,27 @@ bool NumberConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr
     return getStaticValueSlot<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, slot);
 }
 
-JSValuePtr numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
 {
     return jsNaN(exec);
 }
 
-JSValuePtr numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
 {
     return jsNumber(exec, -Inf);
 }
 
-JSValuePtr numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
 {
     return jsNumber(exec, Inf);
 }
 
-JSValuePtr numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
 {
     return jsNumber(exec, 1.7976931348623157E+308);
 }
 
-JSValuePtr numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
 {
     return jsNumber(exec, 5E-324);
 }
@@ -97,7 +97,7 @@ JSValuePtr numberConstructorMinValue(ExecState* exec, const Identifier&, const P
 static JSObject* constructWithNumberConstructor(ExecState* exec, JSObject*, const ArgList& args)
 {
     NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
-    double n = args.isEmpty() ? 0 : args.at(exec, 0).toNumber(exec);
+    double n = args.isEmpty() ? 0 : args.at(0).toNumber(exec);
     object->setInternalValue(jsNumber(exec, n));
     return object;
 }
@@ -109,9 +109,9 @@ ConstructType NumberConstructor::getConstructData(ConstructData& constructData)
 }
 
 // ECMA 15.7.2
-static JSValuePtr callNumberConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callNumberConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsNumber(exec, args.isEmpty() ? 0 : args.at(exec, 0).toNumber(exec));
+    return jsNumber(exec, args.isEmpty() ? 0 : args.at(0).toNumber(exec));
 }
 
 CallType NumberConstructor::getCallData(CallData& callData)
index 070be5f25ebd40a42c63f6941c7a5615ff989b91..b1224ec552d073908cc559efc13dc4dd9ac3ca7a 100644 (file)
@@ -32,11 +32,11 @@ namespace JSC {
         NumberConstructor(ExecState*, PassRefPtr<Structure>, NumberPrototype*);
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-        JSValuePtr getValueProperty(ExecState*, int token) const;
+        JSValue getValueProperty(ExecState*, int token) const;
 
         static const ClassInfo info;
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr proto) 
+        static PassRefPtr<Structure> createStructure(JSValue proto) 
         { 
             return Structure::create(proto, TypeInfo(ObjectType, ImplementsHasInstance)); 
         }
index dc10d8f11d7399f6f9d99287c21e02cbf4709e58..0e8df1730fff84c4ba5c1525526cabf112b8c853 100644 (file)
@@ -36,12 +36,12 @@ NumberObject::NumberObject(PassRefPtr<Structure> structure)
 {
 }
 
-JSValuePtr NumberObject::getJSNumber()
+JSValue NumberObject::getJSNumber()
 {
     return internalValue();
 }
 
-NumberObject* constructNumber(ExecState* exec, JSValuePtr number)
+NumberObject* constructNumber(ExecState* exec, JSValue number)
 {
     NumberObject* object = new (exec) NumberObject(exec->lexicalGlobalObject()->numberObjectStructure());
     object->setInternalValue(number);
index 285421df70f4953298ec653dcde271e167df64bb..d354b9b8a2a8609ed7283c9b7ff1016d23bbe1fc 100644 (file)
@@ -34,10 +34,10 @@ namespace JSC {
     private:
         virtual const ClassInfo* classInfo() const { return &info; }
 
-        virtual JSValuePtr getJSNumber();
+        virtual JSValue getJSNumber();
     };
 
-    NumberObject* constructNumber(ExecState*, JSValuePtr);
+    NumberObject* constructNumber(ExecState*, JSValue);
 
 } // namespace JSC
 
index 778891e2ecabbaf0c521579966d2c0847394b52b..d8be4e4aaaf346ddbcfb165443907b757b926d29 100644 (file)
@@ -23,6 +23,7 @@
 #include "NumberPrototype.h"
 
 #include "Error.h"
+#include "JSFunction.h"
 #include "JSString.h"
 #include "PrototypeFunction.h"
 #include "dtoa.h"
@@ -35,12 +36,12 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(NumberPrototype);
 
-static JSValuePtr numberProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncToFixed(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncToExponential(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr numberProtoFuncToPrecision(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState*, JSObject*, JSValue, const ArgList&);
 
 // ECMA 15.7.4
 
@@ -51,12 +52,12 @@ NumberPrototype::NumberPrototype(ExecState* exec, PassRefPtr<Structure> structur
 
     // The constructor will be added later, after NumberConstructor has been constructed
 
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().toString, numberProtoFuncToString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, numberProtoFuncToLocaleString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, numberProtoFuncValueOf), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().toFixed, numberProtoFuncToFixed), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().toExponential, numberProtoFuncToExponential), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().toPrecision, numberProtoFuncToPrecision), DontEnum);
 }
 
 // ------------------------------ Functions ---------------------------
@@ -67,7 +68,8 @@ static UString integerPartNoExp(double d)
 {
     int decimalPoint;
     int sign;
-    char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);
+    char result[80];
+    WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
     bool resultIsInfOrNan = (decimalPoint == 9999);
     size_t length = strlen(result);
 
@@ -79,19 +81,18 @@ static UString integerPartNoExp(double d)
     else {
         Vector<char, 1024> buf(decimalPoint + 1);
 
-        // FIXME: Remove use of strcpy() and strncpy()
+        // FIXME: Remove use of strncpy()
         if (static_cast<int>(length) <= decimalPoint) {
-            strcpy(buf.data(), result);
+            ASSERT(decimalPoint < 1024);
+            memcpy(buf.data(), result, length);
             memset(buf.data() + length, '0', decimalPoint - length);
         } else
             strncpy(buf.data(), result, decimalPoint);
-
         buf[decimalPoint] = '\0';
+
         str.append(buf.data());
     }
 
-    WTF::freedtoa(result);
-
     return str;
 }
 
@@ -134,14 +135,14 @@ static double intPow10(int e)
     return static_cast<double>(result);
 }
 
-JSValuePtr numberProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
-    JSValuePtr v = thisValue.getJSNumber();
+    JSValue v = thisValue.getJSNumber();
     if (!v)
         return throwError(exec, TypeError);
 
-    double radixAsDouble = args.at(exec, 0).toInteger(exec); // nan -> 0
-    if (radixAsDouble == 10 || args.at(exec, 0).isUndefined())
+    double radixAsDouble = args.at(0).toInteger(exec); // nan -> 0
+    if (radixAsDouble == 10 || args.at(0).isUndefined())
         return jsString(exec, v.toString(exec));
 
     if (radixAsDouble < 2 || radixAsDouble > 36)
@@ -198,33 +199,33 @@ JSValuePtr numberProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVa
     return jsString(exec, startOfResultString);
 }
 
-JSValuePtr numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL numberProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     // FIXME: Not implemented yet.
 
-    JSValuePtr v = thisValue.getJSNumber();
+    JSValue v = thisValue.getJSNumber();
     if (!v)
         return throwError(exec, TypeError);
 
     return jsString(exec, v.toString(exec));
 }
 
-JSValuePtr numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
-    JSValuePtr v = thisValue.getJSNumber();
+    JSValue v = thisValue.getJSNumber();
     if (!v)
         return throwError(exec, TypeError);
 
     return v;
 }
 
-JSValuePtr numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
-    JSValuePtr v = thisValue.getJSNumber();
+    JSValue v = thisValue.getJSNumber();
     if (!v)
         return throwError(exec, TypeError);
 
-    JSValuePtr fractionDigits = args.at(exec, 0);
+    JSValue fractionDigits = args.at(0);
     double df = fractionDigits.toInteger(exec);
     if (!(df >= 0 && df <= 20))
         return throwError(exec, RangeError, "toFixed() digits argument must be between 0 and 20");
@@ -278,8 +279,8 @@ static void fractionalPartToString(char* buf, int& i, const char* result, int re
             strncpy(buf + i, result + 1, fractionalDigits);
             i += fractionalDigits;
         } else {
-            // FIXME: Remove use of strcpy()
-            strcpy(buf + i, result + 1);
+            ASSERT(i + resultLength - 1 < 80);
+            memcpy(buf + i, result + 1, resultLength - 1);
             i += static_cast<int>(resultLength) - 1;
         }
     }
@@ -304,9 +305,9 @@ static void exponentialPartToString(char* buf, int& i, int decimalPoint)
     buf[i++] = static_cast<char>('0' + exponential % 10);
 }
 
-JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
-    JSValuePtr v = thisValue.getJSNumber();
+    JSValue v = thisValue.getJSNumber();
     if (!v)
         return throwError(exec, TypeError);
 
@@ -315,7 +316,7 @@ JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr t
     if (isnan(x) || isinf(x))
         return jsString(exec, UString::from(x));
 
-    JSValuePtr fractionalDigitsValue = args.at(exec, 0);
+    JSValue fractionalDigitsValue = args.at(0);
     double df = fractionalDigitsValue.toInteger(exec);
     if (!(df >= 0 && df <= 20))
         return throwError(exec, RangeError, "toExponential() argument must between 0 and 20");
@@ -346,7 +347,8 @@ JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr t
 
     int decimalPoint;
     int sign;
-    char* result = WTF::dtoa(x, 0, &decimalPoint, &sign, NULL);
+    char result[80];
+    WTF::dtoa(result, x, 0, &decimalPoint, &sign, NULL);
     size_t resultLength = strlen(result);
     decimalPoint += decimalAdjust;
 
@@ -355,10 +357,12 @@ JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr t
     if (sign)
         buf[i++] = '-';
 
-    if (decimalPoint == 999) // ? 9999 is the magical "result is Inf or NaN" value.  what's 999??
-        // FIXME: Remove magic number 80
-        strlcpy(buf + i, result, 80 - i);
-    else {
+    // ? 9999 is the magical "result is Inf or NaN" value.  what's 999??
+    if (decimalPoint == 999) {
+        ASSERT(i + resultLength < 80);
+        memcpy(buf + i, result, resultLength);
+        buf[i + resultLength] = '\0';
+    } else {
         buf[i++] = result[0];
 
         if (includeAllDigits)
@@ -370,20 +374,18 @@ JSValuePtr numberProtoFuncToExponential(ExecState* exec, JSObject*, JSValuePtr t
     }
     ASSERT(i <= 80);
 
-    WTF::freedtoa(result);
-
     return jsString(exec, buf);
 }
 
-JSValuePtr numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
-    JSValuePtr v = thisValue.getJSNumber();
+    JSValue v = thisValue.getJSNumber();
     if (!v)
         return throwError(exec, TypeError);
 
-    double doublePrecision = args.at(exec, 0).toIntegerPreserveNaN(exec);
+    double doublePrecision = args.at(0).toIntegerPreserveNaN(exec);
     double x = v.uncheckedGetNumber();
-    if (args.at(exec, 0).isUndefined() || isnan(x) || isinf(x))
+    if (args.at(0).isUndefined() || isnan(x) || isinf(x))
         return jsString(exec, v.toString(exec));
 
     UString s;
index 2d6112738cf078a3a96f7212826b4b368e3e9cce..cf1790f061c260790569d67851aca8c89712f3ac 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "ObjectConstructor.h"
 
+#include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "ObjectPrototype.h"
 
@@ -41,7 +42,7 @@ ObjectConstructor::ObjectConstructor(ExecState* exec, PassRefPtr<Structure> stru
 // ECMA 15.2.2
 static ALWAYS_INLINE JSObject* constructObject(ExecState* exec, const ArgList& args)
 {
-    JSValuePtr arg = args.at(exec, 0);
+    JSValue arg = args.at(0);
     if (arg.isUndefinedOrNull())
         return new (exec) JSObject(exec->lexicalGlobalObject()->emptyObjectStructure());
     return arg.toObject(exec);
@@ -58,7 +59,7 @@ ConstructType ObjectConstructor::getConstructData(ConstructData& constructData)
     return ConstructTypeHost;
 }
 
-static JSValuePtr callObjectConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     return constructObject(exec, args);
 }
index 4b776a7750e1b0d8ec6aac1440d0a06b4ed3f5f4..98e47131886b4b85cc9a949999177006679c8335 100644 (file)
@@ -22,6 +22,7 @@
 #include "ObjectPrototype.h"
 
 #include "Error.h"
+#include "JSFunction.h"
 #include "JSString.h"
 #include "PrototypeFunction.h"
 
@@ -29,55 +30,55 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(ObjectPrototype);
 
-static JSValuePtr objectProtoFuncValueOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValue, const ArgList&);
 
 ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<Structure> stucture, Structure* prototypeFunctionStructure)
     : JSObject(stucture)
 {
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
 
     // Mozilla extensions
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
 }
 
 // ------------------------------ Functions --------------------------------
 
 // ECMA 15.2.4.2, 15.2.4.4, 15.2.4.5, 15.2.4.7
 
-JSValuePtr objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL objectProtoFuncValueOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     return thisValue.toThisObject(exec);
 }
 
-JSValuePtr objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncHasOwnProperty(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
-    return jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args.at(exec, 0).toString(exec))));
+    return jsBoolean(thisValue.toThisObject(exec)->hasOwnProperty(exec, Identifier(exec, args.at(0).toString(exec))));
 }
 
-JSValuePtr objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSObject* thisObj = thisValue.toThisObject(exec);
 
-    if (!args.at(exec, 0).isObject())
+    if (!args.at(0).isObject())
         return jsBoolean(false);
 
-    JSValuePtr v = asObject(args.at(exec, 0))->prototype();
+    JSValue v = asObject(args.at(0))->prototype();
 
     while (true) {
         if (!v.isObject())
@@ -88,45 +89,45 @@ JSValuePtr objectProtoFuncIsPrototypeOf(ExecState* exec, JSObject*, JSValuePtr t
     }
 }
 
-JSValuePtr objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     CallData callData;
-    if (args.at(exec, 1).getCallData(callData) == CallTypeNone)
+    if (args.at(1).getCallData(callData) == CallTypeNone)
         return throwError(exec, SyntaxError, "invalid getter usage");
-    thisValue.toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)), asObject(args.at(exec, 1)));
+    thisValue.toThisObject(exec)->defineGetter(exec, Identifier(exec, args.at(0).toString(exec)), asObject(args.at(1)));
     return jsUndefined();
 }
 
-JSValuePtr objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     CallData callData;
-    if (args.at(exec, 1).getCallData(callData) == CallTypeNone)
+    if (args.at(1).getCallData(callData) == CallTypeNone)
         return throwError(exec, SyntaxError, "invalid setter usage");
-    thisValue.toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)), asObject(args.at(exec, 1)));
+    thisValue.toThisObject(exec)->defineSetter(exec, Identifier(exec, args.at(0).toString(exec)), asObject(args.at(1)));
     return jsUndefined();
 }
 
-JSValuePtr objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncLookupGetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
-    return thisValue.toThisObject(exec)->lookupGetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)));
+    return thisValue.toThisObject(exec)->lookupGetter(exec, Identifier(exec, args.at(0).toString(exec)));
 }
 
-JSValuePtr objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncLookupSetter(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
-    return thisValue.toThisObject(exec)->lookupSetter(exec, Identifier(exec, args.at(exec, 0).toString(exec)));
+    return thisValue.toThisObject(exec)->lookupSetter(exec, Identifier(exec, args.at(0).toString(exec)));
 }
 
-JSValuePtr objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL objectProtoFuncPropertyIsEnumerable(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
-    return jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args.at(exec, 0).toString(exec))));
+    return jsBoolean(thisValue.toThisObject(exec)->propertyIsEnumerable(exec, Identifier(exec, args.at(0).toString(exec))));
 }
 
-JSValuePtr objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     return thisValue.toThisJSString(exec);
 }
 
-JSValuePtr objectProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]");
 }
index 1c432fe27ba810bb3e9944d24c961e3256c28263..7790ae0909015fe9d898a48cbcb58050508e812f 100644 (file)
@@ -30,7 +30,7 @@ namespace JSC {
         ObjectPrototype(ExecState*, PassRefPtr<Structure>, Structure* prototypeFunctionStructure);
     };
 
-    JSValuePtr objectProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+    JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
 
 } // namespace JSC
 
index 550d3f6b4af010433fb73ecb741ca39023690df4..093bbecf389cae30a5c128007d44ec14b642900d 100644 (file)
 
 namespace JSC {
 
-bool JSValuePtr::equalSlowCase(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
+bool JSValue::equalSlowCase(ExecState* exec, JSValue v1, JSValue v2)
 {
     return equalSlowCaseInline(exec, v1, v2);
 }
 
-bool JSValuePtr::strictEqualSlowCase(JSValuePtr v1, JSValuePtr v2)
+bool JSValue::strictEqualSlowCase(JSValue v1, JSValue v2)
 {
     return strictEqualSlowCaseInline(v1, v2);
 }
 
-NEVER_INLINE JSValuePtr throwOutOfMemoryError(ExecState* exec)
+NEVER_INLINE JSValue throwOutOfMemoryError(ExecState* exec)
 {
     JSObject* error = Error::create(exec, GeneralError, "Out of memory");
     exec->setException(error);
     return error;
 }
 
+NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
+{
+    // exception for the Date exception in defaultValue()
+    JSValue p1 = v1.toPrimitive(callFrame);
+    JSValue p2 = v2.toPrimitive(callFrame);
+
+    if (p1.isString() || p2.isString()) {
+        RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
+        if (!value)
+            return throwOutOfMemoryError(callFrame);
+        return jsString(callFrame, value.release());
+    }
+
+    return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
+}
+
+JSValue jsTypeStringForValue(CallFrame* callFrame, JSValue v)
+{
+    if (v.isUndefined())
+        return jsNontrivialString(callFrame, "undefined");
+    if (v.isBoolean())
+        return jsNontrivialString(callFrame, "boolean");
+    if (v.isNumber())
+        return jsNontrivialString(callFrame, "number");
+    if (v.isString())
+        return jsNontrivialString(callFrame, "string");
+    if (v.isObject()) {
+        // Return "undefined" for objects that should be treated
+        // as null when doing comparisons.
+        if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
+            return jsNontrivialString(callFrame, "undefined");
+        CallData callData;
+        if (asObject(v)->getCallData(callData) != CallTypeNone)
+            return jsNontrivialString(callFrame, "function");
+    }
+    return jsNontrivialString(callFrame, "object");
+}
+
+bool jsIsObjectType(JSValue v)
+{
+    if (!v.isCell())
+        return v.isNull();
+
+    JSType type = asCell(v)->structure()->typeInfo().type();
+    if (type == NumberType || type == StringType)
+        return false;
+    if (type == ObjectType) {
+        if (asObject(v)->structure()->typeInfo().masqueradesAsUndefined())
+            return false;
+        CallData callData;
+        if (asObject(v)->getCallData(callData) != CallTypeNone)
+            return false;
+    }
+    return true;
+}
+
+bool jsIsFunctionType(JSValue v)
+{
+    if (v.isObject()) {
+        CallData callData;
+        if (asObject(v)->getCallData(callData) != CallTypeNone)
+            return true;
+    }
+    return false;
+}
+
 } // namespace JSC
index c6a7e7a303f6801f69ce9fa3590e5c12fcebf74c..f29154da830a27fa3c6b7425f87bcc8a065902f2 100644 (file)
 #ifndef Operations_h
 #define Operations_h
 
+#include "Interpreter.h"
 #include "JSImmediate.h"
 #include "JSNumberCell.h"
 #include "JSString.h"
 
 namespace JSC {
 
+    NEVER_INLINE JSValue throwOutOfMemoryError(ExecState*);
+    NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
+    JSValue jsTypeStringForValue(CallFrame*, JSValue);
+    bool jsIsObjectType(JSValue);
+    bool jsIsFunctionType(JSValue);
+
     // ECMA 11.9.3
-    inline bool JSValuePtr::equal(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
+    inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
     {
-        if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+        if (v1.isInt32() && v2.isInt32())
             return v1 == v2;
 
         return equalSlowCase(exec, v1, v2);
     }
 
-    ALWAYS_INLINE bool JSValuePtr::equalSlowCaseInline(ExecState* exec, JSValuePtr v1, JSValuePtr v2)
+    ALWAYS_INLINE bool JSValue::equalSlowCaseInline(ExecState* exec, JSValue v1, JSValue v2)
     {
-        ASSERT(!JSImmediate::areBothImmediateIntegerNumbers(v1, v2));
-
         do {
             if (v1.isNumber() && v2.isNumber())
                 return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
@@ -53,13 +58,13 @@ namespace JSC {
             if (v1.isUndefinedOrNull()) {
                 if (v2.isUndefinedOrNull())
                     return true;
-                if (JSImmediate::isImmediate(v2))
+                if (!v2.isCell())
                     return false;
                 return v2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
             }
 
             if (v2.isUndefinedOrNull()) {
-                if (JSImmediate::isImmediate(v1))
+                if (!v1.isCell())
                     return false;
                 return v1.asCell()->structure()->typeInfo().masqueradesAsUndefined();
             }
@@ -67,21 +72,21 @@ namespace JSC {
             if (v1.isObject()) {
                 if (v2.isObject())
                     return v1 == v2;
-                JSValuePtr p1 = v1.toPrimitive(exec);
+                JSValue p1 = v1.toPrimitive(exec);
                 if (exec->hadException())
                     return false;
                 v1 = p1;
-                if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+                if (v1.isInt32() && v2.isInt32())
                     return v1 == v2;
                 continue;
             }
 
             if (v2.isObject()) {
-                JSValuePtr p2 = v2.toPrimitive(exec);
+                JSValue p2 = v2.toPrimitive(exec);
                 if (exec->hadException())
                     return false;
                 v2 = p2;
-                if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+                if (v1.isInt32() && v2.isInt32())
                     return v1 == v2;
                 continue;
             }
@@ -105,31 +110,226 @@ namespace JSC {
     }
 
     // ECMA 11.9.3
-    inline bool JSValuePtr::strictEqual(JSValuePtr v1, JSValuePtr v2)
+    ALWAYS_INLINE bool JSValue::strictEqualSlowCaseInline(JSValue v1, JSValue v2)
+    {
+        ASSERT(v1.isCell() && v2.isCell());
+
+        if (v1.asCell()->isString() && v2.asCell()->isString())
+            return asString(v1)->value() == asString(v2)->value();
+
+        return v1 == v2;
+    }
+
+    inline bool JSValue::strictEqual(JSValue v1, JSValue v2)
     {
-        if (JSImmediate::areBothImmediateIntegerNumbers(v1, v2))
+        if (v1.isInt32() && v2.isInt32())
             return v1 == v2;
 
         if (v1.isNumber() && v2.isNumber())
             return v1.uncheckedGetNumber() == v2.uncheckedGetNumber();
 
-        if (JSImmediate::isEitherImmediate(v1, v2))
+        if (!v1.isCell() || !v2.isCell())
             return v1 == v2;
 
-        return strictEqualSlowCase(v1, v2);
+        return strictEqualSlowCaseInline(v1, v2);
     }
 
-    ALWAYS_INLINE bool JSValuePtr::strictEqualSlowCaseInline(JSValuePtr v1, JSValuePtr v2)
+    inline bool jsLess(CallFrame* callFrame, JSValue v1, JSValue v2)
     {
-        ASSERT(!JSImmediate::isEitherImmediate(v1, v2));
+        if (v1.isInt32() && v2.isInt32())
+            return v1.asInt32() < v2.asInt32();
 
-        if (v1.asCell()->isString() && v2.asCell()->isString())
-            return asString(v1)->value() == asString(v2)->value();
+        double n1;
+        double n2;
+        if (v1.getNumber(n1) && v2.getNumber(n2))
+            return n1 < n2;
 
-        return v1 == v2;
+        JSGlobalData* globalData = &callFrame->globalData();
+        if (isJSString(globalData, v1) && isJSString(globalData, v2))
+            return asString(v1)->value() < asString(v2)->value();
+
+        JSValue p1;
+        JSValue p2;
+        bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+        bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+
+        if (wasNotString1 | wasNotString2)
+            return n1 < n2;
+
+        return asString(p1)->value() < asString(p2)->value();
+    }
+
+    inline bool jsLessEq(CallFrame* callFrame, JSValue v1, JSValue v2)
+    {
+        if (v1.isInt32() && v2.isInt32())
+            return v1.asInt32() <= v2.asInt32();
+
+        double n1;
+        double n2;
+        if (v1.getNumber(n1) && v2.getNumber(n2))
+            return n1 <= n2;
+
+        JSGlobalData* globalData = &callFrame->globalData();
+        if (isJSString(globalData, v1) && isJSString(globalData, v2))
+            return !(asString(v2)->value() < asString(v1)->value());
+
+        JSValue p1;
+        JSValue p2;
+        bool wasNotString1 = v1.getPrimitiveNumber(callFrame, n1, p1);
+        bool wasNotString2 = v2.getPrimitiveNumber(callFrame, n2, p2);
+
+        if (wasNotString1 | wasNotString2)
+            return n1 <= n2;
+
+        return !(asString(p2)->value() < asString(p1)->value());
+    }
+
+    // Fast-path choices here are based on frequency data from SunSpider:
+    //    <times> Add case: <t1> <t2>
+    //    ---------------------------
+    //    5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
+    //    247412  Add case: 5 5
+    //    20900   Add case: 5 6
+    //    13962   Add case: 5 3
+    //    4000    Add case: 3 5
+
+    ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
+    {
+        double left;
+        double right = 0.0;
+
+        bool rightIsNumber = v2.getNumber(right);
+        if (rightIsNumber && v1.getNumber(left))
+            return jsNumber(callFrame, left + right);
+        
+        bool leftIsString = v1.isString();
+        if (leftIsString && v2.isString()) {
+            RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
+            if (!value)
+                return throwOutOfMemoryError(callFrame);
+            return jsString(callFrame, value.release());
+        }
+
+        if (rightIsNumber & leftIsString) {
+            RefPtr<UString::Rep> value = v2.isInt32() ?
+                concatenate(asString(v1)->value().rep(), v2.asInt32()) :
+                concatenate(asString(v1)->value().rep(), right);
+
+            if (!value)
+                return throwOutOfMemoryError(callFrame);
+            return jsString(callFrame, value.release());
+        }
+
+        // All other cases are pretty uncommon
+        return jsAddSlowCase(callFrame, v1, v2);
+    }
+
+    inline size_t normalizePrototypeChain(CallFrame* callFrame, JSValue base, JSValue slotBase, const Identifier& propertyName, size_t& slotOffset)
+    {
+        JSCell* cell = asCell(base);
+        size_t count = 0;
+
+        while (slotBase != cell) {
+            JSValue v = cell->structure()->prototypeForLookup(callFrame);
+
+            // If we didn't find slotBase in base's prototype chain, then base
+            // must be a proxy for another object.
+
+            if (v.isNull())
+                return 0;
+
+            cell = asCell(v);
+
+            // Since we're accessing a prototype in a loop, it's a good bet that it
+            // should not be treated as a dictionary.
+            if (cell->structure()->isDictionary()) {
+                asObject(cell)->flattenDictionaryObject();
+                if (slotBase == cell)
+                    slotOffset = cell->structure()->get(propertyName); 
+            }
+
+            ++count;
+        }
+        
+        ASSERT(count);
+        return count;
+    }
+
+    ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
+    {
+        ScopeChainIterator iter = scopeChain->begin();
+        ScopeChainIterator next = iter;
+        ++next;
+        ScopeChainIterator end = scopeChain->end();
+        ASSERT(iter != end);
+
+        PropertySlot slot;
+        JSObject* base;
+        while (true) {
+            base = *iter;
+            if (next == end || base->getPropertySlot(callFrame, property, slot))
+                return base;
+
+            iter = next;
+            ++next;
+        }
+
+        ASSERT_NOT_REACHED();
+        return JSValue();
+    }
+
+    ALWAYS_INLINE JSValue concatenateStrings(CallFrame* callFrame, Register* strings, unsigned count)
+    {
+        ASSERT(count >= 3);
+
+        // Estimate the amount of space required to hold the entire string.  If all
+        // arguments are strings, we can easily calculate the exact amount of space
+        // required.  For any other arguments, for now let's assume they may require
+        // 11 UChars of storage.  This is enouch to hold any int, and likely is also
+        // reasonable for the other immediates.  We may want to come back and tune
+        // this value at some point.
+        unsigned bufferSize = 0;
+        for (unsigned i = 0; i < count; ++i) {
+            JSValue v = strings[i].jsValue();
+            if (LIKELY(v.isString()))
+                bufferSize += asString(v)->value().size();
+            else
+                bufferSize += 11;
+        }
+
+        // Allocate an output string to store the result.
+        // If the first argument is a String, and if it has the capacity (or can grow
+        // its capacity) to hold the entire result then use this as a base to concatenate
+        // onto.  Otherwise, allocate a new empty output buffer.
+        JSValue firstValue = strings[0].jsValue();
+        RefPtr<UString::Rep> resultRep;
+        if (firstValue.isString() && (resultRep = asString(firstValue)->value().rep())->reserveCapacity(bufferSize)) {
+            // We're going to concatenate onto the first string - remove it from the list of items to be appended.
+            ++strings;
+            --count;
+        } else
+            resultRep = UString::Rep::createEmptyBuffer(bufferSize);
+        UString result(resultRep);
+
+        // Loop over the openards, writing them into the output buffer.
+        for (unsigned i = 0; i < count; ++i) {
+            JSValue v = strings[i].jsValue();
+            if (LIKELY(v.isString()))
+                result.append(asString(v)->value());
+            else if (v.isInt32())
+                result.appendNumeric(v.asInt32());
+            else {
+                double d;
+                if (v.getNumber(d))
+                    result.appendNumeric(d);
+                else
+                    result.append(v.toString(callFrame));
+            }
+        }
+
+        return jsString(callFrame, result);
     }
 
-    JSValuePtr throwOutOfMemoryError(ExecState*);
+} // namespace JSC
 
-}
-#endif
+#endif // Operations_h
index 935df6803191aaacb11e819928996593ecf24993..44dc2b84ffd40cb8866cc0ddb27527ede48457e1 100644 (file)
@@ -30,20 +30,23 @@ namespace JSC {
         UString::Rep* key;
         unsigned offset;
         unsigned attributes;
+        JSCell* specificValue;
         unsigned index;
 
-        PropertyMapEntry(UString::Rep* key, unsigned attributes)
+        PropertyMapEntry(UString::Rep* key, unsigned attributes, JSCell* specificValue)
             : key(key)
             , offset(0)
             , attributes(attributes)
+            , specificValue(specificValue)
             , index(0)
         {
         }
 
-        PropertyMapEntry(UString::Rep* key, unsigned offset, unsigned attributes, unsigned index)
+        PropertyMapEntry(UString::Rep* key, unsigned offset, unsigned attributes, JSCell* specificValue, unsigned index)
             : key(key)
             , offset(offset)
             , attributes(attributes)
+            , specificValue(specificValue)
             , index(index)
         {
         }
index 175f2711e38498b0c738a82de939168188e2e5e9..36fa5d83d6102e29c2a2f15bd4c454c92075da2c 100644 (file)
@@ -27,7 +27,7 @@
 
 namespace JSC {
 
-JSValuePtr PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     // Prevent getter functions from observing execution if an exception is pending.
     if (exec->hadException())
index 1dd1afafea8c2350bccf19b7c557defd342b0c7a..15d90342ae7d401939239ba19b08ac09aae79fd7 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "Identifier.h"
 #include "JSValue.h"
-#include "JSImmediate.h"
 #include "Register.h"
 #include <wtf/Assertions.h>
 #include <wtf/NotFound.h>
@@ -39,36 +38,36 @@ namespace JSC {
     class PropertySlot {
     public:
         PropertySlot()
-            : m_offset(WTF::notFound)
         {
             clearBase();
+            clearOffset();
             clearValue();
         }
 
-        explicit PropertySlot(const JSValuePtr base)
+        explicit PropertySlot(const JSValue base)
             : m_slotBase(base)
-            , m_offset(WTF::notFound)
         {
+            clearOffset();
             clearValue();
         }
 
-        typedef JSValuePtr (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
+        typedef JSValue (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
 
-        JSValuePtr getValue(ExecState* exec, const Identifier& propertyName) const
+        JSValue getValue(ExecState* exec, const Identifier& propertyName) const
         {
             if (m_getValue == JSC_VALUE_SLOT_MARKER)
                 return *m_data.valueSlot;
             if (m_getValue == JSC_REGISTER_SLOT_MARKER)
-                return (*m_data.registerSlot).jsValue(exec);
+                return (*m_data.registerSlot).jsValue();
             return m_getValue(exec, propertyName, *this);
         }
 
-        JSValuePtr getValue(ExecState* exec, unsigned propertyName) const
+        JSValue getValue(ExecState* exec, unsigned propertyName) const
         {
             if (m_getValue == JSC_VALUE_SLOT_MARKER)
                 return *m_data.valueSlot;
             if (m_getValue == JSC_REGISTER_SLOT_MARKER)
-                return (*m_data.registerSlot).jsValue(exec);
+                return (*m_data.registerSlot).jsValue();
             return m_getValue(exec, Identifier::from(exec, propertyName), *this);
         }
 
@@ -79,25 +78,16 @@ namespace JSC {
             return m_offset;
         }
 
-        void putValue(JSValuePtr value)
-        { 
-            if (m_getValue == JSC_VALUE_SLOT_MARKER) {
-                *m_data.valueSlot = value;
-                return;
-            }
-            ASSERT(m_getValue == JSC_REGISTER_SLOT_MARKER);
-            *m_data.registerSlot = JSValuePtr(value);
-        }
-
-        void setValueSlot(JSValuePtr* valueSlot) 
+        void setValueSlot(JSValue* valueSlot) 
         {
             ASSERT(valueSlot);
-            m_getValue = JSC_VALUE_SLOT_MARKER;
             clearBase();
+            clearOffset();
+            m_getValue = JSC_VALUE_SLOT_MARKER;
             m_data.valueSlot = valueSlot;
         }
         
-        void setValueSlot(JSValuePtr slotBase, JSValuePtr* valueSlot)
+        void setValueSlot(JSValue slotBase, JSValue* valueSlot)
         {
             ASSERT(valueSlot);
             m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -105,7 +95,7 @@ namespace JSC {
             m_data.valueSlot = valueSlot;
         }
         
-        void setValueSlot(JSValuePtr slotBase, JSValuePtr* valueSlot, size_t offset)
+        void setValueSlot(JSValue slotBase, JSValue* valueSlot, size_t offset)
         {
             ASSERT(valueSlot);
             m_getValue = JSC_VALUE_SLOT_MARKER;
@@ -114,11 +104,12 @@ namespace JSC {
             m_offset = offset;
         }
         
-        void setValue(JSValuePtr value)
+        void setValue(JSValue value)
         {
             ASSERT(value);
-            m_getValue = JSC_VALUE_SLOT_MARKER;
             clearBase();
+            clearOffset();
+            m_getValue = JSC_VALUE_SLOT_MARKER;
             m_value = value;
             m_data.valueSlot = &m_value;
         }
@@ -126,12 +117,13 @@ namespace JSC {
         void setRegisterSlot(Register* registerSlot)
         {
             ASSERT(registerSlot);
-            m_getValue = JSC_REGISTER_SLOT_MARKER;
             clearBase();
+            clearOffset();
+            m_getValue = JSC_REGISTER_SLOT_MARKER;
             m_data.registerSlot = registerSlot;
         }
 
-        void setCustom(JSValuePtr slotBase, GetValueFunc getValue)
+        void setCustom(JSValue slotBase, GetValueFunc getValue)
         {
             ASSERT(slotBase);
             ASSERT(getValue);
@@ -139,7 +131,7 @@ namespace JSC {
             m_slotBase = slotBase;
         }
 
-        void setCustomIndex(JSValuePtr slotBase, unsigned index, GetValueFunc getValue)
+        void setCustomIndex(JSValue slotBase, unsigned index, GetValueFunc getValue)
         {
             ASSERT(slotBase);
             ASSERT(getValue);
@@ -157,17 +149,15 @@ namespace JSC {
         
         void setUndefined()
         {
-            clearBase();
             setValue(jsUndefined());
         }
 
-        JSValuePtr slotBase() const
+        JSValue slotBase() const
         {
-            ASSERT(m_slotBase);
             return m_slotBase;
         }
 
-        void setBase(JSValuePtr base)
+        void setBase(JSValue base)
         {
             ASSERT(m_slotBase);
             ASSERT(base);
@@ -177,33 +167,40 @@ namespace JSC {
         void clearBase()
         {
 #ifndef NDEBUG
-            m_slotBase = noValue();
+            m_slotBase = JSValue();
 #endif
         }
 
         void clearValue()
         {
 #ifndef NDEBUG
-            m_value = noValue();
+            m_value = JSValue();
 #endif
         }
 
+        void clearOffset()
+        {
+            // Clear offset even in release builds, in case this PropertySlot has been used before.
+            // (For other data members, we don't need to clear anything because reuse would meaningfully overwrite them.)
+            m_offset = WTF::notFound;
+        }
+
         unsigned index() const { return m_data.index; }
 
     private:
-        static JSValuePtr functionGetter(ExecState*, const Identifier&, const PropertySlot&);
+        static JSValue functionGetter(ExecState*, const Identifier&, const PropertySlot&);
 
         GetValueFunc m_getValue;
         
-        JSValuePtr m_slotBase;
+        JSValue m_slotBase;
         union {
             JSObject* getterFunc;
-            JSValuePtr* valueSlot;
+            JSValue* valueSlot;
             Register* registerSlot;
             unsigned index;
         } m_data;
 
-        JSValuePtr m_value;
+        JSValue m_value;
 
         size_t m_offset;
     };
index c7f6b2d341c19878bffe08e6329f084798024717..224164d2f91b1bbad066e7087974b994a5b28e3c 100644 (file)
@@ -49,13 +49,13 @@ namespace JSC {
             gcUnprotect(val);
     }
     
-    inline void gcProtect(JSValuePtr value)
+    inline void gcProtect(JSValue value)
     {
         if (value && value.isCell())
             gcProtect(asCell(value));
     }
 
-    inline void gcUnprotect(JSValuePtr value)
+    inline void gcUnprotect(JSValue value)
     {
         if (value && value.isCell())
             gcUnprotect(asCell(value));
@@ -74,7 +74,7 @@ namespace JSC {
         
         T* get() const { return m_ptr; }
         operator T*() const { return m_ptr; }
-        operator JSValuePtr() const { return JSValuePtr(m_ptr); }
+        operator JSValue() const { return JSValue(m_ptr); }
         T* operator->() const { return m_ptr; }
         
         operator bool() const { return m_ptr; }
@@ -87,27 +87,27 @@ namespace JSC {
         T* m_ptr;
     };
 
-    class ProtectedJSValuePtr {
+    class ProtectedJSValue {
     public:
-        ProtectedJSValuePtr() {}
-        ProtectedJSValuePtr(JSValuePtr value);
-        ProtectedJSValuePtr(const ProtectedJSValuePtr&);
-        ~ProtectedJSValuePtr();
+        ProtectedJSValue() {}
+        ProtectedJSValue(JSValue value);
+        ProtectedJSValue(const ProtectedJSValue&);
+        ~ProtectedJSValue();
 
-        template <class U> ProtectedJSValuePtr(const ProtectedPtr<U>&);
+        template <class U> ProtectedJSValue(const ProtectedPtr<U>&);
         
-        JSValuePtr get() const { return m_value; }
-        operator JSValuePtr() const { return m_value; }
-        JSValuePtr operator->() const { return m_value; }
+        JSValue get() const { return m_value; }
+        operator JSValue() const { return m_value; }
+        JSValue operator->() const { return m_value; }
         
         operator bool() const { return m_value; }
         bool operator!() const { return !m_value; }
 
-        ProtectedJSValuePtr& operator=(const ProtectedJSValuePtr&);
-        ProtectedJSValuePtr& operator=(JSValuePtr);
+        ProtectedJSValue& operator=(const ProtectedJSValue&);
+        ProtectedJSValue& operator=(JSValue);
         
     private:
-        JSValuePtr m_value;
+        JSValue m_value;
     };
 
     template <class T> inline ProtectedPtr<T>::ProtectedPtr(T* ptr)
@@ -150,39 +150,39 @@ namespace JSC {
         return *this;
     }
 
-    inline ProtectedJSValuePtr::ProtectedJSValuePtr(JSValuePtr value)
+    inline ProtectedJSValue::ProtectedJSValue(JSValue value)
         : m_value(value)
     {
         gcProtect(m_value);
     }
 
-    inline ProtectedJSValuePtr::ProtectedJSValuePtr(const ProtectedJSValuePtr& o)
+    inline ProtectedJSValue::ProtectedJSValue(const ProtectedJSValue& o)
         : m_value(o.get())
     {
         gcProtect(m_value);
     }
 
-    inline ProtectedJSValuePtr::~ProtectedJSValuePtr()
+    inline ProtectedJSValue::~ProtectedJSValue()
     {
         gcUnprotect(m_value);
     }
 
-    template <class U> ProtectedJSValuePtr::ProtectedJSValuePtr(const ProtectedPtr<U>& o)
+    template <class U> ProtectedJSValue::ProtectedJSValue(const ProtectedPtr<U>& o)
         : m_value(o.get())
     {
         gcProtect(m_value);
     }
 
-    inline ProtectedJSValuePtr& ProtectedJSValuePtr::operator=(const ProtectedJSValuePtr& o) 
+    inline ProtectedJSValue& ProtectedJSValue::operator=(const ProtectedJSValue& o) 
     {
-        JSValuePtr ovalue = o.m_value;
+        JSValue ovalue = o.m_value;
         gcProtect(ovalue);
         gcUnprotect(m_value);
         m_value = ovalue;
         return *this;
     }
 
-    inline ProtectedJSValuePtr& ProtectedJSValuePtr::operator=(JSValuePtr ovalue)
+    inline ProtectedJSValue& ProtectedJSValue::operator=(JSValue ovalue)
     {
         gcProtect(ovalue);
         gcUnprotect(m_value);
@@ -198,17 +198,17 @@ namespace JSC {
     template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const T* b) { return a.get() != b; }
     template <class T> inline bool operator!=(const T* a, const ProtectedPtr<T>& b) { return a != b.get(); }
 
-    inline bool operator==(const ProtectedJSValuePtr& a, const ProtectedJSValuePtr& b) { return a.get() == b.get(); }
-    inline bool operator==(const ProtectedJSValuePtr& a, const JSValuePtr b) { return a.get() == b; }
-    template <class T> inline bool operator==(const ProtectedJSValuePtr& a, const ProtectedPtr<T>& b) { return a.get() == JSValuePtr(b.get()); }
-    inline bool operator==(const JSValuePtr a, const ProtectedJSValuePtr& b) { return a == b.get(); }
-    template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedJSValuePtr& b) { return JSValuePtr(a.get()) == b.get(); }
-
-    inline bool operator!=(const ProtectedJSValuePtr& a, const ProtectedJSValuePtr& b) { return a.get() != b.get(); }
-    inline bool operator!=(const ProtectedJSValuePtr& a, const JSValuePtr b) { return a.get() != b; }
-    template <class T> inline bool operator!=(const ProtectedJSValuePtr& a, const ProtectedPtr<T>& b) { return a.get() != JSValuePtr(b.get()); }
-    inline bool operator!=(const JSValuePtr a, const ProtectedJSValuePtr& b) { return a != b.get(); }
-    template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedJSValuePtr& b) { return JSValuePtr(a.get()) != b.get(); }
+    inline bool operator==(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() == b.get(); }
+    inline bool operator==(const ProtectedJSValue& a, const JSValue b) { return a.get() == b; }
+    template <class T> inline bool operator==(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() == JSValue(b.get()); }
+    inline bool operator==(const JSValue a, const ProtectedJSValue& b) { return a == b.get(); }
+    template <class T> inline bool operator==(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) == b.get(); }
+
+    inline bool operator!=(const ProtectedJSValue& a, const ProtectedJSValue& b) { return a.get() != b.get(); }
+    inline bool operator!=(const ProtectedJSValue& a, const JSValue b) { return a.get() != b; }
+    template <class T> inline bool operator!=(const ProtectedJSValue& a, const ProtectedPtr<T>& b) { return a.get() != JSValue(b.get()); }
+    inline bool operator!=(const JSValue a, const ProtectedJSValue& b) { return a != b.get(); }
+    template <class T> inline bool operator!=(const ProtectedPtr<T>& a, const ProtectedJSValue& b) { return JSValue(a.get()) != b.get(); }
  
 } // namespace JSC
 
index 1e2dfe920eedb5d441b2f1b88eb8441da87ec84e..eb8ea8a9942f7aaf1cb8003c92ced76bb4dd3cbf 100644 (file)
 namespace JSC {
     
     class JSObject;
+    class JSFunction;
     
     class PutPropertySlot {
     public:
-        enum Type { Invalid, ExistingProperty, NewProperty };
+        enum Type { Uncachable, ExistingProperty, NewProperty };
 
         PutPropertySlot()
-            : m_type(Invalid)
+            : m_type(Uncachable)
             , m_base(0)
-            , m_wasTransition(false)
         {
         }
 
@@ -61,18 +61,14 @@ namespace JSC {
         Type type() const { return m_type; }
         JSObject* base() const { return m_base; }
 
-        bool isCacheable() const { return m_type != Invalid; }
+        bool isCacheable() const { return m_type != Uncachable; }
         size_t cachedOffset() const {
             ASSERT(isCacheable());
             return m_offset;
         }
-        
-        bool wasTransition() const { return m_wasTransition; }
-        void setWasTransition(bool wasTransition) { m_wasTransition = wasTransition; }
     private:
         Type m_type;
         JSObject* m_base;
-        bool m_wasTransition;
         size_t m_offset;
     };
 
index b8251d279ea37065cc9a653e5c177ed2635e8a44..7dd4a8ffdede0b04eead102d02bffca35b2eb10f 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 1999-2001, 2004 Harri Porten (porten@kde.org)
  *  Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2009 Torch Mobile, Inc.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
 
 #include "config.h"
 #include "RegExp.h"
-
-#include "JIT.h"
 #include "Lexer.h"
-#include "WRECGenerator.h"
-#include <pcre/pcre.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <wtf/Assertions.h>
 #include <wtf/OwnArrayPtr.h>
 
+
+#if ENABLE(YARR)
+
+#include "yarr/RegexCompiler.h"
+#if ENABLE(YARR_JIT)
+#include "yarr/RegexJIT.h"
+#else
+#include "yarr/RegexInterpreter.h"
+#endif
+
+#else
+
+#if ENABLE(WREC)
+#include "JIT.h"
+#include "WRECGenerator.h"
+#endif
+#include <pcre/pcre.h>
+
+#endif
+
 namespace JSC {
 
 #if ENABLE(WREC)
@@ -40,32 +57,16 @@ using namespace WREC;
 inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
     : m_pattern(pattern)
     , m_flagBits(0)
-    , m_regExp(0)
     , m_constructionError(0)
     , m_numSubpatterns(0)
 {
-#if ENABLE(WREC)
-    m_wrecFunction = Generator::compileRegExp(globalData, pattern, &m_numSubpatterns, &m_constructionError, m_executablePool);
-    if (m_wrecFunction || m_constructionError)
-        return;
-    // Fall through to non-WREC case.
-#else
-    UNUSED_PARAM(globalData);
-#endif
-    m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
-        JSRegExpDoNotIgnoreCase, JSRegExpSingleLine, &m_numSubpatterns, &m_constructionError);
-}
-
-PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern)
-{
-    return adoptRef(new RegExp(globalData, pattern));
+    compile(globalData);
 }
 
 inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags)
     : m_pattern(pattern)
     , m_flags(flags)
     , m_flagBits(0)
-    , m_regExp(0)
     , m_constructionError(0)
     , m_numSubpatterns(0)
 {
@@ -73,30 +74,24 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const US
     // String::match and RegExpObject::match.
     if (flags.find('g') != -1)
         m_flagBits |= Global;
-
-    // FIXME: Eliminate duplication by adding a way ask a JSRegExp what its flags are?
-    JSRegExpIgnoreCaseOption ignoreCaseOption = JSRegExpDoNotIgnoreCase;
-    if (flags.find('i') != -1) {
+    if (flags.find('i') != -1)
         m_flagBits |= IgnoreCase;
-        ignoreCaseOption = JSRegExpIgnoreCase;
-    }
-
-    JSRegExpMultilineOption multilineOption = JSRegExpSingleLine;
-    if (flags.find('m') != -1) {
+    if (flags.find('m') != -1)
         m_flagBits |= Multiline;
-        multilineOption = JSRegExpMultiline;
-    }
 
-#if ENABLE(WREC)
-    m_wrecFunction = Generator::compileRegExp(globalData, pattern, &m_numSubpatterns, &m_constructionError, m_executablePool, (m_flagBits & IgnoreCase), (m_flagBits & Multiline));
-    if (m_wrecFunction || m_constructionError)
-        return;
-    // Fall through to non-WREC case.
-#else
-    UNUSED_PARAM(globalData);
+    compile(globalData);
+}
+
+#if !ENABLE(YARR)
+RegExp::~RegExp()
+{
+    jsRegExpFree(m_regExp);
+}
 #endif
-    m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(pattern.data()), pattern.size(),
-        ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
+
+PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern)
+{
+    return adoptRef(new RegExp(globalData, pattern));
 }
 
 PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& pattern, const UString& flags)
@@ -104,12 +99,90 @@ PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patte
     return adoptRef(new RegExp(globalData, pattern, flags));
 }
 
-RegExp::~RegExp()
+#if ENABLE(YARR)
+
+void RegExp::compile(JSGlobalData* globalData)
 {
-    jsRegExpFree(m_regExp);
+#if ENABLE(YARR_JIT)
+    Yarr::jitCompileRegex(globalData, m_regExpJITCode, m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline());
+#else
+    UNUSED_PARAM(globalData);
+    m_regExpBytecode.set(Yarr::byteCompileRegex(m_pattern, m_numSubpatterns, m_constructionError, ignoreCase(), multiline()));
+#endif
 }
 
-int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
+int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
+{
+    if (startOffset < 0)
+        startOffset = 0;
+    if (ovector)
+        ovector->clear();
+
+    if (startOffset > s.size() || s.isNull())
+        return -1;
+
+#if ENABLE(YARR_JIT)
+    if (!!m_regExpJITCode) {
+#else
+    if (m_regExpBytecode) {
+#endif
+        int offsetVectorSize = (m_numSubpatterns + 1) * 3; // FIXME: should be 2 - but adding temporary fallback to pcre.
+        int* offsetVector;
+        Vector<int, 32> nonReturnedOvector;
+        if (ovector) {
+            ovector->resize(offsetVectorSize);
+            offsetVector = ovector->data();
+        } else {
+            nonReturnedOvector.resize(offsetVectorSize);
+            offsetVector = nonReturnedOvector.data();
+        }
+
+        ASSERT(offsetVector);
+        for (int j = 0; j < offsetVectorSize; ++j)
+            offsetVector[j] = -1;
+
+
+#if ENABLE(YARR_JIT)
+        int result = Yarr::executeRegex(m_regExpJITCode, s.data(), startOffset, s.size(), offsetVector, offsetVectorSize);
+#else
+        int result = Yarr::interpretRegex(m_regExpBytecode.get(), s.data(), startOffset, s.size(), offsetVector);
+#endif
+
+        if (result < 0) {
+#ifndef NDEBUG
+            // TODO: define up a symbol, rather than magic -1
+            if (result != -1)
+                fprintf(stderr, "jsRegExpExecute failed with result %d\n", result);
+#endif
+            if (ovector)
+                ovector->clear();
+        }
+        return result;
+    }
+
+    return -1;
+}
+
+#else
+
+void RegExp::compile(JSGlobalData* globalData)
+{
+    m_regExp = 0;
+#if ENABLE(WREC)
+    m_wrecFunction = Generator::compileRegExp(globalData, m_pattern, &m_numSubpatterns, &m_constructionError, m_executablePool, ignoreCase(), multiline());
+    if (m_wrecFunction || m_constructionError)
+        return;
+    // Fall through to non-WREC case.
+#else
+    UNUSED_PARAM(globalData);
+#endif
+
+    JSRegExpIgnoreCaseOption ignoreCaseOption = ignoreCase() ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase;
+    JSRegExpMultilineOption multilineOption = multiline() ? JSRegExpMultiline : JSRegExpSingleLine;
+    m_regExp = jsRegExpCompile(reinterpret_cast<const UChar*>(m_pattern.data()), m_pattern.size(), ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
+}
+
+int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
 {
     if (startOffset < 0)
         startOffset = 0;
@@ -122,16 +195,19 @@ int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
 #if ENABLE(WREC)
     if (m_wrecFunction) {
         int offsetVectorSize = (m_numSubpatterns + 1) * 2;
-        int* offsetVector = new int [offsetVectorSize];
+        int* offsetVector;
+        Vector<int, 32> nonReturnedOvector;
+        if (ovector) {
+            ovector->resize(offsetVectorSize);
+            offsetVector = ovector->data();
+        } else {
+            nonReturnedOvector.resize(offsetVectorSize);
+            offsetVector = nonReturnedOvector.data();
+        }
+        ASSERT(offsetVector);
         for (int j = 0; j < offsetVectorSize; ++j)
             offsetVector[j] = -1;
 
-        OwnArrayPtr<int> nonReturnedOvector;
-        if (!ovector)
-            nonReturnedOvector.set(offsetVector);
-        else
-            ovector->set(offsetVector);
-
         int result = m_wrecFunction(s.data(), startOffset, s.size(), offsetVector);
 
         if (result < 0) {
@@ -157,8 +233,8 @@ int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
             offsetVector = fixedSizeOffsetVector;
         } else {
             offsetVectorSize = (m_numSubpatterns + 1) * 3;
-            offsetVector = new int [offsetVectorSize];
-            ovector->set(offsetVector);
+            ovector->resize(offsetVectorSize);
+            offsetVector = ovector->data();
         }
 
         int numMatches = jsRegExpExecute(m_regExp, reinterpret_cast<const UChar*>(s.data()), s.size(), startOffset, offsetVector, offsetVectorSize);
@@ -179,4 +255,6 @@ int RegExp::match(const UString& s, int startOffset, OwnArrayPtr<int>* ovector)
     return -1;
 }
 
+#endif
+
 } // namespace JSC
index 139c754f2b5a2d5828770805016ecc6f130e1164..24d4199f4c7478985cd7d3780736982708714d01 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2009 Torch Mobile, Inc.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -26,6 +27,8 @@
 #include "ExecutableAllocator.h"
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
+#include "yarr/RegexJIT.h"
+#include "yarr/RegexInterpreter.h"
 
 struct JSRegExp;
 
@@ -37,7 +40,9 @@ namespace JSC {
     public:
         static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern);
         static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags);
+#if !ENABLE(YARR)
         ~RegExp();
+#endif
 
         bool global() const { return m_flagBits & Global; }
         bool ignoreCase() const { return m_flagBits & IgnoreCase; }
@@ -49,27 +54,33 @@ namespace JSC {
         bool isValid() const { return !m_constructionError; }
         const char* errorMessage() const { return m_constructionError; }
 
-        int match(const UString&, int startOffset, OwnArrayPtr<int>* ovector = 0);
+        int match(const UString&, int startOffset, Vector<int, 32>* ovector = 0);
         unsigned numSubpatterns() const { return m_numSubpatterns; }
 
     private:
         RegExp(JSGlobalData* globalData, const UString& pattern);
         RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags);
 
-        void compile();
+        void compile(JSGlobalData*);
 
         enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 };
 
         UString m_pattern; // FIXME: Just decompile m_regExp instead of storing this.
         UString m_flags; // FIXME: Just decompile m_regExp instead of storing this.
         int m_flagBits;
-        JSRegExp* m_regExp;
         const char* m_constructionError;
         unsigned m_numSubpatterns;
 
+#if ENABLE(YARR_JIT)
+        Yarr::RegexCodeBlock m_regExpJITCode;
+#elif ENABLE(YARR)
+        OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
+#else
 #if ENABLE(WREC)
         WREC::CompiledRegExp m_wrecFunction;
         RefPtr<ExecutablePool> m_executablePool;
+#endif
+        JSRegExp* m_regExp;
 #endif
     };
 
index bff51e05ed20e5ca729693f55224943d99f588d2..e46852130ebc0b84bf938aaa12c6b3c25f036688 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
+ *  Copyright (C) 2009 Torch Mobile, Inc.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
 
 namespace JSC {
 
-static JSValuePtr regExpConstructorInput(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorLastMatch(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorLastParen(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorLeftContext(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorRightContext(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar1(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar2(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar3(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar4(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar5(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar6(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar7(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar8(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpConstructorDollar9(ExecState*, const Identifier&, const PropertySlot&);
-
-static void setRegExpConstructorInput(ExecState*, JSObject*, JSValuePtr);
-static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValuePtr);
+static JSValue regExpConstructorInput(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorLastMatch(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorLastParen(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorLeftContext(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorRightContext(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorDollar1(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorDollar2(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorDollar3(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorDollar4(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorDollar5(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorDollar6(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorDollar7(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorDollar8(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpConstructorDollar9(ExecState*, const Identifier&, const PropertySlot&);
+
+static void setRegExpConstructorInput(ExecState*, JSObject*, JSValue);
+static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValue);
 
 } // namespace JSC
 
@@ -93,14 +94,21 @@ struct RegExpConstructorPrivate {
     RegExpConstructorPrivate()
         : lastNumSubPatterns(0)
         , multiline(false)
+        , lastOvectorIndex(0)
     {
     }
 
+    const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; }
+    Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; }
+    Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; }
+    void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; }
+
     UString input;
     UString lastInput;
-    OwnArrayPtr<int> lastOvector;
-    unsigned lastNumSubPatterns : 31;
+    Vector<int, 32> ovector[2];
+    unsigned lastNumSubPatterns : 30;
     bool multiline : 1;
+    unsigned lastOvectorIndex : 1;
 };
 
 RegExpConstructor::RegExpConstructor(ExecState* exec, PassRefPtr<Structure> structure, RegExpPrototype* regExpPrototype)
@@ -121,20 +129,19 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, PassRefPtr<Structure> stru
 */
 void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector)
 {
-    OwnArrayPtr<int> tmpOvector;
-    position = r->match(s, startOffset, &tmpOvector);
+    position = r->match(s, startOffset, &d->tempOvector());
 
     if (ovector)
-        *ovector = tmpOvector.get();
+        *ovector = d->tempOvector().data();
 
     if (position != -1) {
-        ASSERT(tmpOvector);
+        ASSERT(!d->tempOvector().isEmpty());
 
-        length = tmpOvector[1] - tmpOvector[0];
+        length = d->tempOvector()[1] - d->tempOvector()[0];
 
         d->input = s;
         d->lastInput = s;
-        d->lastOvector.set(tmpOvector.release());
+        d->changeLastOvector();
         d->lastNumSubPatterns = r->numSubpatterns();
     }
 }
@@ -147,8 +154,8 @@ RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate
     d->lastInput = data->lastInput;
     d->lastNumSubPatterns = data->lastNumSubPatterns;
     unsigned offsetVectorSize = (data->lastNumSubPatterns + 1) * 2; // only copying the result part of the vector
-    d->lastOvector.set(new int[offsetVectorSize]);
-    memcpy(d->lastOvector.get(), data->lastOvector.get(), offsetVectorSize * sizeof(int));
+    d->lastOvector().resize(offsetVectorSize);
+    memcpy(d->lastOvector().data(), data->lastOvector().data(), offsetVectorSize * sizeof(int));
     // d->multiline is not needed, and remains uninitialized
 
     setLazyCreationData(d);
@@ -167,13 +174,13 @@ void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
     unsigned lastNumSubpatterns = d->lastNumSubPatterns;
 
     for (unsigned i = 0; i <= lastNumSubpatterns; ++i) {
-        int start = d->lastOvector[2 * i];
+        int start = d->lastOvector()[2 * i];
         if (start >= 0)
-            JSArray::put(exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start));
+            JSArray::put(exec, i, jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start));
     }
 
     PutPropertySlot slot;
-    JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector[0]), slot);
+    JSArray::put(exec, exec->propertyNames().index, jsNumber(exec, d->lastOvector()[0]), slot);
     JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot);
 
     delete d;
@@ -185,39 +192,39 @@ JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
     return new (exec) RegExpMatchesArray(exec, d.get());
 }
 
-JSValuePtr RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
+JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i) const
 {
-    if (d->lastOvector && i <= d->lastNumSubPatterns) {
-        int start = d->lastOvector[2 * i];
+    if (!d->lastOvector().isEmpty() && i <= d->lastNumSubPatterns) {
+        int start = d->lastOvector()[2 * i];
         if (start >= 0)
-            return jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start);
+            return jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start);
     }
     return jsEmptyString(exec);
 }
 
-JSValuePtr RegExpConstructor::getLastParen(ExecState* exec) const
+JSValue RegExpConstructor::getLastParen(ExecState* exec) const
 {
     unsigned i = d->lastNumSubPatterns;
     if (i > 0) {
-        ASSERT(d->lastOvector);
-        int start = d->lastOvector[2 * i];
+        ASSERT(!d->lastOvector().isEmpty());
+        int start = d->lastOvector()[2 * i];
         if (start >= 0)
-            return jsSubstring(exec, d->lastInput, start, d->lastOvector[2 * i + 1] - start);
+            return jsSubstring(exec, d->lastInput, start, d->lastOvector()[2 * i + 1] - start);
     }
     return jsEmptyString(exec);
 }
 
-JSValuePtr RegExpConstructor::getLeftContext(ExecState* exec) const
+JSValue RegExpConstructor::getLeftContext(ExecState* exec) const
 {
-    if (d->lastOvector)
-        return jsSubstring(exec, d->lastInput, 0, d->lastOvector[0]);
+    if (!d->lastOvector().isEmpty())
+        return jsSubstring(exec, d->lastInput, 0, d->lastOvector()[0]);
     return jsEmptyString(exec);
 }
 
-JSValuePtr RegExpConstructor::getRightContext(ExecState* exec) const
+JSValue RegExpConstructor::getRightContext(ExecState* exec) const
 {
-    if (d->lastOvector)
-        return jsSubstring(exec, d->lastInput, d->lastOvector[1], d->lastInput.size() - d->lastOvector[1]);
+    if (!d->lastOvector().isEmpty())
+        return jsSubstring(exec, d->lastInput, d->lastOvector()[1], d->lastInput.size() - d->lastOvector()[1]);
     return jsEmptyString(exec);
 }
     
@@ -226,92 +233,92 @@ bool RegExpConstructor::getOwnPropertySlot(ExecState* exec, const Identifier& pr
     return getStaticValueSlot<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, slot);
 }
 
-JSValuePtr regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 1);
 }
 
-JSValuePtr regExpConstructorDollar2(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar2(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 2);
 }
 
-JSValuePtr regExpConstructorDollar3(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar3(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 3);
 }
 
-JSValuePtr regExpConstructorDollar4(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar4(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 4);
 }
 
-JSValuePtr regExpConstructorDollar5(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar5(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 5);
 }
 
-JSValuePtr regExpConstructorDollar6(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar6(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 6);
 }
 
-JSValuePtr regExpConstructorDollar7(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar7(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 7);
 }
 
-JSValuePtr regExpConstructorDollar8(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar8(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 8);
 }
 
-JSValuePtr regExpConstructorDollar9(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar9(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 9);
 }
 
-JSValuePtr regExpConstructorInput(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorInput(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return jsString(exec, asRegExpConstructor(slot.slotBase())->input());
 }
 
-JSValuePtr regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
 {
     return jsBoolean(asRegExpConstructor(slot.slotBase())->multiline());
 }
 
-JSValuePtr regExpConstructorLastMatch(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorLastMatch(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getBackref(exec, 0);
 }
 
-JSValuePtr regExpConstructorLastParen(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorLastParen(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getLastParen(exec);
 }
 
-JSValuePtr regExpConstructorLeftContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorLeftContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getLeftContext(exec);
 }
 
-JSValuePtr regExpConstructorRightContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorRightContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return asRegExpConstructor(slot.slotBase())->getRightContext(exec);
 }
 
-void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     lookupPut<RegExpConstructor, InternalFunction>(exec, propertyName, value, ExecState::regExpConstructorTable(exec), this, slot);
 }
 
-void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValuePtr value)
+void setRegExpConstructorInput(ExecState* exec, JSObject* baseObject, JSValue value)
 {
     asRegExpConstructor(baseObject)->setInput(value.toString(exec));
 }
 
-void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValuePtr value)
+void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValue value)
 {
     asRegExpConstructor(baseObject)->setMultiline(value.toBoolean(exec));
 }
@@ -319,8 +326,8 @@ void setRegExpConstructorMultiline(ExecState* exec, JSObject* baseObject, JSValu
 // ECMA 15.10.4
 JSObject* constructRegExp(ExecState* exec, const ArgList& args)
 {
-    JSValuePtr arg0 = args.at(exec, 0);
-    JSValuePtr arg1 = args.at(exec, 1);
+    JSValue arg0 = args.at(0);
+    JSValue arg1 = args.at(1);
 
     if (arg0.isObject(&RegExpObject::info)) {
         if (!arg1.isUndefined())
@@ -349,7 +356,7 @@ ConstructType RegExpConstructor::getConstructData(ConstructData& constructData)
 }
 
 // ECMA 15.10.3
-static JSValuePtr callRegExpConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callRegExpConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     return constructRegExp(exec, args);
 }
index f8c43663c9736e816da228131f22d77da252e2aa..6823f3fb709801be9300064eb40a8ec7adf3821b 100644 (file)
@@ -34,12 +34,12 @@ namespace JSC {
     public:
         RegExpConstructor(ExecState*, PassRefPtr<Structure>, RegExpPrototype*);
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
             return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
         }
 
-        virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
 
         static const ClassInfo info;
@@ -53,10 +53,10 @@ namespace JSC {
         void setMultiline(bool);
         bool multiline() const;
 
-        JSValuePtr getBackref(ExecState*, unsigned) const;
-        JSValuePtr getLastParen(ExecState*) const;
-        JSValuePtr getLeftContext(ExecState*) const;
-        JSValuePtr getRightContext(ExecState*) const;
+        JSValue getBackref(ExecState*, unsigned) const;
+        JSValue getLastParen(ExecState*) const;
+        JSValue getLeftContext(ExecState*) const;
+        JSValue getRightContext(ExecState*) const;
 
     private:
         virtual ConstructType getConstructData(ConstructData&);
@@ -67,11 +67,11 @@ namespace JSC {
         OwnPtr<RegExpConstructorPrivate> d;
     };
 
-    RegExpConstructor* asRegExpConstructor(JSValuePtr);
+    RegExpConstructor* asRegExpConstructor(JSValue);
 
     JSObject* constructRegExp(ExecState*, const ArgList&);
 
-    inline RegExpConstructor* asRegExpConstructor(JSValuePtr value)
+    inline RegExpConstructor* asRegExpConstructor(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&RegExpConstructor::info));
         return static_cast<RegExpConstructor*>(asObject(value));
index 358394117f1fd6af78e794a4b6499a715f4c73a6..9ae18b9e891492460c8b6491bf568e637c4c1bcd 100644 (file)
@@ -44,14 +44,14 @@ namespace JSC {
             return JSArray::getOwnPropertySlot(exec, propertyName, slot);
         }
 
-        virtual void put(ExecState* exec, const Identifier& propertyName, JSValuePtr v, PutPropertySlot& slot)
+        virtual void put(ExecState* exec, const Identifier& propertyName, JSValue v, PutPropertySlot& slot)
         {
             if (lazyCreationData())
                 fillArrayInstance(exec);
             JSArray::put(exec, propertyName, v, slot);
         }
 
-        virtual void put(ExecState* exec, unsigned propertyName, JSValuePtr v)
+        virtual void put(ExecState* exec, unsigned propertyName, JSValue v)
         {
             if (lazyCreationData())
                 fillArrayInstance(exec);
index f8e0522223897da36e85dcfe5c043c46c7ce3a70..687844ed5213ced3a98be4d03f1fbb6ff3204cbc 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "RegExpObject.h"
 
+#include "Error.h"
 #include "JSArray.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
 
 namespace JSC {
 
-static JSValuePtr regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpObjectSource(ExecState*, const Identifier&, const PropertySlot&);
-static JSValuePtr regExpObjectLastIndex(ExecState*, const Identifier&, const PropertySlot&);
-static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValuePtr);
+static JSValue regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpObjectSource(ExecState*, const Identifier&, const PropertySlot&);
+static JSValue regExpObjectLastIndex(ExecState*, const Identifier&, const PropertySlot&);
+static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue);
 
 } // namespace JSC
 
@@ -71,54 +72,54 @@ bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propert
     return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
 }
 
-JSValuePtr regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
 {
     return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->global());
 }
 
-JSValuePtr regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
 {
     return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->ignoreCase());
 }
  
-JSValuePtr regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
 {            
     return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->multiline());
 }
 
-JSValuePtr regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return jsString(exec, asRegExpObject(slot.slotBase())->regExp()->pattern());
 }
 
-JSValuePtr regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
 {
     return jsNumber(exec, asRegExpObject(slot.slotBase())->lastIndex());
 }
 
-void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot);
 }
 
-void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValuePtr value)
+void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value)
 {
     asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec));
 }
 
-JSValuePtr RegExpObject::test(ExecState* exec, const ArgList& args)
+JSValue RegExpObject::test(ExecState* exec, const ArgList& args)
 {
     return jsBoolean(match(exec, args));
 }
 
-JSValuePtr RegExpObject::exec(ExecState* exec, const ArgList& args)
+JSValue RegExpObject::exec(ExecState* exec, const ArgList& args)
 {
     if (match(exec, args))
         return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec);
     return jsNull();
 }
 
-static JSValuePtr callRegExpObject(ExecState* exec, JSObject* function, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callRegExpObject(ExecState* exec, JSObject* function, JSValue, const ArgList& args)
 {
     return asRegExpObject(function)->exec(exec, args);
 }
@@ -134,7 +135,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args)
 {
     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
 
-    UString input = args.isEmpty() ? regExpConstructor->input() : args.at(exec, 0).toString(exec);
+    UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec);
     if (input.isNull()) {
         throwError(exec, GeneralError, "No input to " + toString(exec) + ".");
         return false;
index 4c99c30133d095192b7e51c65185408517b14748..fac9978f10a46977e3ab11c382624017ff0f33b4 100644 (file)
@@ -37,16 +37,16 @@ namespace JSC {
         void setLastIndex(double lastIndex) { d->lastIndex = lastIndex; }
         double lastIndex() const { return d->lastIndex; }
 
-        JSValuePtr test(ExecState*, const ArgList&);
-        JSValuePtr exec(ExecState*, const ArgList&);
+        JSValue test(ExecState*, const ArgList&);
+        JSValue exec(ExecState*, const ArgList&);
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
-        virtual void put(ExecState*, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
 
         virtual const ClassInfo* classInfo() const { return &info; }
         static const ClassInfo info;
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
             return Structure::create(prototype, TypeInfo(ObjectType));
         }
@@ -70,9 +70,9 @@ namespace JSC {
         OwnPtr<RegExpObjectData> d;
     };
 
-    RegExpObject* asRegExpObject(JSValuePtr);
+    RegExpObject* asRegExpObject(JSValue);
 
-    inline RegExpObject* asRegExpObject(JSValuePtr value)
+    inline RegExpObject* asRegExpObject(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&RegExpObject::info));
         return static_cast<RegExpObject*>(asObject(value));
index 73787bcc6e9b9fe9e6f5b7745e811268d0c70277..b1ab889e04cc27cdcb6cf590367110fc436f699f 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "ArrayPrototype.h"
 #include "JSArray.h"
+#include "JSFunction.h"
 #include "JSObject.h"
 #include "JSString.h"
 #include "JSValue.h"
@@ -35,10 +36,10 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(RegExpPrototype);
 
-static JSValuePtr regExpProtoFuncTest(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr regExpProtoFuncExec(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr regExpProtoFuncCompile(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr regExpProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
 
 // ECMA 15.10.5
 
@@ -47,36 +48,36 @@ const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0, 0 };
 RegExpPrototype::RegExpPrototype(ExecState* exec, PassRefPtr<Structure> structure, Structure* prototypeFunctionStructure)
     : JSObject(structure)
 {
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum);
 }
 
 // ------------------------------ Functions ---------------------------
     
-JSValuePtr regExpProtoFuncTest(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     if (!thisValue.isObject(&RegExpObject::info))
         return throwError(exec, TypeError);
     return asRegExpObject(thisValue)->test(exec, args);
 }
 
-JSValuePtr regExpProtoFuncExec(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     if (!thisValue.isObject(&RegExpObject::info))
         return throwError(exec, TypeError);
     return asRegExpObject(thisValue)->exec(exec, args);
 }
 
-JSValuePtr regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     if (!thisValue.isObject(&RegExpObject::info))
         return throwError(exec, TypeError);
 
     RefPtr<RegExp> regExp;
-    JSValuePtr arg0 = args.at(exec, 0);
-    JSValuePtr arg1 = args.at(exec, 1);
+    JSValue arg0 = args.at(0);
+    JSValue arg1 = args.at(1);
     
     if (arg0.isObject(&RegExpObject::info)) {
         if (!arg1.isUndefined())
@@ -96,7 +97,7 @@ JSValuePtr regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValuePtr thisVal
     return jsUndefined();
 }
 
-JSValuePtr regExpProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     if (!thisValue.isObject(&RegExpObject::info)) {
         if (thisValue.isObject(&RegExpPrototype::info))
index 32b5e9235cd358cc8fe2657b02c6dbd6ac1b1711..17aff24ec102fa152e2e686fd9d3712fab9a4db6 100644 (file)
@@ -21,7 +21,7 @@
 #ifndef ScopeChain_h
 #define ScopeChain_h
 
-#include <wtf/Assertions.h>
+#include "FastAllocBase.h"
 
 namespace JSC {
 
@@ -30,7 +30,7 @@ namespace JSC {
     class JSObject;
     class ScopeChainIterator;
     
-    class ScopeChainNode {
+    class ScopeChainNode : public FastAllocBase {
     public:
         ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSObject* globalThis)
             : next(next)
@@ -41,6 +41,18 @@ namespace JSC {
         {
             ASSERT(globalData);
         }
+#ifndef NDEBUG
+        // Due to the number of subtle and timing dependent bugs that have occurred due
+        // to deleted but still "valid" ScopeChainNodes we now deliberately clobber the
+        // contents in debug builds.
+        ~ScopeChainNode()
+        {
+            next = 0;
+            object = 0;
+            globalData = 0;
+            globalThis = 0;
+        }
+#endif
 
         ScopeChainNode* next;
         JSObject* object;
@@ -171,6 +183,9 @@ namespace JSC {
         {
             if (m_node)
                 m_node->deref();
+#ifndef NDEBUG
+            m_node = 0;
+#endif
         }
 
         void swap(ScopeChain&);
index 6c73df204f6e76d10a9f014ab90b22bc04cba0b1..87b49f05a5ce7eb1a85d90264ae732a485c4adca 100644 (file)
@@ -47,25 +47,17 @@ private:
 };
 
 SmallStringsStorage::SmallStringsStorage()
+    : m_base(m_characters, numCharactersToStore)
 {
-    for (unsigned i = 0; i < numCharactersToStore; ++i)
-        m_characters[i] = i;
-
     m_base.rc = numCharactersToStore + 1;
-    m_base.buf = m_characters;
-    m_base.len = numCharactersToStore;
-    m_base.offset = 0;
-    m_base._hash = 0;
-    m_base.m_baseString = 0;
-    m_base.preCapacity = 0;
-    m_base.usedPreCapacity = 0;
-    m_base.reportedCost = 0;
-
     // make sure UString doesn't try to reuse the buffer by pretending we have one more character in it
     m_base.usedCapacity = numCharactersToStore + 1;
     m_base.capacity = numCharactersToStore + 1;
     m_base.checkConsistency();
 
+    for (unsigned i = 0; i < numCharactersToStore; ++i)
+        m_characters[i] = i;
+
     memset(&m_reps, 0, sizeof(m_reps));
     for (unsigned i = 0; i < numCharactersToStore; ++i) {
         m_reps[i].offset = i;
index dc1d60fee62590c65e17027d6cd9fa5243badfc7..638044587437a1d3c45873efa33cda09c41d8337 100644 (file)
 #include "config.h"
 #include "StringConstructor.h"
 
+#include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "PrototypeFunction.h"
 #include "StringPrototype.h"
 
 namespace JSC {
 
-static NEVER_INLINE JSValuePtr stringFromCharCodeSlowCase(ExecState* exec, const ArgList& args)
+static NEVER_INLINE JSValue stringFromCharCodeSlowCase(ExecState* exec, const ArgList& args)
 {
     UChar* buf = static_cast<UChar*>(fastMalloc(args.size() * sizeof(UChar)));
     UChar* p = buf;
     ArgList::const_iterator end = args.end();
     for (ArgList::const_iterator it = args.begin(); it != end; ++it)
-        *p++ = static_cast<UChar>((*it).jsValue(exec).toUInt32(exec));
+        *p++ = static_cast<UChar>((*it).toUInt32(exec));
     return jsString(exec, UString(buf, p - buf, false));
 }
 
-static JSValuePtr stringFromCharCode(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL stringFromCharCode(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     if (LIKELY(args.size() == 1))
-        return jsSingleCharacterString(exec, args.at(exec, 0).toUInt32(exec));
+        return jsSingleCharacterString(exec, args.at(0).toUInt32(exec));
     return stringFromCharCodeSlowCase(exec, args);
 }
 
@@ -53,7 +54,7 @@ StringConstructor::StringConstructor(ExecState* exec, PassRefPtr<Structure> stru
     putDirectWithoutTransition(exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
 
     // ECMA 15.5.3.2 fromCharCode()
-    putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum);
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum);
 
     // no. of arguments for constructor
     putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
@@ -64,7 +65,7 @@ static JSObject* constructWithStringConstructor(ExecState* exec, JSObject*, cons
 {
     if (args.isEmpty())
         return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure());
-    return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), args.at(exec, 0).toString(exec));
+    return new (exec) StringObject(exec, exec->lexicalGlobalObject()->stringObjectStructure(), args.at(0).toString(exec));
 }
 
 ConstructType StringConstructor::getConstructData(ConstructData& constructData)
@@ -74,11 +75,11 @@ ConstructType StringConstructor::getConstructData(ConstructData& constructData)
 }
 
 // ECMA 15.5.1
-static JSValuePtr callStringConstructor(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args)
+static JSValue JSC_HOST_CALL callStringConstructor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     if (args.isEmpty())
         return jsEmptyString(exec);
-    return jsString(exec, args.at(exec, 0).toString(exec));
+    return jsString(exec, args.at(0).toString(exec));
 }
 
 CallType StringConstructor::getCallData(CallData& callData)
index 093f5de92fbd2f3486997ef1cb247fbc2478ed4d..fb44498a57e1a7274358abcbe8f9eb4bd14dc6b9 100644 (file)
@@ -61,7 +61,7 @@ bool StringObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, Pr
     return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
 }
 
-void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
+void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
     if (propertyName == exec->propertyNames().length)
         return;
index 540c5761e1b4a37a12fdcf5378af2c239052fbcc..ea3a0454664a771a580c7a9a34252e8ed7dc4b52 100644 (file)
@@ -36,16 +36,16 @@ namespace JSC {
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
 
-        virtual void put(ExecState* exec, const Identifier& propertyName, JSValuePtr, PutPropertySlot&);
+        virtual void put(ExecState* exec, const Identifier& propertyName, JSValue, PutPropertySlot&);
         virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
 
         virtual const ClassInfo* classInfo() const { return &info; }
-        static const ClassInfo info;
+        static const JS_EXPORTDATA ClassInfo info;
 
         JSString* internalValue() const { return asString(JSWrapperObject::internalValue());}
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr prototype)
+        static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
             return Structure::create(prototype, TypeInfo(ObjectType));
         }
@@ -59,9 +59,9 @@ namespace JSC {
         virtual JSString* toThisJSString(ExecState*);
   };
 
-    StringObject* asStringObject(JSValuePtr);
+    StringObject* asStringObject(JSValue);
 
-    inline StringObject* asStringObject(JSValuePtr value)
+    inline StringObject* asStringObject(JSValue value)
     {
         ASSERT(asObject(value)->inherits(&StringObject::info));
         return static_cast<StringObject*>(asObject(value));
index 72c0f47f98a69be25bcec1276b70080bd3e19ecb..bc5c0a5b22eb9f6fa88578215ce806ae185a2aa4 100644 (file)
@@ -42,7 +42,7 @@ namespace JSC {
         {
         }
 
-        static PassRefPtr<Structure> createStructure(JSValuePtr proto) 
+        static PassRefPtr<Structure> createStructure(JSValue proto) 
         { 
             return Structure::create(proto, TypeInfo(ObjectType, MasqueradesAsUndefined)); 
         }
index 9c58f8583a6ffc352114ff74b8016f5ced37ea08..531a302d5ea40fdd8f12facf53d85af7f290da5d 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2009 Torch Mobile, Inc.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -21,6 +22,7 @@
 #include "config.h"
 #include "StringPrototype.h"
 
+#include "CachedCall.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "ObjectPrototype.h"
@@ -37,36 +39,36 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(StringPrototype);
 
-static JSValuePtr stringProtoFuncToString(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncCharAt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncCharCodeAt(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncConcat(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncLastIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncMatch(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncReplace(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSearch(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSlice(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSplit(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSubstr(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSubstring(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncToLowerCase(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncToUpperCase(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncLocaleCompare(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-
-static JSValuePtr stringProtoFuncBig(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSmall(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncBlink(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncBold(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncFixed(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncItalics(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncStrike(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSub(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncSup(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncFontcolor(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncFontsize(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncAnchor(ExecState*, JSObject*, JSValuePtr, const ArgList&);
-static JSValuePtr stringProtoFuncLink(ExecState*, JSObject*, JSValuePtr, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState*, JSObject*, JSValue, const ArgList&);
+
+static JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState*, JSObject*, JSValue, const ArgList&);
+static JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState*, JSObject*, JSValue, const ArgList&);
 
 }
 
@@ -204,14 +206,14 @@ static inline int localeCompare(const UString& a, const UString& b)
     return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.data()), a.size(), reinterpret_cast<const ::UChar*>(b.data()), b.size());
 }
 
-JSValuePtr stringProtoFuncReplace(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSString* sourceVal = thisValue.toThisJSString(exec);
     const UString& source = sourceVal->value();
 
-    JSValuePtr pattern = args.at(exec, 0);
+    JSValue pattern = args.at(0);
 
-    JSValuePtr replacement = args.at(exec, 1);
+    JSValue replacement = args.at(1);
     UString replacementString;
     CallData callData;
     CallType callType = replacement.getCallData(callData);
@@ -231,71 +233,120 @@ JSValuePtr stringProtoFuncReplace(ExecState* exec, JSObject*, JSValuePtr thisVal
         Vector<UString, 16> replacements;
 
         // This is either a loop (if global is set) or a one-way (if not).
-        do {
-            int matchIndex;
-            int matchLen;
-            int* ovector;
-            regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
-            if (matchIndex < 0)
-                break;
-
-            sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
+        if (global && callType == CallTypeJS) {
+            // reg->numSubpatterns() + 1 for pattern args, + 2 for match start and sourceValue
+            int argCount = reg->numSubpatterns() + 1 + 2;
+            JSFunction* func = asFunction(replacement);
+            CachedCall cachedCall(exec, func, argCount, exec->exceptionSlot());
+            if (exec->hadException())
+                return jsNull();
+            while (true) {
+                int matchIndex;
+                int matchLen;
+                int* ovector;
+                regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
+                if (matchIndex < 0)
+                    break;
+                
+                sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
 
-            if (callType != CallTypeNone) {
                 int completeMatchStart = ovector[0];
-                ArgList args;
-
-                for (unsigned i = 0; i < reg->numSubpatterns() + 1; ++i) {
+                unsigned i = 0;
+                for (; i < reg->numSubpatterns() + 1; ++i) {
                     int matchStart = ovector[i * 2];
                     int matchLen = ovector[i * 2 + 1] - matchStart;
 
                     if (matchStart < 0)
-                        args.append(jsUndefined());
+                        cachedCall.setArgument(i, jsUndefined());
                     else
-                        args.append(jsSubstring(exec, source, matchStart, matchLen));
+                        cachedCall.setArgument(i, jsSubstring(exec, source, matchStart, matchLen));
                 }
 
-                args.append(jsNumber(exec, completeMatchStart));
-                args.append(sourceVal);
-
-                replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec));
+                cachedCall.setArgument(i++, jsNumber(exec, completeMatchStart));
+                cachedCall.setArgument(i++, sourceVal);
+                
+                cachedCall.setThis(exec->globalThisValue());
+                replacements.append(cachedCall.call().toString(cachedCall.newCallFrame()));
                 if (exec->hadException())
                     break;
-            } else
-                replacements.append(substituteBackreferences(replacementString, source, ovector, reg));
 
-            lastIndex = matchIndex + matchLen;
-            startPosition = lastIndex;
+                lastIndex = matchIndex + matchLen;
+                startPosition = lastIndex;
 
-            // special case of empty match
-            if (matchLen == 0) {
-                startPosition++;
-                if (startPosition > source.size())
+                // special case of empty match
+                if (matchLen == 0) {
+                    startPosition++;
+                    if (startPosition > source.size())
+                        break;
+                }
+            }            
+        } else {
+            do {
+                int matchIndex;
+                int matchLen;
+                int* ovector;
+                regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
+                if (matchIndex < 0)
                     break;
-            }
-        } while (global);
 
-        if (lastIndex < source.size())
-            sourceRanges.append(UString::Range(lastIndex, source.size() - lastIndex));
+                sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
+
+                if (callType != CallTypeNone) {
+                    int completeMatchStart = ovector[0];
+                    MarkedArgumentBuffer args;
+
+                    for (unsigned i = 0; i < reg->numSubpatterns() + 1; ++i) {
+                        int matchStart = ovector[i * 2];
+                        int matchLen = ovector[i * 2 + 1] - matchStart;
+
+                        if (matchStart < 0)
+                            args.append(jsUndefined());
+                        else
+                            args.append(jsSubstring(exec, source, matchStart, matchLen));
+                    }
 
-        UString result = source.spliceSubstringsWithSeparators(sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size());
+                    args.append(jsNumber(exec, completeMatchStart));
+                    args.append(sourceVal);
 
-        if (result == source)
+                    replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec));
+                    if (exec->hadException())
+                        break;
+                } else
+                    replacements.append(substituteBackreferences(replacementString, source, ovector, reg));
+
+                lastIndex = matchIndex + matchLen;
+                startPosition = lastIndex;
+
+                // special case of empty match
+                if (matchLen == 0) {
+                    startPosition++;
+                    if (startPosition > source.size())
+                        break;
+                }
+            } while (global);
+        }
+
+        if (!lastIndex && replacements.isEmpty())
             return sourceVal;
 
-        return jsString(exec, result);
+        if (lastIndex < source.size())
+            sourceRanges.append(UString::Range(lastIndex, source.size() - lastIndex));
+
+        return jsString(exec, source.spliceSubstringsWithSeparators(sourceRanges.data(), sourceRanges.size(),
+            replacements.data(), replacements.size()));
     }
 
-    // First arg is a string
+    // Not a regular expression, so treat the pattern as a string.
+
     UString patternString = pattern.toString(exec);
     int matchPos = source.find(patternString);
-    int matchLen = patternString.size();
-    // Do the replacement
+
     if (matchPos == -1)
         return sourceVal;
 
+    int matchLen = patternString.size();
     if (callType != CallTypeNone) {
-        ArgList args;
+        MarkedArgumentBuffer args;
         args.append(jsSubstring(exec, source, matchPos, matchLen));
         args.append(jsNumber(exec, matchPos));
         args.append(sourceVal);
@@ -304,12 +355,10 @@ JSValuePtr stringProtoFuncReplace(ExecState* exec, JSObject*, JSValuePtr thisVal
     }
 
     int ovector[2] = { matchPos, matchPos + matchLen };
-    return jsString(exec, source.substr(0, matchPos)
-        + substituteBackreferences(replacementString, source, ovector, 0)
-        + source.substr(matchPos + matchLen));
+    return jsString(exec, source.replaceRange(matchPos, matchLen, substituteBackreferences(replacementString, source, ovector, 0)));
 }
 
-JSValuePtr stringProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     // Also used for valueOf.
 
@@ -322,13 +371,13 @@ JSValuePtr stringProtoFuncToString(ExecState* exec, JSObject*, JSValuePtr thisVa
     return throwError(exec, TypeError);
 }
 
-JSValuePtr stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     unsigned len = s.size();
-    JSValuePtr a0 = args.at(exec, 0);
-    if (a0.isUInt32Fast()) {
-        uint32_t i = a0.getUInt32Fast();
+    JSValue a0 = args.at(0);
+    if (a0.isUInt32()) {
+        uint32_t i = a0.asUInt32();
         if (i < len)
             return jsSingleCharacterSubstring(exec, s, i);
         return jsEmptyString(exec);
@@ -339,13 +388,13 @@ JSValuePtr stringProtoFuncCharAt(ExecState* exec, JSObject*, JSValuePtr thisValu
     return jsEmptyString(exec);
 }
 
-JSValuePtr stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     unsigned len = s.size();
-    JSValuePtr a0 = args.at(exec, 0);
-    if (a0.isUInt32Fast()) {
-        uint32_t i = a0.getUInt32Fast();
+    JSValue a0 = args.at(0);
+    if (a0.isUInt32()) {
+        uint32_t i = a0.asUInt32();
         if (i < len)
             return jsNumber(exec, s.data()[i]);
         return jsNaN(exec);
@@ -356,29 +405,29 @@ JSValuePtr stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSValuePtr this
     return jsNaN(exec);
 }
 
-JSValuePtr stringProtoFuncConcat(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
 
     ArgList::const_iterator end = args.end();
     for (ArgList::const_iterator it = args.begin(); it != end; ++it)
-        s += (*it).jsValue(exec).toString(exec);
+        s += (*it).toString(exec);
     return jsString(exec, s);
 }
 
-JSValuePtr stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     int len = s.size();
 
-    JSValuePtr a0 = args.at(exec, 0);
-    JSValuePtr a1 = args.at(exec, 1);
+    JSValue a0 = args.at(0);
+    JSValue a1 = args.at(1);
     UString u2 = a0.toString(exec);
     int pos;
     if (a1.isUndefined())
         pos = 0;
-    else if (a1.isUInt32Fast())
-        pos = min<uint32_t>(a1.getUInt32Fast(), len);
+    else if (a1.isUInt32())
+        pos = min<uint32_t>(a1.asUInt32(), len);
     else {
         double dpos = a1.toInteger(exec);
         if (dpos < 0)
@@ -391,13 +440,13 @@ JSValuePtr stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisVal
     return jsNumber(exec, s.find(u2, pos));
 }
 
-JSValuePtr stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     int len = s.size();
 
-    JSValuePtr a0 = args.at(exec, 0);
-    JSValuePtr a1 = args.at(exec, 1);
+    JSValue a0 = args.at(0);
+    JSValue a1 = args.at(1);
 
     UString u2 = a0.toString(exec);
     double dpos = a1.toIntegerPreserveNaN(exec);
@@ -408,11 +457,11 @@ JSValuePtr stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValuePtr thi
     return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
 }
 
-JSValuePtr stringProtoFuncMatch(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
 
-    JSValuePtr a0 = args.at(exec, 0);
+    JSValue a0 = args.at(0);
 
     UString u = s;
     RefPtr<RegExp> reg;
@@ -439,7 +488,7 @@ JSValuePtr stringProtoFuncMatch(ExecState* exec, JSObject*, JSValuePtr thisValue
     }
 
     // return array of matches
-    ArgList list;
+    MarkedArgumentBuffer list;
     int lastIndex = 0;
     while (pos >= 0) {
         list.append(jsSubstring(exec, u, pos, matchLength));
@@ -459,11 +508,11 @@ JSValuePtr stringProtoFuncMatch(ExecState* exec, JSObject*, JSValuePtr thisValue
     return constructArray(exec, list);
 }
 
-JSValuePtr stringProtoFuncSearch(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
 
-    JSValuePtr a0 = args.at(exec, 0);
+    JSValue a0 = args.at(0);
 
     UString u = s;
     RefPtr<RegExp> reg;
@@ -484,13 +533,13 @@ JSValuePtr stringProtoFuncSearch(ExecState* exec, JSObject*, JSValuePtr thisValu
     return jsNumber(exec, pos);
 }
 
-JSValuePtr stringProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     int len = s.size();
 
-    JSValuePtr a0 = args.at(exec, 0);
-    JSValuePtr a1 = args.at(exec, 1);
+    JSValue a0 = args.at(0);
+    JSValue a1 = args.at(1);
 
     // The arg processing is very much like ArrayProtoFunc::Slice
     double start = a0.toInteger(exec);
@@ -508,12 +557,12 @@ JSValuePtr stringProtoFuncSlice(ExecState* exec, JSObject*, JSValuePtr thisValue
     return jsEmptyString(exec);
 }
 
-JSValuePtr stringProtoFuncSplit(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
 
-    JSValuePtr a0 = args.at(exec, 0);
-    JSValuePtr a1 = args.at(exec, 1);
+    JSValue a0 = args.at(0);
+    JSValue a1 = args.at(1);
 
     JSArray* result = constructEmptyArray(exec);
     unsigned i = 0;
@@ -527,7 +576,7 @@ JSValuePtr stringProtoFuncSplit(ExecState* exec, JSObject*, JSValuePtr thisValue
         }
         int pos = 0;
         while (i != limit && pos < s.size()) {
-            OwnArrayPtr<int> ovector;
+            Vector<int, 32> ovector;
             int mpos = reg->match(s, pos, &ovector);
             if (mpos < 0)
                 break;
@@ -570,13 +619,13 @@ JSValuePtr stringProtoFuncSplit(ExecState* exec, JSObject*, JSValuePtr thisValue
     return result;
 }
 
-JSValuePtr stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     int len = s.size();
 
-    JSValuePtr a0 = args.at(exec, 0);
-    JSValuePtr a1 = args.at(exec, 1);
+    JSValue a0 = args.at(0);
+    JSValue a1 = args.at(1);
 
     double start = a0.toInteger(exec);
     double length = a1.isUndefined() ? len : a1.toInteger(exec);
@@ -592,13 +641,13 @@ JSValuePtr stringProtoFuncSubstr(ExecState* exec, JSObject*, JSValuePtr thisValu
     return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(length));
 }
 
-JSValuePtr stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     int len = s.size();
 
-    JSValuePtr a0 = args.at(exec, 0);
-    JSValuePtr a1 = args.at(exec, 1);
+    JSValue a0 = args.at(0);
+    JSValue a1 = args.at(1);
 
     double start = a0.toNumber(exec);
     double end = a1.toNumber(exec);
@@ -624,7 +673,7 @@ JSValuePtr stringProtoFuncSubstring(ExecState* exec, JSObject*, JSValuePtr thisV
     return jsSubstring(exec, s, static_cast<unsigned>(start), static_cast<unsigned>(end) - static_cast<unsigned>(start));
 }
 
-JSValuePtr stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     JSString* sVal = thisValue.toThisJSString(exec);
     const UString& s = sVal->value();
@@ -658,7 +707,7 @@ JSValuePtr stringProtoFuncToLowerCase(ExecState* exec, JSObject*, JSValuePtr thi
     return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
-JSValuePtr stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     JSString* sVal = thisValue.toThisJSString(exec);
     const UString& s = sVal->value();
@@ -692,81 +741,81 @@ JSValuePtr stringProtoFuncToUpperCase(ExecState* exec, JSObject*, JSValuePtr thi
     return jsString(exec, UString(buffer.releaseBuffer(), length, false));
 }
 
-JSValuePtr stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     if (args.size() < 1)
       return jsNumber(exec, 0);
 
     UString s = thisValue.toThisString(exec);
-    JSValuePtr a0 = args.at(exec, 0);
+    JSValue a0 = args.at(0);
     return jsNumber(exec, localeCompare(s, a0.toString(exec)));
 }
 
-JSValuePtr stringProtoFuncBig(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
     return jsNontrivialString(exec, "<big>" + s + "</big>");
 }
 
-JSValuePtr stringProtoFuncSmall(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
     return jsNontrivialString(exec, "<small>" + s + "</small>");
 }
 
-JSValuePtr stringProtoFuncBlink(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
     return jsNontrivialString(exec, "<blink>" + s + "</blink>");
 }
 
-JSValuePtr stringProtoFuncBold(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
     return jsNontrivialString(exec, "<b>" + s + "</b>");
 }
 
-JSValuePtr stringProtoFuncFixed(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
     return jsString(exec, "<tt>" + s + "</tt>");
 }
 
-JSValuePtr stringProtoFuncItalics(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
     return jsNontrivialString(exec, "<i>" + s + "</i>");
 }
 
-JSValuePtr stringProtoFuncStrike(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
     return jsNontrivialString(exec, "<strike>" + s + "</strike>");
 }
 
-JSValuePtr stringProtoFuncSub(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
     return jsNontrivialString(exec, "<sub>" + s + "</sub>");
 }
 
-JSValuePtr stringProtoFuncSup(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList&)
+JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
     return jsNontrivialString(exec, "<sup>" + s + "</sup>");
 }
 
-JSValuePtr stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
-    JSValuePtr a0 = args.at(exec, 0);
+    JSValue a0 = args.at(0);
     return jsNontrivialString(exec, "<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");
 }
 
-JSValuePtr stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
-    JSValuePtr a0 = args.at(exec, 0);
+    JSValue a0 = args.at(0);
 
     uint32_t smallInteger;
     if (a0.getUInt32(smallInteger) && smallInteger <= 9) {
@@ -804,17 +853,17 @@ JSValuePtr stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValuePtr thisVa
     return jsNontrivialString(exec, "<font size=\"" + a0.toString(exec) + "\">" + s + "</font>");
 }
 
-JSValuePtr stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
-    JSValuePtr a0 = args.at(exec, 0);
+    JSValue a0 = args.at(0);
     return jsNontrivialString(exec, "<a name=\"" + a0.toString(exec) + "\">" + s + "</a>");
 }
 
-JSValuePtr stringProtoFuncLink(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
+JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
-    JSValuePtr a0 = args.at(exec, 0);
+    JSValue a0 = args.at(0);
     UString linkText = a0.toString(exec);
 
     unsigned linkTextSize = linkText.size();
index 8133cd2e0c0c48f8e3586d682e3b0fdadd9f12ca..3b078365ecaef0078e5536d16d08f8818e736bf6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -65,17 +65,19 @@ static const unsigned newTableSize = 16;
 static WTF::RefCountedLeakCounter structureCounter("Structure");
 
 #if ENABLE(JSC_MULTIPLE_THREADS)
-static Mutex ignoreSetMutex;
+static Mutex& ignoreSetMutex = *(new Mutex);
 #endif
 
 static bool shouldIgnoreLeaks;
-static HashSet<Structure*> ignoreSet;
+static HashSet<Structure*>& ignoreSet = *(new HashSet<Structure*>);
 #endif
 
 #if DUMP_STRUCTURE_ID_STATISTICS
-static HashSet<Structure*> liveStructureSet;
+static HashSet<Structure*>& liveStructureSet = *(new HashSet<Structure*>);
 #endif
 
+static int comparePropertyMapEntryIndices(const void* a, const void* b);
+
 void Structure::dumpStatistics()
 {
 #if DUMP_STRUCTURE_ID_STATISTICS
@@ -120,13 +122,14 @@ void Structure::dumpStatistics()
 #endif
 }
 
-Structure::Structure(JSValuePtr prototype, const TypeInfo& typeInfo)
+Structure::Structure(JSValue prototype, const TypeInfo& typeInfo)
     : m_typeInfo(typeInfo)
     , m_prototype(prototype)
+    , m_specificValueInPrevious(0)
     , m_propertyTable(0)
     , m_propertyStorageCapacity(JSObject::inlineStorageCapacity)
     , m_offset(noOffset)
-    , m_isDictionary(false)
+    , m_dictionaryKind(NoneDictionaryKind)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(false)
     , m_usingSingleTransitionSlot(true)
@@ -158,8 +161,8 @@ Structure::~Structure()
         if (m_previous->m_usingSingleTransitionSlot) {
             m_previous->m_transitions.singleTransition = 0;
         } else {
-            ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), m_attributesInPrevious)));
-            m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious));
+            ASSERT(m_previous->m_transitions.table->contains(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious));
+            m_previous->m_transitions.table->remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious);
         }
     }
 
@@ -279,14 +282,14 @@ void Structure::materializePropertyMap()
     for (ptrdiff_t i = structures.size() - 2; i >= 0; --i) {
         structure = structures[i];
         structure->m_nameInPrevious->ref();
-        PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, ++m_propertyTable->lastIndexUsed); 
+        PropertyMapEntry entry(structure->m_nameInPrevious.get(), structure->m_offset, structure->m_attributesInPrevious, structure->m_specificValueInPrevious, ++m_propertyTable->lastIndexUsed);
         insertIntoPropertyMapHashTable(entry);
     }
 }
 
 void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& propertyNames, JSObject* baseObject)
 {
-    bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || m_isDictionary);
+    bool shouldCache = propertyNames.shouldCache() && !(propertyNames.size() || isDictionary());
 
     if (shouldCache && m_cachedPropertyNameArrayData) {
         if (m_cachedPropertyNameArrayData->cachedPrototypeChain() == prototypeChain(exec)) {
@@ -305,8 +308,11 @@ void Structure::getEnumerablePropertyNames(ExecState* exec, PropertyNameArray& p
     }
 
     if (shouldCache) {
+        StructureChain* protoChain = prototypeChain(exec);
         m_cachedPropertyNameArrayData = propertyNames.data();
-        m_cachedPropertyNameArrayData->setCachedPrototypeChain(prototypeChain(exec));
+        if (!protoChain->isCacheable())
+            return;
+        m_cachedPropertyNameArrayData->setCachedPrototypeChain(protoChain);
         m_cachedPropertyNameArrayData->setCachedStructure(this);
     }
 }
@@ -326,20 +332,69 @@ void Structure::growPropertyStorageCapacity()
         m_propertyStorageCapacity *= 2;
 }
 
-PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)
+void Structure::despecifyDictionaryFunction(const Identifier& propertyName)
+{
+    const UString::Rep* rep = propertyName._ustring.rep();
+
+    materializePropertyMapIfNecessary();
+
+    ASSERT(isDictionary());
+    ASSERT(m_propertyTable);
+
+    unsigned i = rep->computedHash();
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numProbes;
+#endif
+
+    unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+    ASSERT(entryIndex != emptyEntryIndex);
+
+    if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+        m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
+        return;
+    }
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numCollisions;
+#endif
+
+    unsigned k = 1 | doubleHash(rep->computedHash());
+
+    while (1) {
+        i += k;
+
+#if DUMP_PROPERTYMAP_STATS
+        ++numRehashes;
+#endif
+
+        entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+        ASSERT(entryIndex != emptyEntryIndex);
+
+        if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+            m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
+            return;
+        }
+    }
+}
+
+PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
 {
-    ASSERT(!structure->m_isDictionary);
+    ASSERT(!structure->isDictionary());
     ASSERT(structure->typeInfo().type() == ObjectType);
 
     if (structure->m_usingSingleTransitionSlot) {
         Structure* existingTransition = structure->m_transitions.singleTransition;
-        if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep() && existingTransition->m_attributesInPrevious == attributes) {
+        if (existingTransition && existingTransition->m_nameInPrevious.get() == propertyName.ustring().rep()
+            && existingTransition->m_attributesInPrevious == attributes
+            && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0)) {
+
             ASSERT(structure->m_transitions.singleTransition->m_offset != noOffset);
             offset = structure->m_transitions.singleTransition->m_offset;
             return existingTransition;
         }
     } else {
-        if (Structure* existingTransition = structure->m_transitions.table->get(make_pair(propertyName.ustring().rep(), attributes))) {
+        if (Structure* existingTransition = structure->m_transitions.table->get(make_pair(propertyName.ustring().rep(), attributes), specificValue)) {
             ASSERT(existingTransition->m_offset != noOffset);
             offset = existingTransition->m_offset;
             return existingTransition;
@@ -349,25 +404,28 @@ PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Struct
     return 0;
 }
 
-PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, size_t& offset)
+PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset)
 {
-    ASSERT(!structure->m_isDictionary);
+    ASSERT(!structure->isDictionary());
     ASSERT(structure->typeInfo().type() == ObjectType);
-    ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, offset));
+    ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
 
     if (structure->transitionCount() > s_maxTransitionLength) {
-        RefPtr<Structure> transition = toDictionaryTransition(structure);
-        offset = transition->put(propertyName, attributes);
+        RefPtr<Structure> transition = toCacheableDictionaryTransition(structure);
+        ASSERT(structure != transition);
+        offset = transition->put(propertyName, attributes, specificValue);
         if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
             transition->growPropertyStorageCapacity();
         return transition.release();
     }
 
     RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
+
     transition->m_cachedPrototypeChain = structure->m_cachedPrototypeChain;
     transition->m_previous = structure;
     transition->m_nameInPrevious = propertyName.ustring().rep();
     transition->m_attributesInPrevious = attributes;
+    transition->m_specificValueInPrevious = specificValue;
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
 
@@ -385,7 +443,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
             transition->createPropertyMapHashTable();
     }
 
-    offset = transition->put(propertyName, attributes);
+    offset = transition->put(propertyName, attributes, specificValue);
     if (transition->propertyStorageSize() > transition->propertyStorageCapacity())
         transition->growPropertyStorageCapacity();
 
@@ -401,24 +459,24 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
         structure->m_usingSingleTransitionSlot = false;
         StructureTransitionTable* transitionTable = new StructureTransitionTable;
         structure->m_transitions.table = transitionTable;
-        transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition);
+        transitionTable->add(make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious);
     }
-    structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get());
+    structure->m_transitions.table->add(make_pair(propertyName.ustring().rep(), attributes), transition.get(), specificValue);
     return transition.release();
 }
 
 PassRefPtr<Structure> Structure::removePropertyTransition(Structure* structure, const Identifier& propertyName, size_t& offset)
 {
-    ASSERT(!structure->m_isDictionary);
+    ASSERT(!structure->isUncacheableDictionary());
 
-    RefPtr<Structure> transition = toDictionaryTransition(structure);
+    RefPtr<Structure> transition = toUncacheableDictionaryTransition(structure);
 
     offset = transition->remove(propertyName);
 
     return transition.release();
 }
 
-PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, JSValuePtr prototype)
+PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure, JSValue prototype)
 {
     RefPtr<Structure> transition = create(prototype, structure->typeInfo());
 
@@ -434,6 +492,25 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure,
     return transition.release();
 }
 
+PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structure, const Identifier& replaceFunction)
+{
+    RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
+
+    transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
+    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
+
+    // Don't set m_offset, as one can not transition to this.
+
+    structure->materializePropertyMapIfNecessary();
+    transition->m_propertyTable = structure->copyPropertyTable();
+    transition->m_isPinnedPropertyTable = true;
+
+    bool removed = transition->despecifyFunction(replaceFunction);
+    ASSERT_UNUSED(removed, removed);
+
+    return transition.release();
+}
+
 PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
 {
     RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
@@ -449,46 +526,84 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
     return transition.release();
 }
 
-PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure)
+PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, DictionaryKind kind)
 {
-    ASSERT(!structure->m_isDictionary);
-
+    ASSERT(!structure->isUncacheableDictionary());
+    
     RefPtr<Structure> transition = create(structure->m_prototype, structure->typeInfo());
-    transition->m_isDictionary = true;
+    transition->m_dictionaryKind = kind;
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
-
+    
     structure->materializePropertyMapIfNecessary();
     transition->m_propertyTable = structure->copyPropertyTable();
     transition->m_isPinnedPropertyTable = true;
-
+    
     return transition.release();
 }
 
-PassRefPtr<Structure> Structure::fromDictionaryTransition(Structure* structure)
+PassRefPtr<Structure> Structure::toCacheableDictionaryTransition(Structure* structure)
 {
-    ASSERT(structure->m_isDictionary);
+    return toDictionaryTransition(structure, CachedDictionaryKind);
+}
 
-    // Since dictionary Structures are not shared, and no opcodes specialize
-    // for them, we don't need to allocate a new Structure when transitioning
-    // to non-dictionary status.
+PassRefPtr<Structure> Structure::toUncacheableDictionaryTransition(Structure* structure)
+{
+    return toDictionaryTransition(structure, UncachedDictionaryKind);
+}
 
-    // FIMXE: We can make this more efficient by canonicalizing the Structure (draining the
-    // deleted offsets vector) before transitioning from dictionary. 
-    if (!structure->m_propertyTable || !structure->m_propertyTable->deletedOffsets || structure->m_propertyTable->deletedOffsets->isEmpty())
-        structure->m_isDictionary = false;
+PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSObject* object)
+{
+    ASSERT(isDictionary());
+    if (isUncacheableDictionary()) {
+        ASSERT(m_propertyTable);
+        Vector<PropertyMapEntry*> sortedPropertyEntries(m_propertyTable->keyCount);
+        PropertyMapEntry** p = sortedPropertyEntries.data();
+        unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+        for (unsigned i = 1; i <= entryCount; i++) {
+            if (m_propertyTable->entries()[i].key)
+                *p++ = &m_propertyTable->entries()[i];
+        }
+        size_t propertyCount = p - sortedPropertyEntries.data();
+        qsort(sortedPropertyEntries.data(), propertyCount, sizeof(PropertyMapEntry*), comparePropertyMapEntryIndices);
+        sortedPropertyEntries.resize(propertyCount);
+
+        // We now have the properties currently defined on this object
+        // in the order that they are expected to be in, but we need to
+        // reorder the storage, so we have to copy the current values out
+        Vector<JSValue> values(propertyCount);
+        // FIXME: Remove this workaround with the next merge.
+        unsigned anonymousSlotCount = 0;
+        for (unsigned i = 0; i < propertyCount; i++) {
+            PropertyMapEntry* entry = sortedPropertyEntries[i];
+            values[i] = object->getDirectOffset(entry->offset);
+            // Update property table to have the new property offsets
+            entry->offset = anonymousSlotCount + i;
+            entry->index = i;
+        }
+        
+        // Copy the original property values into their final locations
+        for (unsigned i = 0; i < propertyCount; i++)
+            object->putDirectOffset(anonymousSlotCount + i, values[i]);
+
+        if (m_propertyTable->deletedOffsets) {
+            delete m_propertyTable->deletedOffsets;
+            m_propertyTable->deletedOffsets = 0;
+        }
+    }
 
-    return structure;
+    m_dictionaryKind = NoneDictionaryKind;
+    return this;
 }
 
-size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes)
+size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
 {
     ASSERT(!m_transitions.singleTransition);
 
     materializePropertyMapIfNecessary();
 
     m_isPinnedPropertyTable = true;
-    size_t offset = put(propertyName, attributes);
+    size_t offset = put(propertyName, attributes, specificValue);
     if (propertyStorageSize() > propertyStorageCapacity())
         growPropertyStorageCapacity();
     clearEnumerationCache();
@@ -497,8 +612,7 @@ size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, u
 
 size_t Structure::removePropertyWithoutTransition(const Identifier& propertyName)
 {
-    ASSERT(!m_transitions.singleTransition);
-    ASSERT(m_isDictionary);
+    ASSERT(isUncacheableDictionary());
 
     materializePropertyMapIfNecessary();
 
@@ -564,16 +678,12 @@ PropertyMapHashTable* Structure::copyPropertyTable()
     return newTable;
 }
 
-size_t Structure::get(const Identifier& propertyName, unsigned& attributes)
+size_t Structure::get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue)
 {
-    ASSERT(!propertyName.isNull());
-
     materializePropertyMapIfNecessary();
     if (!m_propertyTable)
         return notFound;
 
-    UString::Rep* rep = propertyName._ustring.rep();
-
     unsigned i = rep->computedHash();
 
 #if DUMP_PROPERTYMAP_STATS
@@ -586,6 +696,7 @@ size_t Structure::get(const Identifier& propertyName, unsigned& attributes)
 
     if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
         attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
+        specificValue = m_propertyTable->entries()[entryIndex - 1].specificValue;
         return m_propertyTable->entries()[entryIndex - 1].offset;
     }
 
@@ -608,12 +719,64 @@ size_t Structure::get(const Identifier& propertyName, unsigned& attributes)
 
         if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
             attributes = m_propertyTable->entries()[entryIndex - 1].attributes;
+            specificValue = m_propertyTable->entries()[entryIndex - 1].specificValue;
             return m_propertyTable->entries()[entryIndex - 1].offset;
         }
     }
 }
 
-size_t Structure::put(const Identifier& propertyName, unsigned attributes)
+bool Structure::despecifyFunction(const Identifier& propertyName)
+{
+    ASSERT(!propertyName.isNull());
+
+    materializePropertyMapIfNecessary();
+    if (!m_propertyTable)
+        return false;
+
+    UString::Rep* rep = propertyName._ustring.rep();
+
+    unsigned i = rep->computedHash();
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numProbes;
+#endif
+
+    unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+    if (entryIndex == emptyEntryIndex)
+        return false;
+
+    if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+        ASSERT(m_propertyTable->entries()[entryIndex - 1].specificValue);
+        m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
+        return true;
+    }
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numCollisions;
+#endif
+
+    unsigned k = 1 | doubleHash(rep->computedHash());
+
+    while (1) {
+        i += k;
+
+#if DUMP_PROPERTYMAP_STATS
+        ++numRehashes;
+#endif
+
+        entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask];
+        if (entryIndex == emptyEntryIndex)
+            return false;
+
+        if (rep == m_propertyTable->entries()[entryIndex - 1].key) {
+            ASSERT(m_propertyTable->entries()[entryIndex - 1].specificValue);
+            m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
+            return true;
+        }
+    }
+}
+
+size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
 {
     ASSERT(!propertyName.isNull());
     ASSERT(get(propertyName) == notFound);
@@ -683,6 +846,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes)
     rep->ref();
     m_propertyTable->entries()[entryIndex - 1].key = rep;
     m_propertyTable->entries()[entryIndex - 1].attributes = attributes;
+    m_propertyTable->entries()[entryIndex - 1].specificValue = specificValue;
     m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed;
 
     unsigned newOffset;
@@ -702,6 +866,16 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes)
     return newOffset;
 }
 
+bool Structure::hasTransition(UString::Rep* rep, unsigned attributes)
+{
+    if (m_usingSingleTransitionSlot) {
+        return m_transitions.singleTransition
+            && m_transitions.singleTransition->m_nameInPrevious == rep
+            && m_transitions.singleTransition->m_attributesInPrevious == attributes;
+    }
+    return m_transitions.table->hasTransition(make_pair(rep, attributes));
+}
+
 size_t Structure::remove(const Identifier& propertyName)
 {
     ASSERT(!propertyName.isNull());
@@ -755,6 +929,7 @@ size_t Structure::remove(const Identifier& propertyName)
     key->deref();
     m_propertyTable->entries()[entryIndex - 1].key = 0;
     m_propertyTable->entries()[entryIndex - 1].attributes = 0;
+    m_propertyTable->entries()[entryIndex - 1].specificValue = 0;
     m_propertyTable->entries()[entryIndex - 1].offset = 0;
 
     if (!m_propertyTable->deletedOffsets)
@@ -871,7 +1046,7 @@ void Structure::rehashPropertyMapHashTable(unsigned newTableSize)
     checkConsistency();
 }
 
-static int comparePropertyMapEntryIndices(const void* a, const void* b)
+int comparePropertyMapEntryIndices(const void* a, const void* b)
 {
     unsigned ia = static_cast<PropertyMapEntry* const*>(a)[0]->index;
     unsigned ib = static_cast<PropertyMapEntry* const*>(b)[0]->index;
@@ -948,11 +1123,8 @@ void Structure::getEnumerableNamesFromClassInfoTable(ExecState* exec, const Clas
             continue;
         table->initializeIfNeeded(exec);
         ASSERT(table->table);
-#if ENABLE(PERFECT_HASH_SIZE)
-        int hashSizeMask = table->hashSizeMask;
-#else
+
         int hashSizeMask = table->compactSize - 1;
-#endif
         const HashEntry* entry = table->table;
         for (int i = 0; i <= hashSizeMask; ++i, ++entry) {
             if (entry->key() && !(entry->attributes() & DontEnum))
index ea17c246167a2e171afe00be964a8e023daa404a..55b7186089dc7b2c6ddc1ef0a1aa71c11c4cdbcd 100644 (file)
@@ -51,7 +51,7 @@ namespace JSC {
     class Structure : public RefCounted<Structure> {
     public:
         friend class JIT;
-        static PassRefPtr<Structure> create(JSValuePtr prototype, const TypeInfo& typeInfo)
+        static PassRefPtr<Structure> create(JSValue prototype, const TypeInfo& typeInfo)
         {
             return adoptRef(new Structure(prototype, typeInfo));
         }
@@ -61,13 +61,16 @@ namespace JSC {
 
         static void dumpStatistics();
 
-        static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, size_t& offset);
-        static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, size_t& offset);
+        static PassRefPtr<Structure> addPropertyTransition(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
+        static PassRefPtr<Structure> addPropertyTransitionToExistingStructure(Structure*, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset);
         static PassRefPtr<Structure> removePropertyTransition(Structure*, const Identifier& propertyName, size_t& offset);
-        static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValuePtr prototype);
+        static PassRefPtr<Structure> changePrototypeTransition(Structure*, JSValue prototype);
+        static PassRefPtr<Structure> despecifyFunctionTransition(Structure*, const Identifier&);        
         static PassRefPtr<Structure> getterSetterTransition(Structure*);
-        static PassRefPtr<Structure> toDictionaryTransition(Structure*);
-        static PassRefPtr<Structure> fromDictionaryTransition(Structure*);
+        static PassRefPtr<Structure> toCacheableDictionaryTransition(Structure*);
+        static PassRefPtr<Structure> toUncacheableDictionaryTransition(Structure*);
+
+        PassRefPtr<Structure> flattenDictionaryStructure(JSObject*);
 
         ~Structure();
 
@@ -78,16 +81,17 @@ namespace JSC {
         }
 
         // These should be used with caution.  
-        size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes);
+        size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
         size_t removePropertyWithoutTransition(const Identifier& propertyName);
-        void setPrototypeWithoutTransition(JSValuePtr prototype) { m_prototype = prototype; }
-
-        bool isDictionary() const { return m_isDictionary; }
+        void setPrototypeWithoutTransition(JSValue prototype) { m_prototype = prototype; }
+        
+        bool isDictionary() const { return m_dictionaryKind != NoneDictionaryKind; }
+        bool isUncacheableDictionary() const { return m_dictionaryKind == UncachedDictionaryKind; }
 
         const TypeInfo& typeInfo() const { return m_typeInfo; }
 
-        JSValuePtr storedPrototype() const { return m_prototype; }
-        JSValuePtr prototypeForLookup(ExecState*) const;
+        JSValue storedPrototype() const { return m_prototype; }
+        JSValue prototypeForLookup(ExecState*) const;
         StructureChain* prototypeChain(ExecState*) const;
 
         Structure* previousID() const { return m_previous.get(); }
@@ -95,9 +99,25 @@ namespace JSC {
         void growPropertyStorageCapacity();
         size_t propertyStorageCapacity() const { return m_propertyStorageCapacity; }
         size_t propertyStorageSize() const { return m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1; }
+        bool isUsingInlineStorage() const;
 
         size_t get(const Identifier& propertyName);
-        size_t get(const Identifier& propertyName, unsigned& attributes);
+        size_t get(const UString::Rep* rep, unsigned& attributes, JSCell*& specificValue);
+        size_t get(const Identifier& propertyName, unsigned& attributes, JSCell*& specificValue)
+        {
+            ASSERT(!propertyName.isNull());
+            return get(propertyName.ustring().rep(), attributes, specificValue);
+        }
+        bool transitionedFor(const JSCell* specificValue)
+        {
+            return m_specificValueInPrevious == specificValue;
+        }
+        bool hasTransition(UString::Rep*, unsigned attributes);
+        bool hasTransition(const Identifier& propertyName, unsigned attributes)
+        {
+            return hasTransition(propertyName._ustring.rep(), attributes);
+        }
+
         void getEnumerablePropertyNames(ExecState*, PropertyNameArray&, JSObject*);
 
         bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; }
@@ -105,10 +125,20 @@ namespace JSC {
 
         bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; }
 
-    private:
-        Structure(JSValuePtr prototype, const TypeInfo&);
+        JSCell* specificValue() { return m_specificValueInPrevious; }
+        void despecifyDictionaryFunction(const Identifier& propertyName);
 
-        size_t put(const Identifier& propertyName, unsigned attributes);
+    private:
+        Structure(JSValue prototype, const TypeInfo&);
+        
+        typedef enum { 
+            NoneDictionaryKind = 0,
+            CachedDictionaryKind = 1,
+            UncachedDictionaryKind = 2
+        } DictionaryKind;
+        static PassRefPtr<Structure> toDictionaryTransition(Structure*, DictionaryKind);
+
+        size_t put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue);
         size_t remove(const Identifier& propertyName);
         void getEnumerableNamesFromPropertyTable(PropertyNameArray&);
         void getEnumerableNamesFromClassInfoTable(ExecState*, const ClassInfo*, PropertyNameArray&);
@@ -121,6 +151,8 @@ namespace JSC {
         void insertIntoPropertyMapHashTable(const PropertyMapEntry&);
         void checkConsistency();
 
+        bool despecifyFunction(const Identifier&);
+
         PropertyMapHashTable* copyPropertyTable();
         void materializePropertyMap();
         void materializePropertyMapIfNecessary()
@@ -132,11 +164,6 @@ namespace JSC {
 
         void clearEnumerationCache();
 
-        void* addressOfCount()
-        {
-            return &m_refCount;
-        }
-
         signed char transitionCount() const
         {
             // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
@@ -153,11 +180,12 @@ namespace JSC {
 
         TypeInfo m_typeInfo;
 
-        JSValuePtr m_prototype;
+        JSValue m_prototype;
         mutable RefPtr<StructureChain> m_cachedPrototypeChain;
 
         RefPtr<Structure> m_previous;
         RefPtr<UString::Rep> m_nameInPrevious;
+        JSCell* m_specificValueInPrevious;
 
         union {
             Structure* singleTransition;
@@ -171,11 +199,11 @@ namespace JSC {
         size_t m_propertyStorageCapacity;
         signed char m_offset;
 
-        bool m_isDictionary : 1;
+        unsigned m_dictionaryKind : 2;
         bool m_isPinnedPropertyTable : 1;
         bool m_hasGetterSetterProperties : 1;
         bool m_usingSingleTransitionSlot : 1;
-        unsigned m_attributesInPrevious : 5;
+        unsigned m_attributesInPrevious : 7;
     };
 
     inline size_t Structure::get(const Identifier& propertyName)
@@ -222,7 +250,23 @@ namespace JSC {
                 return m_propertyTable->entries()[entryIndex - 1].offset;
         }
     }
+    
+    bool StructureTransitionTable::contains(const StructureTransitionTableHash::Key& key, JSCell* specificValue)
+    {
+        TransitionTable::iterator find = m_table.find(key);
+        if (find == m_table.end())
+            return false;
+
+        return find->second.first || find->second.second->transitionedFor(specificValue);
+    }
 
+    Structure* StructureTransitionTable::get(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const
+    {
+        Transition transition = m_table.get(key);
+        if (transition.second && transition.second->transitionedFor(specificValue))
+            return transition.second;
+        return transition.first;
+    }
 } // namespace JSC
 
 #endif // Structure_h
index 085876c496b54ea5d5f0a072b1f07fd88677e65d..e83f626ab1b134be7e397dcf73092d03ce573273 100644 (file)
@@ -46,4 +46,16 @@ StructureChain::StructureChain(Structure* head)
     m_vector[i] = 0;
 }
 
+bool StructureChain::isCacheable() const
+{
+    uint32_t i = 0;
+    
+    while (m_vector[i]) {
+        // Both classes of dictionary structure may change arbitrarily so we can't cache them
+        if (m_vector[i++]->isDictionary())
+            return false;
+    }
+    return true;
+}
+
 } // namespace JSC
index 795e6494a7b72cb716db3f247de203f7ad0f19a1..c48749d29be302f6733162ec4c972b2c4e5340b7 100644 (file)
@@ -39,6 +39,7 @@ namespace JSC {
     public:
         static PassRefPtr<StructureChain> create(Structure* head) { return adoptRef(new StructureChain(head)); }
         RefPtr<Structure>* head() { return m_vector.get(); }
+        bool isCacheable() const;
 
     private:
         StructureChain(Structure* head);
index 154304963a8cf12cc8d3d9d6d515f5c73680c9b0..5b4f4e63221b83043fd78e7cd167e723cdced22a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -54,7 +54,7 @@ namespace JSC {
     struct StructureTransitionTableHashTraits {
         typedef WTF::HashTraits<RefPtr<UString::Rep> > FirstTraits;
         typedef WTF::GenericHashTraits<unsigned> SecondTraits;
-        typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType> TraitType;
+        typedef std::pair<FirstTraits::TraitType, SecondTraits::TraitType > TraitType;
 
         static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero;
         static TraitType emptyValue() { return std::make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); }
@@ -65,7 +65,48 @@ namespace JSC {
         static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
     };
 
-    typedef HashMap<StructureTransitionTableHash::Key, Structure*, StructureTransitionTableHash, StructureTransitionTableHashTraits> StructureTransitionTable;
+    class StructureTransitionTable {
+        typedef std::pair<Structure*, Structure*> Transition;
+        typedef HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> TransitionTable;
+    public:
+        // The contains and get methods accept imprecise matches, so if an unspecialised transition exists
+        // for the given key they will consider that transition to be a match.  If a specialised transition
+        // exists and it matches the provided specificValue, get will return the specific transition.
+        inline bool contains(const StructureTransitionTableHash::Key&, JSCell* specificValue);
+        inline Structure* get(const StructureTransitionTableHash::Key&, JSCell* specificValue) const;
+        bool hasTransition(const StructureTransitionTableHash::Key& key)
+        {
+            return m_table.contains(key);
+        }
+        void remove(const StructureTransitionTableHash::Key& key, JSCell* specificValue)
+        {
+            TransitionTable::iterator find = m_table.find(key);
+            if (!specificValue)
+                find->second.first = 0;
+            else
+                find->second.second = 0;
+            if (!find->second.first && !find->second.second)
+                m_table.remove(find);
+        }
+        void add(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue)
+        {
+            if (!specificValue) {
+                TransitionTable::iterator find = m_table.find(key);
+                if (find == m_table.end())
+                    m_table.add(key, Transition(structure, 0));
+                else
+                    find->second.first = structure;
+            } else {
+                // If we're adding a transition to a specific value, then there cannot be
+                // an existing transition
+                ASSERT(!m_table.contains(key));
+                m_table.add(key, Transition(0, structure));
+            }
+
+        }
+    private:
+        TransitionTable m_table;
+    };
 
 } // namespace JSC
 
diff --git a/runtime/TimeoutChecker.cpp b/runtime/TimeoutChecker.cpp
new file mode 100644 (file)
index 0000000..75bf37f
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "TimeoutChecker.h"
+
+#include "CallFrame.h"
+#include "JSGlobalObject.h"
+
+#if PLATFORM(DARWIN)
+#include <mach/mach.h>
+#endif
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if PLATFORM(WIN_OS)
+#include <windows.h>
+#endif
+
+#if PLATFORM(QT)
+#include <QDateTime>
+#endif
+
+using namespace std;
+
+namespace JSC {
+
+// Number of ticks before the first timeout check is done.
+static const int ticksUntilFirstCheck = 1024;
+
+// Number of milliseconds between each timeout check.
+static const int intervalBetweenChecks = 1000;
+
+// Returns the time the current thread has spent executing, in milliseconds.
+static inline unsigned getCPUTime()
+{
+#if PLATFORM(DARWIN)
+    mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
+    thread_basic_info_data_t info;
+
+    // Get thread information
+    mach_port_t threadPort = mach_thread_self();
+    thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
+    mach_port_deallocate(mach_task_self(), threadPort);
+    
+    unsigned time = info.user_time.seconds * 1000 + info.user_time.microseconds / 1000;
+    time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
+    
+    return time;
+#elif HAVE(SYS_TIME_H)
+    // FIXME: This should probably use getrusage with the RUSAGE_THREAD flag.
+    struct timeval tv;
+    gettimeofday(&tv, 0);
+    return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+#elif PLATFORM(QT)
+    QDateTime t = QDateTime::currentDateTime();
+    return t.toTime_t() * 1000 + t.time().msec();
+#elif PLATFORM(WIN_OS)
+    union {
+        FILETIME fileTime;
+        unsigned long long fileTimeAsLong;
+    } userTime, kernelTime;
+    
+    // GetThreadTimes won't accept NULL arguments so we pass these even though
+    // they're not used.
+    FILETIME creationTime, exitTime;
+    
+    GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
+    
+    return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
+#else
+#error Platform does not have getCurrentTime function
+#endif
+}
+
+TimeoutChecker::TimeoutChecker()
+    : m_timeoutInterval(0)
+    , m_startCount(0)
+{
+    reset();
+}
+
+void TimeoutChecker::reset()
+{
+    m_ticksUntilNextCheck = ticksUntilFirstCheck;
+    m_timeAtLastCheck = 0;
+    m_timeExecuting = 0;
+}
+
+bool TimeoutChecker::didTimeOut(ExecState* exec)
+{
+    unsigned currentTime = getCPUTime();
+    
+    if (!m_timeAtLastCheck) {
+        // Suspicious amount of looping in a script -- start timing it
+        m_timeAtLastCheck = currentTime;
+        return false;
+    }
+    
+    unsigned timeDiff = currentTime - m_timeAtLastCheck;
+    
+    if (timeDiff == 0)
+        timeDiff = 1;
+    
+    m_timeExecuting += timeDiff;
+    m_timeAtLastCheck = currentTime;
+    
+    // Adjust the tick threshold so we get the next checkTimeout call in the
+    // interval specified in intervalBetweenChecks.
+    m_ticksUntilNextCheck = static_cast<unsigned>((static_cast<float>(intervalBetweenChecks) / timeDiff) * m_ticksUntilNextCheck);
+    // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
+    // preferred script check time interval.
+    if (m_ticksUntilNextCheck == 0)
+        m_ticksUntilNextCheck = ticksUntilFirstCheck;
+    
+    if (exec->dynamicGlobalObject()->shouldInterruptScriptBeforeTimeout())
+        return true;
+
+    if (m_timeoutInterval && m_timeExecuting > m_timeoutInterval) {
+        if (exec->dynamicGlobalObject()->shouldInterruptScript())
+            return true;
+        
+        reset();
+    }
+    
+    return false;
+}
+
+} // namespace JSC
diff --git a/runtime/TimeoutChecker.h b/runtime/TimeoutChecker.h
new file mode 100644 (file)
index 0000000..7bfa6d0
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TimeoutChecker_h
+#define TimeoutChecker_h
+
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+    class ExecState;
+
+    class TimeoutChecker {
+    public:
+        TimeoutChecker();
+
+        void setTimeoutInterval(unsigned timeoutInterval) { m_timeoutInterval = timeoutInterval; }
+        
+        unsigned ticksUntilNextCheck() { return m_ticksUntilNextCheck; }
+        
+        void start()
+        {
+            if (!m_startCount)
+                reset();
+            ++m_startCount;
+        }
+
+        void stop()
+        {
+            ASSERT(m_startCount);
+            --m_startCount;
+        }
+
+        void reset();
+
+        bool didTimeOut(ExecState*);
+
+    private:
+        unsigned m_timeoutInterval;
+        unsigned m_timeAtLastCheck;
+        unsigned m_timeExecuting;
+        unsigned m_startCount;
+        unsigned m_ticksUntilNextCheck;
+    };
+
+} // namespace JSC
+
+#endif // TimeoutChecker_h
index 52da34786e83d9dd193fa2624179820ff08324ca..70aeed33e9c9a187efef82845849a71ad788800a 100644 (file)
@@ -35,13 +35,22 @@ namespace JSC {
     static const unsigned MasqueradesAsUndefined = 1;
     static const unsigned ImplementsHasInstance = 1 << 1;
     static const unsigned OverridesHasInstance = 1 << 2;
-    static const unsigned NeedsThisConversion = 1 << 3;
-    static const unsigned HasStandardGetOwnPropertySlot = 1 << 4;
+    static const unsigned ImplementsDefaultHasInstance = 1 << 3;
+    static const unsigned NeedsThisConversion = 1 << 4;
+    static const unsigned HasStandardGetOwnPropertySlot = 1 << 5;
 
     class TypeInfo {
         friend class JIT;
     public:
-        TypeInfo(JSType type, unsigned flags = 0) : m_type(type), m_flags(flags) { }
+        TypeInfo(JSType type, unsigned flags = 0)
+            : m_type(type)
+        {
+            // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
+            if ((flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
+                m_flags = flags | ImplementsDefaultHasInstance;
+            else
+                m_flags = flags;
+        }
 
         JSType type() const { return m_type; }
 
index c7777b8bd58ebfcff2071fd6f2b711efac923d01..e1e51df55f524b44102559abd394fa0d62b471d6 100644 (file)
@@ -1,8 +1,8 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
- *  Copyright (c) 2009, Google Inc. All rights reserved.
+ *  Copyright (C) 2009 Google Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -62,6 +62,9 @@ namespace JSC {
 extern const double NaN;
 extern const double Inf;
 
+// This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
+static const int minLengthToShare = 10;
+
 static inline size_t overflowIndicator() { return std::numeric_limits<size_t>::max(); }
 static inline size_t maxUChars() { return std::numeric_limits<size_t>::max() / sizeof(UChar); }
 
@@ -93,7 +96,7 @@ static inline void copyChars(UChar* destination, const UChar* source, unsigned n
     memcpy(destination, source, numCharacters * sizeof(UChar));
 }
 
-COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes)
+COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes);
 
 CString::CString(const char* c)
     : m_length(strlen(c))
@@ -191,30 +194,20 @@ UString::BaseString* UString::Rep::nullBaseString;
 UString::BaseString* UString::Rep::emptyBaseString;
 UString* UString::nullUString;
 
-static void initializeStaticBaseString(int len, UChar* buf, UString::BaseString& base)
+static void initializeStaticBaseString(UString::BaseString& base)
 {
-    base.offset = 0;
-    base.len = len;
     base.rc = INT_MAX / 2;
-    base._hash = 0;
     base.m_identifierTableAndFlags.setFlag(UString::Rep::StaticFlag);
-    base.m_baseString = 0;
-    base.buf = buf;
-    base.preCapacity = 0;
-    base.usedPreCapacity = 0;
-    base.capacity = 0;
-    base.usedCapacity = 0;
-    base.reportedCost = 0;
     base.checkConsistency();
 }
 
 void initializeUString()
 {
-    UString::Rep::nullBaseString = new UString::BaseString;
-    initializeStaticBaseString(0, 0, *UString::Rep::nullBaseString);
+    UString::Rep::nullBaseString = new UString::BaseString(0, 0);
+    initializeStaticBaseString(*UString::Rep::nullBaseString);
 
-    UString::Rep::emptyBaseString = new UString::BaseString;
-    initializeStaticBaseString(0, &sharedEmptyChar, *UString::Rep::emptyBaseString);
+    UString::Rep::emptyBaseString = new UString::BaseString(&sharedEmptyChar, 0);
+    initializeStaticBaseString(*UString::Rep::emptyBaseString);
 
     UString::nullUString = new UString;
 }
@@ -228,52 +221,6 @@ PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar* d, int l)
     return create(copyD, l);
 }
 
-PassRefPtr<UString::Rep> UString::Rep::create(UChar* d, int l)
-{
-    BaseString* r = new BaseString;
-    r->offset = 0;
-    r->len = l;
-    r->rc = 1;
-    r->_hash = 0;
-    r->m_baseString = 0;
-    r->reportedCost = 0;
-    r->buf = d;
-    r->usedCapacity = l;
-    r->capacity = l;
-    r->usedPreCapacity = 0;
-    r->preCapacity = 0;
-
-    r->checkConsistency();
-
-    // steal the single reference this Rep was created with
-    return adoptRef(r);
-}
-
-PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> rep, int offset, int length)
-{
-    ASSERT(rep);
-    rep->checkConsistency();
-
-    int repOffset = rep->offset;
-
-    PassRefPtr<BaseString> base = rep->baseString();
-
-    ASSERT(-(offset + repOffset) <= base->usedPreCapacity);
-    ASSERT(offset + repOffset + length <= base->usedCapacity);
-
-    Rep* r = new Rep;
-    r->offset = repOffset + offset;
-    r->len = length;
-    r->rc = 1;
-    r->_hash = 0;
-    r->setBaseString(base);
-
-    r->checkConsistency();
-
-    // steal the single reference this Rep was created with
-    return adoptRef(r);
-}
-
 PassRefPtr<UString::Rep> UString::Rep::createFromUTF8(const char* string)
 {
     if (!string)
@@ -288,6 +235,23 @@ PassRefPtr<UString::Rep> UString::Rep::createFromUTF8(const char* string)
     return UString::Rep::createCopying(buffer.data(), p - buffer.data());
 }
 
+PassRefPtr<UString::Rep> UString::Rep::create(UChar* string, int length, PassRefPtr<UString::SharedUChar> sharedBuffer)
+{
+    PassRefPtr<UString::Rep> rep = create(string, length);
+    rep->baseString()->setSharedBuffer(sharedBuffer);
+    rep->checkConsistency();
+    return rep;
+}
+
+UString::SharedUChar* UString::Rep::sharedBuffer()
+{
+    UString::BaseString* base = baseString();
+    if (len < minLengthToShare)
+        return 0;
+
+    return base->sharedBuffer();
+}
+
 void UString::Rep::destroy()
 {
     checkConsistency();
@@ -297,10 +261,14 @@ void UString::Rep::destroy()
     if (!isStatic()) {
         if (identifierTable())
             Identifier::remove(this);
+
         UString::BaseString* base = baseString();
-        if (base == this)
-            fastFree(base->buf);
-        else
+        if (base == this) {
+            if (m_sharedBuffer)
+                m_sharedBuffer->deref();
+            else
+                fastFree(base->buf);
+        } else
             base->deref();
 
         delete this;
@@ -424,25 +392,88 @@ void UString::Rep::checkConsistency() const
 }
 #endif
 
-// put these early so they can be inlined
-static inline size_t expandedSize(size_t size, size_t otherSize)
+UString::SharedUChar* UString::BaseString::sharedBuffer()
 {
-    // Do the size calculation in two parts, returning overflowIndicator if
-    // we overflow the maximum value that we can handle.
+    if (!m_sharedBuffer)
+        setSharedBuffer(SharedUChar::create(new OwnFastMallocPtr<UChar>(buf)));
+    return m_sharedBuffer;
+}
 
-    if (size > maxUChars())
-        return overflowIndicator();
+void UString::BaseString::setSharedBuffer(PassRefPtr<UString::SharedUChar> sharedBuffer)
+{
+    // The manual steps below are because m_sharedBuffer can't be a RefPtr. m_sharedBuffer
+    // is in a union with another variable to avoid making BaseString any larger.
+    if (m_sharedBuffer)
+        m_sharedBuffer->deref();
+    m_sharedBuffer = sharedBuffer.releaseRef();
+}
 
-    size_t expandedSize = ((size + 10) / 10 * 11) + 1;
-    if (maxUChars() - expandedSize < otherSize)
+bool UString::BaseString::slowIsBufferReadOnly()
+{
+    // The buffer may not be modified as soon as the underlying data has been shared with another class.
+    if (m_sharedBuffer->isShared())
+        return true;
+
+    // At this point, we know it that the underlying buffer isn't shared outside of this base class,
+    // so get rid of m_sharedBuffer.
+    OwnPtr<OwnFastMallocPtr<UChar> > mallocPtr(m_sharedBuffer->release());
+    UChar* unsharedBuf = const_cast<UChar*>(mallocPtr->release());
+    setSharedBuffer(0);
+    preCapacity += (buf - unsharedBuf);
+    buf = unsharedBuf;
+    return false;
+}
+
+// Put these early so they can be inlined.
+static inline size_t expandedSize(size_t capacitySize, size_t precapacitySize)
+{
+    // Combine capacitySize & precapacitySize to produce a single size to allocate,
+    // check that doing so does not result in overflow.
+    size_t size = capacitySize + precapacitySize;
+    if (size < capacitySize)
         return overflowIndicator();
 
-    return expandedSize + otherSize;
+    // Small Strings (up to 4 pages):
+    // Expand the allocation size to 112.5% of the amount requested.  This is largely sicking
+    // to our previous policy, however 112.5% is cheaper to calculate.
+    if (size < 0x4000) {
+        size_t expandedSize = ((size + (size >> 3)) | 15) + 1;
+        // Given the limited range within which we calculate the expansion in this
+        // fashion the above calculation should never overflow.
+        ASSERT(expandedSize >= size);
+        ASSERT(expandedSize < maxUChars());
+        return expandedSize;
+    }
+
+    // Medium Strings (up to 128 pages):
+    // For pages covering multiple pages over-allocation is less of a concern - any unused
+    // space will not be paged in if it is not used, so this is purely a VM overhead.  For
+    // these strings allocate 2x the requested size.
+    if (size < 0x80000) {
+        size_t expandedSize = ((size + size) | 0xfff) + 1;
+        // Given the limited range within which we calculate the expansion in this
+        // fashion the above calculation should never overflow.
+        ASSERT(expandedSize >= size);
+        ASSERT(expandedSize < maxUChars());
+        return expandedSize;
+    }
+
+    // Large Strings (to infinity and beyond!):
+    // Revert to our 112.5% policy - probably best to limit the amount of unused VM we allow
+    // any individual string be responsible for.
+    size_t expandedSize = ((size + (size >> 3)) | 0xfff) + 1;
+
+    // Check for overflow - any result that is at least as large as requested (but
+    // still below the limit) is okay.
+    if ((expandedSize >= size) && (expandedSize < maxUChars()))
+        return expandedSize;
+    return overflowIndicator();
 }
 
 static inline bool expandCapacity(UString::Rep* rep, int requiredLength)
 {
     rep->checkConsistency();
+    ASSERT(!rep->baseString()->isBufferReadOnly());
 
     UString::BaseString* base = rep->baseString();
 
@@ -463,6 +494,35 @@ static inline bool expandCapacity(UString::Rep* rep, int requiredLength)
     return true;
 }
 
+bool UString::Rep::reserveCapacity(int capacity)
+{
+    // If this is an empty string there is no point 'growing' it - just allocate a new one.
+    // If the BaseString is shared with another string that is using more capacity than this
+    // string is, then growing the buffer won't help.
+    // If the BaseString's buffer is readonly, then it isn't allowed to grow.
+    UString::BaseString* base = baseString();
+    if (!base->buf || !base->capacity || (offset + len) != base->usedCapacity || base->isBufferReadOnly())
+        return false;
+    
+    // If there is already sufficient capacity, no need to grow!
+    if (capacity <= base->capacity)
+        return true;
+
+    checkConsistency();
+
+    size_t newCapacity = expandedSize(capacity, base->preCapacity);
+    UChar* oldBuf = base->buf;
+    base->buf = reallocChars(base->buf, newCapacity);
+    if (!base->buf) {
+        base->buf = oldBuf;
+        return false;
+    }
+    base->capacity = newCapacity - base->preCapacity;
+
+    checkConsistency();
+    return true;
+}
+
 void UString::expandCapacity(int requiredLength)
 {
     if (!JSC::expandCapacity(m_rep.get(), requiredLength))
@@ -472,6 +532,7 @@ void UString::expandCapacity(int requiredLength)
 void UString::expandPreCapacity(int requiredPreCap)
 {
     m_rep->checkConsistency();
+    ASSERT(!m_rep->baseString()->isBufferReadOnly());
 
     BaseString* base = m_rep->baseString();
 
@@ -575,7 +636,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
     } else if (thisSize == 0) {
         // this is empty
         rep = UString::Rep::createCopying(tData, tSize);
-    } else if (rep == base && rep->rc == 1) {
+    } else if (rep == base && !base->isShared()) {
         // this is direct and has refcount of 1 (so we can just alter it directly)
         if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)))
             rep = &UString::Rep::null();
@@ -584,7 +645,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
             rep->len = length;
             rep->_hash = 0;
         }
-    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
+    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
         // this reaches the end of the buffer - extend it if it's long enough to append to
         if (!expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length)))
             rep = &UString::Rep::null();
@@ -593,7 +654,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
             rep = UString::Rep::create(rep, 0, length);
         }
     } else {
-        // this is shared with someone using more capacity, gotta make a whole new string
+        // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
         size_t newCapacity = expandedSize(length, 0);
         UChar* d = allocChars(newCapacity);
         if (!d)
@@ -629,7 +690,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
         rep = createRep(t);
     } else if (tSize == 0) {
         // t is empty, we'll just return *this below.
-    } else if (rep == base && rep->rc == 1) {
+    } else if (rep == base && !base->isShared()) {
         // this is direct and has refcount of 1 (so we can just alter it directly)
         expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
         UChar* d = rep->data();
@@ -639,7 +700,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
             rep->len = length;
             rep->_hash = 0;
         }
-    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
+    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
         // this string reaches the end of the buffer - extend it
         expandCapacity(rep.get(), newCapacityWithOverflowCheck(thisOffset, length));
         UChar* d = rep->data();
@@ -649,7 +710,7 @@ static ALWAYS_INLINE PassRefPtr<UString::Rep> concatenate(PassRefPtr<UString::Re
             rep = UString::Rep::create(rep, 0, length);
         }
     } else {
-        // this is shared with someone using more capacity, gotta make a whole new string
+        // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
         size_t newCapacity = expandedSize(length, 0);
         UChar* d = allocChars(newCapacity);
         if (!d)
@@ -674,13 +735,19 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
     b->checkConsistency();
 
     int aSize = a->size();
-    int aOffset = a->offset;
     int bSize = b->size();
-    int bOffset = b->offset;
-    int length = aSize + bSize;
+    int aOffset = a->offset;
 
     // possible cases:
 
+    UString::BaseString* aBase = a->baseString();
+    if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + aSize < aBase->capacity && !aBase->isBufferReadOnly()) {
+        // b is a single character (common fast case)
+        ++aBase->usedCapacity;
+        a->data()[aSize] = b->data()[0];
+        return UString::Rep::create(a, 0, aSize + 1);
+    }
+
     // a is empty
     if (aSize == 0)
         return b;
@@ -688,17 +755,12 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
     if (bSize == 0)
         return a;
 
-    UString::BaseString* aBase = a->baseString();
-    if (bSize == 1 && aOffset + aSize == aBase->usedCapacity && aOffset + length <= aBase->capacity) {
-        // b is a single character (common fast case)
-        aBase->usedCapacity = aOffset + length;
-        a->data()[aSize] = b->data()[0];
-        return UString::Rep::create(a, 0, length);
-    }
+    int bOffset = b->offset;
+    int length = aSize + bSize;
 
     UString::BaseString* bBase = b->baseString();
     if (aOffset + aSize == aBase->usedCapacity && aSize >= minShareSize && 4 * aSize >= bSize
-        && (-bOffset != bBase->usedPreCapacity || aSize >= bSize)) {
+        && (-bOffset != bBase->usedPreCapacity || aSize >= bSize) && !aBase->isBufferReadOnly()) {
         // - a reaches the end of its buffer so it qualifies for shared append
         // - also, it's at least a quarter the length of b - appending to a much shorter
         //   string does more harm than good
@@ -718,7 +780,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* a, UString::Rep* b)
         return result;
     }
 
-    if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize) {
+    if (-bOffset == bBase->usedPreCapacity && bSize >= minShareSize && 4 * bSize >= aSize && !bBase->isBufferReadOnly()) {
         // - b reaches the beginning of its buffer so it qualifies for shared prepend
         // - also, it's at least a quarter the length of a - prepending to a much shorter
         //   string does more harm than good
@@ -796,7 +858,8 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d)
     int decimalPoint;
     int sign;
 
-    char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);
+    char result[80];
+    WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
     int length = static_cast<int>(strlen(result));
   
     int i = 0;
@@ -847,9 +910,7 @@ PassRefPtr<UString::Rep> concatenate(UString::Rep* rep, double d)
         buf[i++] = '\0';
     }
     
-  WTF::freedtoa(result);
-
-  return concatenate(rep, buf);
+    return concatenate(rep, buf);
 }
 
 UString UString::from(int i)
@@ -937,8 +998,9 @@ UString UString::from(double d)
     char buf[80];
     int decimalPoint;
     int sign;
-
-    char* result = WTF::dtoa(d, 0, &decimalPoint, &sign, NULL);
+    
+    char result[80];
+    WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
     int length = static_cast<int>(strlen(result));
   
     int i = 0;
@@ -991,9 +1053,7 @@ UString UString::from(double d)
         ASSERT(i <= static_cast<int>(sizeof(buf)));
     }
     
-  WTF::freedtoa(result);
-
-  return UString(buf);
+    return UString(buf);
 }
 
 UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const
@@ -1038,6 +1098,28 @@ UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, in
     return UString::Rep::create(buffer, totalLength);
 }
 
+UString UString::replaceRange(int rangeStart, int rangeLength, const UString& replacement) const
+{
+    m_rep->checkConsistency();
+
+    int replacementLength = replacement.size();
+    int totalLength = size() - rangeLength + replacementLength;
+    if (totalLength == 0)
+        return "";
+
+    UChar* buffer = allocChars(totalLength);
+    if (!buffer)
+        return null();
+
+    copyChars(buffer, data(), rangeStart);
+    copyChars(buffer + rangeStart, replacement.data(), replacementLength);
+    int rangeEnd = rangeStart + rangeLength;
+    copyChars(buffer + rangeStart + replacementLength, data() + rangeEnd, size() - rangeEnd);
+
+    return UString::Rep::create(buffer, totalLength);
+}
+
+
 UString& UString::append(const UString &t)
 {
     m_rep->checkConsistency();
@@ -1055,7 +1137,7 @@ UString& UString::append(const UString &t)
         *this = t;
     } else if (tSize == 0) {
         // t is empty
-    } else if (m_rep == base && m_rep->rc == 1) {
+    } else if (m_rep == base && !base->isShared()) {
         // this is direct and has refcount of 1 (so we can just alter it directly)
         expandCapacity(newCapacityWithOverflowCheck(thisOffset, length));
         if (data()) {
@@ -1063,7 +1145,7 @@ UString& UString::append(const UString &t)
             m_rep->len = length;
             m_rep->_hash = 0;
         }
-    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize) {
+    } else if (thisOffset + thisSize == base->usedCapacity && thisSize >= minShareSize && !base->isBufferReadOnly()) {
         // this reaches the end of the buffer - extend it if it's long enough to append to
         expandCapacity(newCapacityWithOverflowCheck(thisOffset, length));
         if (data()) {
@@ -1071,7 +1153,7 @@ UString& UString::append(const UString &t)
             m_rep = Rep::create(m_rep, 0, length);
         }
     } else {
-        // this is shared with someone using more capacity, gotta make a whole new string
+        // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
         size_t newCapacity = expandedSize(length, 0);
         UChar* d = allocChars(newCapacity);
         if (!d)
@@ -1096,6 +1178,18 @@ UString& UString::append(const UChar* tData, int tSize)
     return *this;
 }
 
+UString& UString::appendNumeric(int i)
+{
+    m_rep = concatenate(rep(), i);
+    return *this;
+}
+
+UString& UString::appendNumeric(double d)
+{
+    m_rep = concatenate(rep(), d);
+    return *this;
+}
+
 UString& UString::append(const char* t)
 {
     m_rep = concatenate(m_rep.release(), t);
@@ -1122,7 +1216,7 @@ UString& UString::append(UChar c)
             m_rep = Rep::create(d, 1);
             m_rep->baseString()->capacity = newCapacity;
         }
-    } else if (m_rep == base && m_rep->rc == 1) {
+    } else if (m_rep == base && !base->isShared()) {
         // this is direct and has refcount of 1 (so we can just alter it directly)
         expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true));
         UChar* d = m_rep->data();
@@ -1131,7 +1225,7 @@ UString& UString::append(UChar c)
             m_rep->len = length + 1;
             m_rep->_hash = 0;
         }
-    } else if (thisOffset + length == base->usedCapacity && length >= minShareSize) {
+    } else if (thisOffset + length == base->usedCapacity && length >= minShareSize && !base->isBufferReadOnly()) {
         // this reaches the end of the string - extend it and share
         expandCapacity(newCapacityWithOverflowCheck(thisOffset, length, true));
         UChar* d = m_rep->data();
@@ -1140,7 +1234,7 @@ UString& UString::append(UChar c)
             m_rep = Rep::create(m_rep, 0, length + 1);
         }
     } else {
-        // this is shared with someone using more capacity, gotta make a whole new string
+        // This is shared in some way that prevents us from modifying base, so we must make a whole new string.
         size_t newCapacity = expandedSize(length + 1, 0);
         UChar* d = allocChars(newCapacity);
         if (!d)
@@ -1216,7 +1310,7 @@ UString& UString::operator=(const char* c)
     int l = static_cast<int>(strlen(c));
     UChar* d;
     BaseString* base = m_rep->baseString();
-    if (m_rep->rc == 1 && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) {
+    if (!base->isShared() && l <= base->capacity && m_rep == base && m_rep->offset == 0 && base->preCapacity == 0) {
         d = base->buf;
         m_rep->_hash = 0;
         m_rep->len = l;
@@ -1534,19 +1628,6 @@ UString UString::substr(int pos, int len) const
     return UString(Rep::create(m_rep, pos, len));
 }
 
-bool operator==(const UString& s1, const UString& s2)
-{
-    int size = s1.size();
-    switch (size) {
-        case 0:
-            return !s2.size();
-        case 1:
-            return s2.size() == 1 && s1.data()[0] == s2.data()[0];
-        default:
-            return s2.size() == size && memcmp(s1.data(), s2.data(), size * sizeof(UChar)) == 0;
-    }
-}
-
 bool operator==(const UString& s1, const char *s2)
 {
     if (s2 == 0)
index 59a7665059ffb34d0e3f0219f6b20b33ffe7cf5e..d01b75de7e3bdbce0bf023f405d636664fc647cf 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
- *  Copyright (c) 2009, Google Inc. All rights reserved.
+ *  Copyright (C) 2009 Google Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -27,6 +27,8 @@
 #include <stdint.h>
 #include <string.h>
 #include <wtf/Assertions.h>
+#include <wtf/CrossThreadRefCounted.h>
+#include <wtf/OwnFastMallocPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/PtrAndFlags.h>
 #include <wtf/RefPtr.h>
@@ -75,11 +77,26 @@ namespace JSC {
         friend class JIT;
 
     public:
+        typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
         struct BaseString;
         struct Rep : Noncopyable {
             friend class JIT;
 
-            static PassRefPtr<Rep> create(UChar*, int);
+            static PassRefPtr<Rep> create(UChar* buffer, int length)
+            {
+                return adoptRef(new BaseString(buffer, length));
+            }
+
+            static PassRefPtr<Rep> createEmptyBuffer(size_t size)
+            {
+                // Guard against integer overflow
+                if (size < (std::numeric_limits<size_t>::max() / sizeof(UChar))) {
+                    if (void * buf = tryFastMalloc(size * sizeof(UChar)))
+                        return adoptRef(new BaseString(static_cast<UChar*>(buf), 0, size));
+                }
+                return adoptRef(new BaseString(0, 0, 0));
+            }
+
             static PassRefPtr<Rep> createCopying(const UChar*, int);
             static PassRefPtr<Rep> create(PassRefPtr<Rep> base, int offset, int length);
 
@@ -87,6 +104,10 @@ namespace JSC {
             // Returns UString::Rep::null for null input or conversion failure.
             static PassRefPtr<Rep> createFromUTF8(const char*);
 
+            // Uses SharedUChar to have joint ownership over the UChar*.
+            static PassRefPtr<Rep> create(UChar*, int, PassRefPtr<SharedUChar>);
+
+            SharedUChar* sharedBuffer();
             void destroy();
 
             bool baseIsSelf() const { return m_identifierTableAndFlags.isFlagSet(BaseStringFlag); }
@@ -124,21 +145,60 @@ namespace JSC {
             int rc; // For null and empty static strings, this field does not reflect a correct count, because ref/deref are not thread-safe. A special case in destroy() guarantees that these do not get deleted.
             mutable unsigned _hash;
             PtrAndFlags<IdentifierTable, UStringFlags> m_identifierTableAndFlags;
-            void* m_baseString; // If "this" is a BaseString instance, it is 0. BaseString* otherwise.
 
             static BaseString& null() { return *nullBaseString; }
             static BaseString& empty() { return *emptyBaseString; }
 
+            bool reserveCapacity(int capacity);
+
+        protected:
+            // Constructor for use by BaseString subclass; they use the union with m_baseString for another purpose.
+            Rep(int length)
+                : offset(0)
+                , len(length)
+                , rc(1)
+                , _hash(0)
+                , m_baseString(0)
+            {
+            }
+
+            Rep(PassRefPtr<BaseString> base, int offsetInBase, int length)
+                : offset(offsetInBase)
+                , len(length)
+                , rc(1)
+                , _hash(0)
+                , m_baseString(base.releaseRef())
+            {
+                checkConsistency();
+            }
+
+            union {
+                // If !baseIsSelf()
+                BaseString* m_baseString;
+                // If baseIsSelf()
+                SharedUChar* m_sharedBuffer;
+            };
+
         private:
+            // For SmallStringStorage which allocates an array and does initialization manually.
+            Rep() { }
+
+            friend class SmallStringsStorage;
             friend void initializeUString();
-            static BaseString* nullBaseString;
-            static BaseString* emptyBaseString;
+            JS_EXPORTDATA static BaseString* nullBaseString;
+            JS_EXPORTDATA static BaseString* emptyBaseString;
         };
 
+
         struct BaseString : public Rep {
-            BaseString()
+            bool isShared() { return rc != 1 || isBufferReadOnly(); }
+            void setSharedBuffer(PassRefPtr<SharedUChar>);
+
+            bool isBufferReadOnly()
             {
-                m_identifierTableAndFlags.setFlag(BaseStringFlag);
+                if (!m_sharedBuffer)
+                    return false;
+                return slowIsBufferReadOnly();
             }
 
             // potentially shared data.
@@ -149,6 +209,27 @@ namespace JSC {
             int usedCapacity;
 
             size_t reportedCost;
+
+        private:
+            BaseString(UChar* buffer, int length, int additionalCapacity = 0)
+                : Rep(length)
+                , buf(buffer)
+                , preCapacity(0)
+                , usedPreCapacity(0)
+                , capacity(length + additionalCapacity)
+                , usedCapacity(length)
+                , reportedCost(0)
+            {
+                m_identifierTableAndFlags.setFlag(BaseStringFlag);
+                checkConsistency();
+            }
+
+            SharedUChar* sharedBuffer();
+            bool slowIsBufferReadOnly();
+
+            friend struct Rep;
+            friend class SmallStringsStorage;
+            friend void initializeUString();
         };
 
     public:
@@ -197,11 +278,15 @@ namespace JSC {
 
         UString spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const;
 
+        UString replaceRange(int rangeStart, int RangeEnd, const UString& replacement) const;
+
         UString& append(const UString&);
         UString& append(const char*);
         UString& append(UChar);
         UString& append(char c) { return append(static_cast<UChar>(static_cast<unsigned char>(c))); }
         UString& append(const UChar*, int size);
+        UString& appendNumeric(int);
+        UString& appendNumeric(double);
 
         bool getCString(CStringBuffer&) const;
 
@@ -265,6 +350,17 @@ namespace JSC {
 
         size_t cost() const;
 
+        // Attempt to grow this string such that it can grow to a total length of 'capacity'
+        // without reallocation.  This may fail a number of reasons - if the BasicString is
+        // shared and another string is using part of the capacity beyond our end point, if
+        // the realloc fails, or if this string is empty and has no storage.
+        //
+        // This method returns a boolean indicating success.
+        bool reserveCapacity(int capacity)
+        {
+            return m_rep->reserveCapacity(capacity);
+        }
+
     private:
         void expandCapacity(int requiredLength);
         void expandPreCapacity(int requiredPreCap);
@@ -281,7 +377,26 @@ namespace JSC {
     PassRefPtr<UString::Rep> concatenate(UString::Rep*, int);
     PassRefPtr<UString::Rep> concatenate(UString::Rep*, double);
 
-    bool operator==(const UString&, const UString&);
+    inline bool operator==(const UString& s1, const UString& s2)
+    {
+        int size = s1.size();
+        switch (size) {
+        case 0:
+            return !s2.size();
+        case 1:
+            return s2.size() == 1 && s1.data()[0] == s2.data()[0];
+        case 2: {
+            if (s2.size() != 2)
+                return false;
+            const UChar* d1 = s1.data();
+            const UChar* d2 = s2.data();
+            return (d1[0] == d2[0]) & (d1[1] == d2[1]);
+        }
+        default:
+            return s2.size() == size && memcmp(s1.data(), s2.data(), size * sizeof(UChar)) == 0;
+        }
+    }
+
 
     inline bool operator!=(const UString& s1, const UString& s2)
     {
@@ -320,6 +435,22 @@ namespace JSC {
 
     bool equal(const UString::Rep*, const UString::Rep*);
 
+    inline PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<UString::Rep> rep, int offset, int length)
+    {
+        ASSERT(rep);
+        rep->checkConsistency();
+
+        int repOffset = rep->offset;
+
+        PassRefPtr<BaseString> base = rep->baseString();
+
+        ASSERT(-(offset + repOffset) <= base->usedPreCapacity);
+        ASSERT(offset + repOffset + length <= base->usedCapacity);
+
+        // Steal the single reference this Rep was created with.
+        return adoptRef(new Rep(base, repOffset + offset, length));
+    }
+
     inline UChar* UString::Rep::data() const
     {
         const BaseString* base = baseString();
@@ -338,17 +469,18 @@ namespace JSC {
     inline void UString::Rep::setBaseString(PassRefPtr<BaseString> base)
     {
         ASSERT(base != this);
+        ASSERT(!baseIsSelf());
         m_baseString = base.releaseRef();
     }
 
     inline UString::BaseString* UString::Rep::baseString()
     {
-        return reinterpret_cast<BaseString*>(baseIsSelf() ? this : m_baseString);
+        return !baseIsSelf() ? m_baseString : reinterpret_cast<BaseString*>(this) ;
     }
 
     inline const UString::BaseString* UString::Rep::baseString() const
     {
-        return const_cast<const BaseString*>(const_cast<Rep*>(this)->baseString());
+        return const_cast<Rep*>(this)->baseString();
     }
 
 #ifdef NDEBUG
index 1b0a01b5987f14189abefafb2db2bda233ffba91..c8f84badc81c847a35688fb4229fcbba0e03c4dd 100644 (file)
@@ -16,6 +16,19 @@ I think this should be 'false'
 
     Author:             christine@netscape.com
     Date:               12 november 1997
+
+
+The test case described above is correct, however the second test case in this file is not,
+'o instanceof o' should thow an exception.  According to ECMA-262:
+
+    8.6.2 Internal Properties and Methods:
+        "... only Function objects implement [[HasInstance]]"
+    11.8.6 The instanceof operator:
+        "6.If Result(4) does not have a [[HasInstance]] method, throw a TypeError exception."
+
+{} does not implement [[HasInstance]] (since it is not a function), so passing it as the
+constructor to be tested to instanceof should result in a TypeError being thrown.
+
 */
     var SECTION = "instanceof-003";
     var VERSION = "ECMA_2";
@@ -35,12 +48,10 @@ I think this should be 'false'
         theproto instanceof Foo );
 
 
-    var o = {};
-
     AddTestCase(
         "o = {}; o instanceof o",
-        false,
-        o instanceof o );
+        "EXCEPTION",
+        (function(){ try { var o = {}; o instanceof o; return "no exception"; } catch (e) { return "EXCEPTION"; } } )() );
 
 
     test();
index 4ccb9d43e7f12a566cb3d14d77257417df865478..cab6ed90d288d108a0c6a683b271de3723668679 100644 (file)
  *  Author:             
  */
 
-    var SECTION = "instanceof";       // provide a document reference (ie, ECMA section)
-    var VERSION = "ECMA_2"; // Version of JavaScript or ECMA
-    var TITLE   = "Regression test for Bugzilla #7635";       // Provide ECMA section title or a description
-    var BUGNUMBER = "http://bugzilla.mozilla.org/show_bug.cgi?id=7635";     // Provide URL to bugsplat or bugzilla report
+var SECTION = "instanceof";       // provide a document reference (ie, ECMA section)
+var VERSION = "ECMA_2"; // Version of JavaScript or ECMA
+var TITLE   = "Regression test for Bugzilla #7635";       // Provide ECMA section title or a description
+var BUGNUMBER = "http://bugzilla.mozilla.org/show_bug.cgi?id=7635";     // Provide URL to bugsplat or bugzilla report
 
-    startTest();               // leave this alone
+startTest();               // leave this alone
 
-    /*
-     * Calls to AddTestCase here. AddTestCase is a function that is defined
-     * in shell.js and takes three arguments:
-     * - a string representation of what is being tested
-     * - the expected result
-     * - the actual result
-     *
-     * For example, a test might look like this:
-     *
-     * var zip = /[\d]{5}$/;
-     *
-     * AddTestCase(
-     * "zip = /[\d]{5}$/; \"PO Box 12345 Boston, MA 02134\".match(zip)",   // description of the test
-     *  "02134",                                                           // expected result
-     *  "PO Box 12345 Boston, MA 02134".match(zip) );                      // actual result
-     *
-     */
-
-       function Foo() {}
-       theproto = {};
-       Foo.prototype = theproto
-       theproto instanceof Foo
+/*
+ * Calls to AddTestCase here. AddTestCase is a function that is defined
+ * in shell.js and takes three arguments:
+ * - a string representation of what is being tested
+ * - the expected result
+ * - the actual result
+ *
+ * For example, a test might look like this:
+ *
+ * var zip = /[\d]{5}$/;
+ *
+ * AddTestCase(
+ * "zip = /[\d]{5}$/; \"PO Box 12345 Boston, MA 02134\".match(zip)",   // description of the test
+ *  "02134",                                                           // expected result
+ *  "PO Box 12345 Boston, MA 02134".match(zip) );                      // actual result
+ *
+ */
 
+function Foo() {}
+theproto = {};
+Foo.prototype = theproto
+theproto instanceof Foo
 
-       AddTestCase( "function Foo() {}; theproto = {}; Foo.prototype = theproto; theproto instanceof Foo",
-                       false,
-                       theproto instanceof Foo );
-       
-       var o  = {};
 
-       AddTestCase( "var o = {}; o instanceof o", false, o instanceof o );
+AddTestCase( "function Foo() {}; theproto = {}; Foo.prototype = theproto; theproto instanceof Foo",
+        false,
+        theproto instanceof Foo );
 
-       var f = new Function();
+var f = new Function();
 
-       AddTestCase( "var f = new Function(); f instanceof f", false, f instanceof f );
+AddTestCase( "var f = new Function(); f instanceof f", false, f instanceof f );
 
 
-    test();       // leave this alone.  this executes the test cases and
-                  // displays results.
+test();       // leave this alone.  this executes the test cases and
+              // displays results.
index e51c4d153891e257997cb5fb422c2e186e052f1d..fdcb4e96c5114bbc62e672844f6580afa56f0e61 100644 (file)
@@ -6,12 +6,12 @@
 <h2>Test results, squirrelfish</h2><br>
 <p class='results_summary'>
 Test List: All tests<br>
-Skip List: (none)<br>
-1135 test(s) selected, 1127 test(s) completed, 50 failures reported (4.43% failed)<br>
-Engine command line: "/Users/Cameron/WebKit/WebKitBuild/Debug/jsc" <br>
-OS type: Darwin d141-97-200.home.cgocable.net 9.5.0 Darwin Kernel Version 9.5.0: Wed Sep  3 11:29:43 PDT 2008; root:xnu-1228.7.58~1/RELEASE_I386 i386<br>
-Testcase execution time: 1 minutes, 10 seconds.<br>
-Tests completed on Thu Sep 18 02:24:54 2008.<br><br>
+Skip List: ecma/Date/15.9.2.1.js, ecma/Date/15.9.2.2-1.js, ecma/Date/15.9.2.2-2.js, ecma/Date/15.9.2.2-3.js, ecma/Date/15.9.2.2-4.js, ecma/Date/15.9.2.2-5.js, ecma/Date/15.9.2.2-6.js, ecma_3/Date/15.9.5.7.js<br>
+1127 test(s) selected, 1119 test(s) completed, 49 failures reported (4.37% failed)<br>
+Engine command line: "/Volumes/Big/ggaren/build/Debug/jsc" <br>
+OS type: Darwin il0301a-dhcp53.apple.com 9.7.0 Darwin Kernel Version 9.7.0: Tue Mar 31 22:52:17 PDT 2009; root:xnu-1228.12.14~1/RELEASE_I386 i386<br>
+Testcase execution time: 3 minutes, 18 seconds.<br>
+Tests completed on Tue Apr 21 12:56:28 2009.<br><br>
 [ <a href='#fail_detail'>Failure Details</a> | <a href='#retest_list'>Retest List</a> | <a href='menu.html'>Test Selection Page</a> ]<br>
 <hr>
 <a name='fail_detail'></a>
@@ -30,33 +30,16 @@ Failure messages were:<br>
 Failure messages were:<br>
 eval("function f(){}function g(){}") (threw no exception thrown = fail FAILED! expected: pass<br>
 </tt><br>
-<a name='failure3'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Date/15.9.5.7.js'>ecma_3/Date/15.9.5.7.js</a> failed</b> <br>
+<a name='failure3'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/FunExpr/fe-001.js'>ecma_3/FunExpr/fe-001.js</a> failed</b> <br>
  [ <a href='#failure2'>Previous Failure</a> | <a href='#failure4'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
-<tt><br>
+<tt>STATUS: Function Expression Statements basic test.<br>
 Failure messages were:<br>
-(Wed Dec 31 1969 16:00:00 GMT-0800 (PST)).toLocaleTimeString() = 4:00:00 PM PST FAILED! expected: 16:00:00<br>
-(Wed Dec 31 1969 08:00:00 GMT-0800 (PST)).toLocaleTimeString() = 8:00:00 AM PST FAILED! expected: 08:00:00<br>
-(Sun Dec 31 1899 16:00:00 GMT-0800 (PST)).toLocaleTimeString() = 5:00:00 PM PDT FAILED! expected: 16:00:00<br>
-(Mon Jan 01 1900 00:00:00 GMT-0800 (PST)).toLocaleTimeString() = 1:00:00 AM PDT FAILED! expected: 00:00:00<br>
-(Fri Dec 31 1999 16:00:00 GMT-0800 (PST)).toLocaleTimeString() = 4:00:00 PM PST FAILED! expected: 16:00:00<br>
-(Sat Jan 01 2000 00:00:00 GMT-0800 (PST)).toLocaleTimeString() = 12:00:00 AM PST FAILED! expected: 00:00:00<br>
-(Mon Feb 28 2000 16:00:00 GMT-0800 (PST)).toLocaleTimeString() = 4:00:00 PM PST FAILED! expected: 16:00:00<br>
-(Mon Feb 28 2000 15:59:59 GMT-0800 (PST)).toLocaleTimeString() = 3:59:59 PM PST FAILED! expected: 15:59:59<br>
-(Tue Feb 29 2000 00:00:00 GMT-0800 (PST)).toLocaleTimeString() = 12:00:00 AM PST FAILED! expected: 00:00:00<br>
-(Thu Sep 18 2008 02:24:30 GMT-0700 (PDT)).toLocaleTimeString() = 2:24:30 AM PDT FAILED! expected: 02:24:30<br>
-(Thu Sep 18 2008 10:24:30 GMT-0700 (PDT)).toLocaleTimeString() = 10:24:30 AM PDT FAILED! expected: 10:24:30<br>
-(Fri Dec 31 2004 16:00:00 GMT-0800 (PST)).toLocaleTimeString() = 4:00:00 PM PST FAILED! expected: 16:00:00<br>
-(Fri Dec 31 2004 15:59:59 GMT-0800 (PST)).toLocaleTimeString() = 3:59:59 PM PST FAILED! expected: 15:59:59<br>
-(Sat Jan 01 2005 00:00:00 GMT-0800 (PST)).toLocaleTimeString() = 12:00:00 AM PST FAILED! expected: 00:00:00<br>
+FAILED!: [reported from test()] Both functions were defined.<br>
+FAILED!: [reported from test()] Expected value '1', Actual value '0'<br>
+FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure4'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/FunExpr/fe-001.js'>ecma_3/FunExpr/fe-001.js</a> failed</b> <br>
+<a name='failure4'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/15.10.2-1.js'>ecma_3/RegExp/15.10.2-1.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=(none)' target='other_window'>Bug Number (none)</a><br>
  [ <a href='#failure3'>Previous Failure</a> | <a href='#failure5'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
-<tt>Expected exit code 0, got 3<br>
-Testcase terminated with signal 0<br>
-Complete testcase output was:<br>
-Testcase produced no output!</tt><br>
-<a name='failure5'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/15.10.2-1.js'>ecma_3/RegExp/15.10.2-1.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=(none)' target='other_window'>Bug Number (none)</a><br>
- [ <a href='#failure4'>Previous Failure</a> | <a href='#failure6'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>STATUS: RegExp conformance test<br>
 Failure messages were:<br>
 FAILED!: [reported from test()] Section 7 of test -<br>
@@ -81,8 +64,8 @@ FAILED!: [reported from test()] Expect: ["baaabaac", "ba", , "abaac"]<br>
 FAILED!: [reported from test()] Actual: ["baaabaac", "ba", "aa", "abaac"]<br>
 FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure6'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/perlstress-001.js'>ecma_3/RegExp/perlstress-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=85721' target='other_window'>Bug Number 85721</a><br>
- [ <a href='#failure5'>Previous Failure</a> | <a href='#failure7'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure5'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/perlstress-001.js'>ecma_3/RegExp/perlstress-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=85721' target='other_window'>Bug Number 85721</a><br>
+ [ <a href='#failure4'>Previous Failure</a> | <a href='#failure6'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>STATUS: Testing regular expression edge cases<br>
 Failure messages were:<br>
 FAILED!: [reported from test()] Section 218 of test -<br>
@@ -121,8 +104,8 @@ FAILED!: [reported from test()] Expect: ["aabbaa", "aa", , ]<br>
 FAILED!: [reported from test()] Actual: ["aabbaa", "aa", "bb"]<br>
 FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure7'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-209919.js'>ecma_3/RegExp/regress-209919.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=209919' target='other_window'>Bug Number 209919</a><br>
- [ <a href='#failure6'>Previous Failure</a> | <a href='#failure8'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure6'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/RegExp/regress-209919.js'>ecma_3/RegExp/regress-209919.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=209919' target='other_window'>Bug Number 209919</a><br>
+ [ <a href='#failure5'>Previous Failure</a> | <a href='#failure7'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>STATUS: Testing regexp submatches with quantifiers<br>
 Failure messages were:<br>
 FAILED!: [reported from test()] Section 1 of test -<br>
@@ -161,55 +144,55 @@ FAILED!: [reported from test()] Expect: ["1.000,00", "000", ",00"]<br>
 FAILED!: [reported from test()] Actual: ["1.000,00", "", ",00"]<br>
 FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure8'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Statements/regress-194364.js'>ecma_3/Statements/regress-194364.js</a> failed</b> <br>
- [ <a href='#failure7'>Previous Failure</a> | <a href='#failure9'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure7'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Statements/regress-194364.js'>ecma_3/Statements/regress-194364.js</a> failed</b> <br>
+ [ <a href='#failure6'>Previous Failure</a> | <a href='#failure8'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure9'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-001.js'>ecma_3/Unicode/uc-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=23610' target='other_window'>Bug Number 23610</a><br>
- [ <a href='#failure8'>Previous Failure</a> | <a href='#failure10'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure8'></a><dd><b>Testcase <a target='other_window' href='./ecma_3/Unicode/uc-001.js'>ecma_3/Unicode/uc-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=23610' target='other_window'>Bug Number 23610</a><br>
+ [ <a href='#failure7'>Previous Failure</a> | <a href='#failure9'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>STATUS: Unicode format-control character (Category Cf) test.<br>
 Failure messages were:<br>
 FAILED!: [reported from test()] Unicode format-control character test (Category Cf.)<br>
 FAILED!: [reported from test()] Expected value 'no error', Actual value 'no‎ error'<br>
 FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure10'></a><dd><b>Testcase <a target='other_window' href='./js1_2/Objects/toString-001.js'>js1_2/Objects/toString-001.js</a> failed</b> <br>
- [ <a href='#failure9'>Previous Failure</a> | <a href='#failure11'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure9'></a><dd><b>Testcase <a target='other_window' href='./js1_2/Objects/toString-001.js'>js1_2/Objects/toString-001.js</a> failed</b> <br>
+ [ <a href='#failure8'>Previous Failure</a> | <a href='#failure10'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 var o = new Object(); o.toString() = [object Object] FAILED! expected: {}<br>
 o = {}; o.toString() = [object Object] FAILED! expected: {}<br>
 o = { name:"object", length:0, value:"hello" }; o.toString() = false FAILED! expected: true<br>
 </tt><br>
-<a name='failure11'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/Function_object.js'>js1_2/function/Function_object.js</a> failed</b> <br>
- [ <a href='#failure10'>Previous Failure</a> | <a href='#failure12'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure10'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/Function_object.js'>js1_2/function/Function_object.js</a> failed</b> <br>
+ [ <a href='#failure9'>Previous Failure</a> | <a href='#failure11'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 f.arity = undefined FAILED! expected: 3<br>
-(new Function()).toString() = function anonymous() {} FAILED! expected: <br>
+} FAILED! expected: <br>
 </tt><br>
-<a name='failure12'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/function-001-n.js'>js1_2/function/function-001-n.js</a> failed</b> <br>
- [ <a href='#failure11'>Previous Failure</a> | <a href='#failure13'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure11'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/function-001-n.js'>js1_2/function/function-001-n.js</a> failed</b> <br>
+ [ <a href='#failure10'>Previous Failure</a> | <a href='#failure12'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 3, got 0<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 function-001.js functions not separated by semicolons are errors in version 120 and higher<br>
 eval("function f(){}function g(){}") = undefined FAILED! expected: error<br>
 </tt><br>
-<a name='failure13'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/tostring-1.js'>js1_2/function/tostring-1.js</a> failed</b> <br>
- [ <a href='#failure12'>Previous Failure</a> | <a href='#failure14'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure12'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/tostring-1.js'>js1_2/function/tostring-1.js</a> failed</b> <br>
+ [ <a href='#failure11'>Previous Failure</a> | <a href='#failure13'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 } FAILED! expected: <br>
 } FAILED! expected: <br>
 } FAILED! expected: <br>
 } FAILED! expected: <br>
-f.toString() = function anonymous() {return "hello!"} FAILED! expected: <br>
+} FAILED! expected: <br>
 </tt><br>
-<a name='failure14'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/tostring-2.js'>js1_2/function/tostring-2.js</a> failed</b> <br>
- [ <a href='#failure13'>Previous Failure</a> | <a href='#failure15'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure13'></a><dd><b>Testcase <a target='other_window' href='./js1_2/function/tostring-2.js'>js1_2/function/tostring-2.js</a> failed</b> <br>
+ [ <a href='#failure12'>Previous Failure</a> | <a href='#failure14'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 } FAILED! expected: <br>
@@ -222,22 +205,22 @@ Failure messages were:<br>
 } FAILED! expected: <br>
 } FAILED! expected: <br>
 </tt><br>
-<a name='failure15'></a><dd><b>Testcase <a target='other_window' href='./js1_2/operator/equality.js'>js1_2/operator/equality.js</a> failed</b> <br>
- [ <a href='#failure14'>Previous Failure</a> | <a href='#failure16'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure14'></a><dd><b>Testcase <a target='other_window' href='./js1_2/operator/equality.js'>js1_2/operator/equality.js</a> failed</b> <br>
+ [ <a href='#failure13'>Previous Failure</a> | <a href='#failure15'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 (new String('x') == 'x')                  = true FAILED! expected: false<br>
 ('x' == new String('x'))                  = true FAILED! expected: false<br>
 </tt><br>
-<a name='failure16'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastIndex.js'>js1_2/regexp/RegExp_lastIndex.js</a> failed</b> <br>
- [ <a href='#failure15'>Previous Failure</a> | <a href='#failure17'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure15'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_lastIndex.js'>js1_2/regexp/RegExp_lastIndex.js</a> failed</b> <br>
+ [ <a href='#failure14'>Previous Failure</a> | <a href='#failure16'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 re=/x./g; re.lastIndex=4; re.exec('xyabcdxa') = xa FAILED! expected: ["xa"]<br>
 re.exec('xyabcdef') = xy FAILED! expected: ["xy"]<br>
 </tt><br>
-<a name='failure17'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_multiline.js'>js1_2/regexp/RegExp_multiline.js</a> failed</b> <br>
- [ <a href='#failure16'>Previous Failure</a> | <a href='#failure18'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure16'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_multiline.js'>js1_2/regexp/RegExp_multiline.js</a> failed</b> <br>
+ [ <a href='#failure15'>Previous Failure</a> | <a href='#failure17'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 (multiline == true) '123\n456'.match(/^4../) = null FAILED! expected: 456<br>
@@ -246,8 +229,8 @@ Failure messages were:<br>
 (multiline == true) 'a11\na22\na23\na24'.match(/a..$/g) = a24 FAILED! expected: a11,a22,a23,a24<br>
 (multiline == true) 'a11\na22\na23\na24'.match(new RegExp('a..$','g')) = a24 FAILED! expected: a11,a22,a23,a24<br>
 </tt><br>
-<a name='failure18'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_multiline_as_array.js'>js1_2/regexp/RegExp_multiline_as_array.js</a> failed</b> <br>
- [ <a href='#failure17'>Previous Failure</a> | <a href='#failure19'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure17'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/RegExp_multiline_as_array.js'>js1_2/regexp/RegExp_multiline_as_array.js</a> failed</b> <br>
+ [ <a href='#failure16'>Previous Failure</a> | <a href='#failure18'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 (['$*'] == true) '123\n456'.match(/^4../) = null FAILED! expected: 456<br>
@@ -256,20 +239,20 @@ Failure messages were:<br>
 (['$*'] == true) 'a11\na22\na23\na24'.match(/a..$/g) = a24 FAILED! expected: a11,a22,a23,a24<br>
 (['$*'] == true) 'a11\na22\na23\na24'.match(new RegExp('a..$','g')) = a24 FAILED! expected: a11,a22,a23,a24<br>
 </tt><br>
-<a name='failure19'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/beginLine.js'>js1_2/regexp/beginLine.js</a> failed</b> <br>
- [ <a href='#failure18'>Previous Failure</a> | <a href='#failure20'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure18'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/beginLine.js'>js1_2/regexp/beginLine.js</a> failed</b> <br>
+ [ <a href='#failure17'>Previous Failure</a> | <a href='#failure19'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 123xyz'.match(new RegExp('^\d+')) = null FAILED! expected: 123<br>
 </tt><br>
-<a name='failure20'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/endLine.js'>js1_2/regexp/endLine.js</a> failed</b> <br>
- [ <a href='#failure19'>Previous Failure</a> | <a href='#failure21'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure19'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/endLine.js'>js1_2/regexp/endLine.js</a> failed</b> <br>
+ [ <a href='#failure18'>Previous Failure</a> | <a href='#failure20'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 xyz'.match(new RegExp('\d+$')) = null FAILED! expected: 890<br>
 </tt><br>
-<a name='failure21'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/string_split.js'>js1_2/regexp/string_split.js</a> failed</b> <br>
- [ <a href='#failure20'>Previous Failure</a> | <a href='#failure22'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure20'></a><dd><b>Testcase <a target='other_window' href='./js1_2/regexp/string_split.js'>js1_2/regexp/string_split.js</a> failed</b> <br>
+ [ <a href='#failure19'>Previous Failure</a> | <a href='#failure21'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 'abc'.split(/[a-z]/) = ,,, FAILED! expected: ,,<br>
@@ -277,22 +260,22 @@ Failure messages were:<br>
 'abc'.split(new RegExp('[a-z]')) = ,,, FAILED! expected: ,,<br>
 'abc'.split(new RegExp('[a-z]')) = ,,, FAILED! expected: ,,<br>
 </tt><br>
-<a name='failure22'></a><dd><b>Testcase <a target='other_window' href='./js1_2/version120/boolean-001.js'>js1_2/version120/boolean-001.js</a> failed</b> <br>
- [ <a href='#failure21'>Previous Failure</a> | <a href='#failure23'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure21'></a><dd><b>Testcase <a target='other_window' href='./js1_2/version120/boolean-001.js'>js1_2/version120/boolean-001.js</a> failed</b> <br>
+ [ <a href='#failure20'>Previous Failure</a> | <a href='#failure22'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt><br>
 Failure messages were:<br>
 new Boolean(false) = true FAILED! expected: false<br>
 </tt><br>
-<a name='failure23'></a><dd><b>Testcase <a target='other_window' href='./js1_2/version120/regress-99663.js'>js1_2/version120/regress-99663.js</a> failed</b> <br>
- [ <a href='#failure22'>Previous Failure</a> | <a href='#failure24'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure22'></a><dd><b>Testcase <a target='other_window' href='./js1_2/version120/regress-99663.js'>js1_2/version120/regress-99663.js</a> failed</b> <br>
+ [ <a href='#failure21'>Previous Failure</a> | <a href='#failure23'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>STATUS: Regression test for Bugzilla bug 99663<br>
 Failure messages were:<br>
 Section 1 of test - got Error: Can't find variable: it FAILED! expected: a "read-only" error<br>
 Section 2 of test - got Error: Can't find variable: it FAILED! expected: a "read-only" error<br>
 Section 3 of test - got Error: Can't find variable: it FAILED! expected: a "read-only" error<br>
 </tt><br>
-<a name='failure24'></a><dd><b>Testcase <a target='other_window' href='./js1_3/Script/function-001-n.js'>js1_3/Script/function-001-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=10278' target='other_window'>Bug Number 10278</a><br>
- [ <a href='#failure23'>Previous Failure</a> | <a href='#failure25'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure23'></a><dd><b>Testcase <a target='other_window' href='./js1_3/Script/function-001-n.js'>js1_3/Script/function-001-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=10278' target='other_window'>Bug Number 10278</a><br>
+ [ <a href='#failure22'>Previous Failure</a> | <a href='#failure24'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 3, got 0<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -300,15 +283,15 @@ BUGNUMBER: 10278<br>
 function-001.js functions not separated by semicolons are errors in version 120 and higher<br>
 eval("function f(){}function g(){}") = undefined FAILED! expected: error<br>
 </tt><br>
-<a name='failure25'></a><dd><b>Testcase <a target='other_window' href='./js1_3/Script/script-001.js'>js1_3/Script/script-001.js</a> failed</b> <br>
- [ <a href='#failure24'>Previous Failure</a> | <a href='#failure26'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure24'></a><dd><b>Testcase <a target='other_window' href='./js1_3/Script/script-001.js'>js1_3/Script/script-001.js</a> failed</b> <br>
+ [ <a href='#failure23'>Previous Failure</a> | <a href='#failure25'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 script-001 NativeScript<br>
 </tt><br>
-<a name='failure26'></a><dd><b>Testcase <a target='other_window' href='./js1_3/regress/function-001-n.js'>js1_3/regress/function-001-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=10278' target='other_window'>Bug Number 10278</a><br>
- [ <a href='#failure25'>Previous Failure</a> | <a href='#failure27'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure25'></a><dd><b>Testcase <a target='other_window' href='./js1_3/regress/function-001-n.js'>js1_3/regress/function-001-n.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=10278' target='other_window'>Bug Number 10278</a><br>
+ [ <a href='#failure24'>Previous Failure</a> | <a href='#failure26'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 3, got 0<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -316,90 +299,90 @@ BUGNUMBER: 10278<br>
 function-001.js functions not separated by semicolons are errors in version 120 and higher<br>
 eval("function f(){}function g(){}") = undefined FAILED! expected: error<br>
 </tt><br>
-<a name='failure27'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-001.js'>js1_5/Exceptions/catchguard-001.js</a> failed</b> <br>
+<a name='failure26'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-001.js'>js1_5/Exceptions/catchguard-001.js</a> failed</b> <br>
+ [ <a href='#failure25'>Previous Failure</a> | <a href='#failure27'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<tt>Expected exit code 0, got 3<br>
+Testcase terminated with signal 0<br>
+Complete testcase output was:<br>
+Testcase produced no output!</tt><br>
+<a name='failure27'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-002.js'>js1_5/Exceptions/catchguard-002.js</a> failed</b> <br>
  [ <a href='#failure26'>Previous Failure</a> | <a href='#failure28'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure28'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-002.js'>js1_5/Exceptions/catchguard-002.js</a> failed</b> <br>
+<a name='failure28'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-003.js'>js1_5/Exceptions/catchguard-003.js</a> failed</b> <br>
  [ <a href='#failure27'>Previous Failure</a> | <a href='#failure29'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure29'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/catchguard-003.js'>js1_5/Exceptions/catchguard-003.js</a> failed</b> <br>
+<a name='failure29'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/errstack-001.js'>js1_5/Exceptions/errstack-001.js</a> failed</b> <br>
  [ <a href='#failure28'>Previous Failure</a> | <a href='#failure30'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure30'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/errstack-001.js'>js1_5/Exceptions/errstack-001.js</a> failed</b> <br>
+<a name='failure30'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/regress-50447.js'>js1_5/Exceptions/regress-50447.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=50447' target='other_window'>Bug Number 50447</a><br>
  [ <a href='#failure29'>Previous Failure</a> | <a href='#failure31'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
-Testcase produced no output!</tt><br>
-<a name='failure31'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Exceptions/regress-50447.js'>js1_5/Exceptions/regress-50447.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=50447' target='other_window'>Bug Number 50447</a><br>
+BUGNUMBER: 50447<br>
+STATUS: Test (non-ECMA) Error object properties fileName, lineNumber<br>
+</tt><br>
+<a name='failure31'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-001.js'>js1_5/GetSet/getset-001.js</a> failed</b> <br>
  [ <a href='#failure30'>Previous Failure</a> | <a href='#failure32'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
-BUGNUMBER: 50447<br>
-STATUS: Test (non-ECMA) Error object properties fileName, lineNumber<br>
-</tt><br>
-<a name='failure32'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-001.js'>js1_5/GetSet/getset-001.js</a> failed</b> <br>
+Testcase produced no output!</tt><br>
+<a name='failure32'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-002.js'>js1_5/GetSet/getset-002.js</a> failed</b> <br>
  [ <a href='#failure31'>Previous Failure</a> | <a href='#failure33'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure33'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-002.js'>js1_5/GetSet/getset-002.js</a> failed</b> <br>
+<a name='failure33'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-003.js'>js1_5/GetSet/getset-003.js</a> failed</b> <br>
  [ <a href='#failure32'>Previous Failure</a> | <a href='#failure34'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure34'></a><dd><b>Testcase <a target='other_window' href='./js1_5/GetSet/getset-003.js'>js1_5/GetSet/getset-003.js</a> failed</b> <br>
+<a name='failure34'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-90596-001.js'>js1_5/Object/regress-90596-001.js</a> failed</b> <br>
  [ <a href='#failure33'>Previous Failure</a> | <a href='#failure35'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure35'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-90596-001.js'>js1_5/Object/regress-90596-001.js</a> failed</b> <br>
+<a name='failure35'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-90596-002.js'>js1_5/Object/regress-90596-002.js</a> failed</b> <br>
  [ <a href='#failure34'>Previous Failure</a> | <a href='#failure36'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure36'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-90596-002.js'>js1_5/Object/regress-90596-002.js</a> failed</b> <br>
+<a name='failure36'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-96284-001.js'>js1_5/Object/regress-96284-001.js</a> failed</b> <br>
  [ <a href='#failure35'>Previous Failure</a> | <a href='#failure37'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure37'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-96284-001.js'>js1_5/Object/regress-96284-001.js</a> failed</b> <br>
+<a name='failure37'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-96284-002.js'>js1_5/Object/regress-96284-002.js</a> failed</b> <br>
  [ <a href='#failure36'>Previous Failure</a> | <a href='#failure38'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure38'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Object/regress-96284-002.js'>js1_5/Object/regress-96284-002.js</a> failed</b> <br>
+<a name='failure38'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-44009.js'>js1_5/Regress/regress-44009.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=44009' target='other_window'>Bug Number 44009</a><br>
  [ <a href='#failure37'>Previous Failure</a> | <a href='#failure39'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
-Testcase produced no output!</tt><br>
-<a name='failure39'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-44009.js'>js1_5/Regress/regress-44009.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=44009' target='other_window'>Bug Number 44009</a><br>
- [ <a href='#failure38'>Previous Failure</a> | <a href='#failure40'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
-<tt>Expected exit code 0, got 3<br>
-Testcase terminated with signal 0<br>
-Complete testcase output was:<br>
 BUGNUMBER: 44009<br>
 STATUS: Testing that we don't crash on obj.toSource()<br>
 </tt><br>
-<a name='failure40'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-103602.js'>js1_5/Regress/regress-103602.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=103602' target='other_window'>Bug Number 103602</a><br>
- [ <a href='#failure39'>Previous Failure</a> | <a href='#failure41'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure39'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-103602.js'>js1_5/Regress/regress-103602.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=103602' target='other_window'>Bug Number 103602</a><br>
+ [ <a href='#failure38'>Previous Failure</a> | <a href='#failure40'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>STATUS: Reassignment to a const is NOT an error per ECMA<br>
 Failure messages were:<br>
 FAILED!: [reported from test()] Section 1 of test -<br>
@@ -409,26 +392,26 @@ FAILED!: [reported from test()] Section 3 of test -<br>
 FAILED!: [reported from test()] Expected value '1', Actual value '2'<br>
 FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure41'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-104077.js'>js1_5/Regress/regress-104077.js</a> failed</b> <br>
- [ <a href='#failure40'>Previous Failure</a> | <a href='#failure42'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure40'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-104077.js'>js1_5/Regress/regress-104077.js</a> failed</b> <br>
+ [ <a href='#failure39'>Previous Failure</a> | <a href='#failure41'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure42'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-127557.js'>js1_5/Regress/regress-127557.js</a> failed</b> <br>
- [ <a href='#failure41'>Previous Failure</a> | <a href='#failure43'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure41'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-127557.js'>js1_5/Regress/regress-127557.js</a> failed</b> <br>
+ [ <a href='#failure40'>Previous Failure</a> | <a href='#failure42'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure43'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-172699.js'>js1_5/Regress/regress-172699.js</a> failed</b> <br>
- [ <a href='#failure42'>Previous Failure</a> | <a href='#failure44'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure42'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-172699.js'>js1_5/Regress/regress-172699.js</a> failed</b> <br>
+ [ <a href='#failure41'>Previous Failure</a> | <a href='#failure43'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure44'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-179524.js'>js1_5/Regress/regress-179524.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=179524' target='other_window'>Bug Number 179524</a><br>
- [ <a href='#failure43'>Previous Failure</a> | <a href='#failure45'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure43'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Regress/regress-179524.js'>js1_5/Regress/regress-179524.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=179524' target='other_window'>Bug Number 179524</a><br>
+ [ <a href='#failure42'>Previous Failure</a> | <a href='#failure44'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>STATUS: Don't crash on extraneous arguments to str.match(), etc.<br>
 Failure messages were:<br>
 FAILED!: [reported from test()] Section 14 of test -<br>
@@ -478,14 +461,14 @@ FAILED!: [reported from test()] Section 36 of test -<br>
 FAILED!: [reported from test()] Expected value 'SHOULD HAVE FALLEN INTO CATCH-BLOCK!', Actual value 'ABC Zbc'<br>
 FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure45'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/regress-220584.js'>js1_5/Scope/regress-220584.js</a> failed</b> <br>
- [ <a href='#failure44'>Previous Failure</a> | <a href='#failure46'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure44'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/regress-220584.js'>js1_5/Scope/regress-220584.js</a> failed</b> <br>
+ [ <a href='#failure43'>Previous Failure</a> | <a href='#failure45'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure46'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/scope-001.js'>js1_5/Scope/scope-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=53268' target='other_window'>Bug Number 53268</a><br>
- [ <a href='#failure45'>Previous Failure</a> | <a href='#failure47'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure45'></a><dd><b>Testcase <a target='other_window' href='./js1_5/Scope/scope-001.js'>js1_5/Scope/scope-001.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=53268' target='other_window'>Bug Number 53268</a><br>
+ [ <a href='#failure44'>Previous Failure</a> | <a href='#failure46'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>STATUS: Testing scope after changing obj.__proto__<br>
 Failure messages were:<br>
 FAILED!: [reported from test()] Step 1:  setting obj.__proto__ = global object<br>
@@ -496,8 +479,8 @@ FAILED!: [reported from test()] Type mismatch, expected type undefined, actual t
 FAILED!: [reported from test()] Expected value 'undefined', Actual value '1'<br>
 FAILED!: [reported from test()] <br>
 </tt><br>
-<a name='failure47'></a><dd><b>Testcase <a target='other_window' href='./js1_6/Regress/regress-301574.js'>js1_6/Regress/regress-301574.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=301574' target='other_window'>Bug Number 301574</a><br>
- [ <a href='#failure46'>Previous Failure</a> | <a href='#failure48'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure46'></a><dd><b>Testcase <a target='other_window' href='./js1_6/Regress/regress-301574.js'>js1_6/Regress/regress-301574.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=301574' target='other_window'>Bug Number 301574</a><br>
+ [ <a href='#failure45'>Previous Failure</a> | <a href='#failure47'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>STATUS: E4X should be enabled even when e4x=1 not specified<br>
 Failure messages were:<br>
 FAILED!: E4X should be enabled even when e4x=1 not specified: XML()<br>
@@ -507,20 +490,20 @@ FAILED!: E4X should be enabled even when e4x=1 not specified: XMLList()<br>
 FAILED!: Expected value 'No error', Actual value 'error: ReferenceError: Can't find variable: XML'<br>
 FAILED!: <br>
 </tt><br>
-<a name='failure48'></a><dd><b>Testcase <a target='other_window' href='./js1_6/Regress/regress-309242.js'>js1_6/Regress/regress-309242.js</a> failed</b> <br>
- [ <a href='#failure47'>Previous Failure</a> | <a href='#failure49'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure47'></a><dd><b>Testcase <a target='other_window' href='./js1_6/Regress/regress-309242.js'>js1_6/Regress/regress-309242.js</a> failed</b> <br>
+ [ <a href='#failure46'>Previous Failure</a> | <a href='#failure48'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure49'></a><dd><b>Testcase <a target='other_window' href='./js1_6/Regress/regress-314887.js'>js1_6/Regress/regress-314887.js</a> failed</b> <br>
- [ <a href='#failure48'>Previous Failure</a> | <a href='#failure50'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure48'></a><dd><b>Testcase <a target='other_window' href='./js1_6/Regress/regress-314887.js'>js1_6/Regress/regress-314887.js</a> failed</b> <br>
+ [ <a href='#failure47'>Previous Failure</a> | <a href='#failure49'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
 Testcase produced no output!</tt><br>
-<a name='failure50'></a><dd><b>Testcase <a target='other_window' href='./js1_6/String/regress-306591.js'>js1_6/String/regress-306591.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=306591' target='other_window'>Bug Number 306591</a><br>
- [ <a href='#failure49'>Previous Failure</a> | <a href='#failure51'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
+<a name='failure49'></a><dd><b>Testcase <a target='other_window' href='./js1_6/String/regress-306591.js'>js1_6/String/regress-306591.js</a> failed</b> <a href='http://bugzilla.mozilla.org/show_bug.cgi?id=306591' target='other_window'>Bug Number 306591</a><br>
+ [ <a href='#failure48'>Previous Failure</a> | <a href='#failure50'>Next Failure</a> | <a href='#tippy_top'>Top of Page</a> ]<br>
 <tt>Expected exit code 0, got 3<br>
 Testcase terminated with signal 0<br>
 Complete testcase output was:<br>
@@ -534,12 +517,11 @@ STATUS: See https://bugzilla.mozilla.org/show_bug.cgi?id=304828<br>
 <pre>
 <a name='retest_list'></a>
 <h2>Retest List</h2><br>
-# Retest List, squirrelfish, generated Thu Sep 18 02:24:54 2008.
+# Retest List, squirrelfish, generated Tue Apr 21 12:56:28 2009.
 # Original test base was: All tests.
-# 1127 of 1135 test(s) were completed, 50 failures reported.
+# 1119 of 1127 test(s) were completed, 49 failures reported.
 ecma/TypeConversion/9.3.1-3.js
 ecma_2/Exceptions/function-001.js
-ecma_3/Date/15.9.5.7.js
 ecma_3/FunExpr/fe-001.js
 ecma_3/RegExp/15.10.2-1.js
 ecma_3/RegExp/perlstress-001.js
@@ -586,4 +568,4 @@ js1_5/Scope/scope-001.js
 js1_6/Regress/regress-301574.js
 js1_6/Regress/regress-309242.js
 js1_6/Regress/regress-314887.js
-js1_6/String/regress-306591.js
+js1_6/String/regress-306591.js
\ No newline at end of file
index 32e016fd783429c6618ec0ae4fa72132e98dddc5..145a1cee8f3604d9e527562b725807ef6ab96fa5 100644 (file)
@@ -77,7 +77,7 @@ CompiledRegExp Generator::compileRegExp(JSGlobalData* globalData, const UString&
     }
 
     *numSubpatterns_ptr = parser.numSubpatterns();
-    pool = globalData->poolForSize(generator.size());
+    pool = globalData->executableAllocator.poolForSize(generator.size());
     return reinterpret_cast<CompiledRegExp>(generator.copyCode(pool.get()));
 }
 
index 4b5f3d407a2588ec9cb8735c962303b1627520aa..e2e8abaf05ec128cc5806c97d2020e2b0b9740fb 100644 (file)
@@ -40,16 +40,7 @@ namespace JSC { namespace WREC {
 
 void Generator::generateEnter()
 {
-#if PLATFORM(X86_64)
-    // On x86-64 edi and esi are caller preserved, so nothing to do here.
-    // The four arguments have been passed in the registers %rdi, %rsi,
-    // %rdx, %rcx - shuffle these into the expected locations.
-    move(X86::edi, input); // (arg 1) edi -> eax
-    move(X86::ecx, output); // (arg 4) ecx -> edi
-    move(X86::edx, length); // (arg 3) edx -> ecx
-    move(X86::esi, index); // (arg 2) esi -> edx
-
-#else
+#if PLATFORM(X86)
     // On x86 edi & esi are callee preserved registers.
     push(X86::edi);
     push(X86::esi);
@@ -67,24 +58,20 @@ void Generator::generateEnter()
     peek(output, 3);
 #endif
 #endif
-
-#ifndef NDEBUG
-    // ASSERT that the output register is not null.
-    Jump outputNotNull = jnzPtr(output);
-    breakpoint();
-    outputNotNull.link(this);
-#endif
 }
 
 void Generator::generateReturnSuccess()
 {
+    ASSERT(returnRegister != index);
+    ASSERT(returnRegister != output);
+
     // Set return value.
-    pop(X86::eax); // match begin
-    store32(X86::eax, output);
+    pop(returnRegister); // match begin
+    store32(returnRegister, output);
     store32(index, Address(output, 4)); // match end
     
     // Restore callee save registers.
-#if !PLATFORM(X86_64)
+#if PLATFORM(X86)
     pop(X86::esi);
     pop(X86::edi);
 #endif
@@ -100,14 +87,14 @@ void Generator::generateIncrementIndex(Jump* failure)
 {
     peek(index);
     if (failure)
-        *failure = je32(length, index);
+        *failure = branch32(Equal, length, index);
     add32(Imm32(1), index);
     poke(index);
 }
 
 void Generator::generateLoadCharacter(JumpList& failures)
 {
-    failures.append(je32(length, index));
+    failures.append(branch32(Equal, length, index));
     load16(BaseIndex(input, index, TimesTwo), character);
 }
 
@@ -115,14 +102,15 @@ void Generator::generateLoadCharacter(JumpList& failures)
 // were part of the input string.
 void Generator::generateJumpIfNotEndOfInput(Label target)
 {
-    jle32(index, length, target);
+    branch32(LessThanOrEqual, index, length, target);
 }
 
 void Generator::generateReturnFailure()
 {
     pop();
-    move(Imm32(-1), X86::eax);
-#if !PLATFORM(X86_64)
+    move(Imm32(-1), returnRegister);
+
+#if PLATFORM(X86)
     pop(X86::esi);
     pop(X86::edi);
 #endif
@@ -145,7 +133,7 @@ void Generator::generateBackreferenceQuantifier(JumpList& failures, Quantifier::
     GenerateBackreferenceFunctor functor(subpatternId);
 
     load32(Address(output, (2 * subpatternId) * sizeof(int)), character);
-    Jump skipIfEmpty = je32(Address(output, ((2 * subpatternId) + 1) * sizeof(int)), character);
+    Jump skipIfEmpty = branch32(Equal, Address(output, ((2 * subpatternId) + 1) * sizeof(int)), character);
 
     ASSERT(quantifierType == Quantifier::Greedy || quantifierType == Quantifier::NonGreedy);
     if (quantifierType == Quantifier::Greedy)
@@ -175,7 +163,7 @@ void Generator::generateNonGreedyQuantifier(JumpList& failures, GenerateAtomFunc
     Label alternativeFailed(this);
     pop(index);
     if (max != Quantifier::Infinity)
-        je32(repeatCount, Imm32(max), quantifierFailed);
+        branch32(Equal, repeatCount, Imm32(max), quantifierFailed);
 
     // (1) Read an atom.
     if (min)
@@ -187,7 +175,7 @@ void Generator::generateNonGreedyQuantifier(JumpList& failures, GenerateAtomFunc
     
     // (2) Keep reading if we're under the minimum.
     if (min > 1)
-        jl32(repeatCount, Imm32(min), readAtom);
+        branch32(LessThan, repeatCount, Imm32(min), readAtom);
 
     // (3) Test the rest of the alternative.
     if (!min)
@@ -221,7 +209,7 @@ void Generator::generateGreedyQuantifier(JumpList& failures, GenerateAtomFunctor
     else if (max == 1)
         doneReadingAtomsList.append(jump());
     else {
-        jne32(repeatCount, Imm32(max), readAtom);
+        branch32(NotEqual, repeatCount, Imm32(max), readAtom);
         doneReadingAtomsList.append(jump());
     }
 
@@ -238,7 +226,7 @@ void Generator::generateGreedyQuantifier(JumpList& failures, GenerateAtomFunctor
 
     // (2) Verify that we have enough atoms.
     doneReadingAtomsList.link(this);
-    jl32(repeatCount, Imm32(min), quantifierFailed);
+    branch32(LessThan, repeatCount, Imm32(min), quantifierFailed);
 
     // (3) Test the rest of the alternative.
     push(index);
@@ -277,7 +265,7 @@ bool Generator::generatePatternCharacterPair(JumpList& failures, int ch1, int ch
 
     // Optimistically consume 2 characters.
     add32(Imm32(2), index);
-    failures.append(jg32(index, length));
+    failures.append(branch32(GreaterThan, index, length));
 
     // Load the characters we just consumed, offset -2 characters from index.
     load32(BaseIndex(input, index, TimesTwo, -2 * 2), character);
@@ -306,7 +294,7 @@ bool Generator::generatePatternCharacterPair(JumpList& failures, int ch1, int ch
     }
     int pair = ch1 | (ch2 << 16);
 
-    failures.append(jne32(character, Imm32(pair)));
+    failures.append(branch32(NotEqual, character, Imm32(pair)));
     return true;
 }
 
@@ -328,14 +316,14 @@ void Generator::generatePatternCharacter(JumpList& failures, int ch)
             ch |= 32;
         } else if (!isASCII(ch) && ((lower = Unicode::toLower(ch)) != (upper = Unicode::toUpper(ch)))) {
             // handle unicode case sentitive characters - branch to success on upper
-            isUpper = je32(character, Imm32(upper));
+            isUpper = branch32(Equal, character, Imm32(upper));
             hasUpper = true;
             ch = lower;
         }
     }
     
     // checks for ch, or lower case version of ch, if insensitive
-    failures.append(jne32(character, Imm32((unsigned short)ch)));
+    failures.append(branch32(NotEqual, character, Imm32((unsigned short)ch)));
 
     if (m_parser.ignoreCase() && hasUpper) {
         // for unicode case insensitive matches, branch here if upper matches.
@@ -357,33 +345,33 @@ void Generator::generateCharacterClassInvertedRange(JumpList& failures, JumpList
         // check if there are any ranges or matches below lo.  If not, just jl to failure -
         // if there is anything else to check, check that first, if it falls through jmp to failure.
         if ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {
-            Jump loOrAbove = jge32(character, Imm32((unsigned short)lo));
+            Jump loOrAbove = branch32(GreaterThanOrEqual, character, Imm32((unsigned short)lo));
             
             // generate code for all ranges before this one
             if (which)
                 generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
             
             while ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {
-                matchDest.append(je32(character, Imm32((unsigned short)matches[*matchIndex])));
+                matchDest.append(branch32(Equal, character, Imm32((unsigned short)matches[*matchIndex])));
                 ++*matchIndex;
             }
             failures.append(jump());
 
             loOrAbove.link(this);
         } else if (which) {
-            Jump loOrAbove = jge32(character, Imm32((unsigned short)lo));
+            Jump loOrAbove = branch32(GreaterThanOrEqual, character, Imm32((unsigned short)lo));
 
             generateCharacterClassInvertedRange(failures, matchDest, ranges, which, matchIndex, matches, matchCount);
             failures.append(jump());
 
             loOrAbove.link(this);
         } else
-            failures.append(jl32(character, Imm32((unsigned short)lo)));
+            failures.append(branch32(LessThan, character, Imm32((unsigned short)lo)));
 
         while ((*matchIndex < matchCount) && (matches[*matchIndex] <= hi))
             ++*matchIndex;
 
-        matchDest.append(jle32(character, Imm32((unsigned short)hi)));
+        matchDest.append(branch32(LessThanOrEqual, character, Imm32((unsigned short)hi)));
         // fall through to here, the value is above hi.
 
         // shuffle along & loop around if there are any more matches to handle.
@@ -397,12 +385,12 @@ void Generator::generateCharacterClassInverted(JumpList& matchDest, const Charac
 {
     Jump unicodeFail;
     if (charClass.numMatchesUnicode || charClass.numRangesUnicode) {
-        Jump isAscii = jle32(character, Imm32(0x7f));
+        Jump isAscii = branch32(LessThanOrEqual, character, Imm32(0x7f));
     
         if (charClass.numMatchesUnicode) {
             for (unsigned i = 0; i < charClass.numMatchesUnicode; ++i) {
                 UChar ch = charClass.matchesUnicode[i];
-                matchDest.append(je32(character, Imm32(ch)));
+                matchDest.append(branch32(Equal, character, Imm32(ch)));
             }
         }
         
@@ -411,8 +399,8 @@ void Generator::generateCharacterClassInverted(JumpList& matchDest, const Charac
                 UChar lo = charClass.rangesUnicode[i].begin;
                 UChar hi = charClass.rangesUnicode[i].end;
                 
-                Jump below = jl32(character, Imm32(lo));
-                matchDest.append(jle32(character, Imm32(hi)));
+                Jump below = branch32(LessThan, character, Imm32(lo));
+                matchDest.append(branch32(LessThanOrEqual, character, Imm32(hi)));
                 below.link(this);
             }
         }
@@ -426,7 +414,7 @@ void Generator::generateCharacterClassInverted(JumpList& matchDest, const Charac
         JumpList failures; 
         generateCharacterClassInvertedRange(failures, matchDest, charClass.ranges, charClass.numRanges, &matchIndex, charClass.matches, charClass.numMatches);
         while (matchIndex < charClass.numMatches)
-            matchDest.append(je32(character, Imm32((unsigned short)charClass.matches[matchIndex++])));
+            matchDest.append(branch32(Equal, character, Imm32((unsigned short)charClass.matches[matchIndex++])));
 
         failures.link(this);
     } else if (charClass.numMatches) {
@@ -443,13 +431,13 @@ void Generator::generateCharacterClassInverted(JumpList& matchDest, const Charac
                 if (isASCIIUpper(ch))
                     continue;
             }
-            matchDest.append(je32(character, Imm32((unsigned short)ch)));
+            matchDest.append(branch32(Equal, character, Imm32((unsigned short)ch)));
         }
 
         if (unsigned countAZaz = matchesAZaz.size()) {
             or32(Imm32(32), character);
             for (unsigned i = 0; i < countAZaz; ++i)
-                matchDest.append(je32(character, Imm32(matchesAZaz[i])));
+                matchDest.append(branch32(Equal, character, Imm32(matchesAZaz[i])));
         }
     }
 
@@ -533,7 +521,7 @@ void Generator::generateAssertionBOL(JumpList& failures)
         JumpList previousIsNewline;
 
         // begin of input == success
-        previousIsNewline.append(je32(index, Imm32(0)));
+        previousIsNewline.append(branch32(Equal, index, Imm32(0)));
 
         // now check prev char against newline characters.
         load16(BaseIndex(input, index, TimesTwo, -2), character);
@@ -543,7 +531,7 @@ void Generator::generateAssertionBOL(JumpList& failures)
 
         previousIsNewline.link(this);
     } else
-        failures.append(jne32(index, Imm32(0)));
+        failures.append(branch32(NotEqual, index, Imm32(0)));
 }
 
 void Generator::generateAssertionEOL(JumpList& failures)
@@ -556,7 +544,7 @@ void Generator::generateAssertionEOL(JumpList& failures)
         failures.append(jump());
         nextIsNewline.link(this);
     } else {
-        failures.append(jne32(length, index));
+        failures.append(branch32(NotEqual, length, index));
     }
 }
 
@@ -568,7 +556,7 @@ void Generator::generateAssertionWordBoundary(JumpList& failures, bool invert)
     // (1) Check if the previous value was a word char
 
     // (1.1) check for begin of input
-    Jump atBegin = je32(index, Imm32(0));
+    Jump atBegin = branch32(Equal, index, Imm32(0));
     // (1.2) load the last char, and chck if is word character
     load16(BaseIndex(input, index, TimesTwo, -2), character);
     JumpList previousIsWord;
@@ -625,14 +613,14 @@ void Generator::generateBackreference(JumpList& failures, unsigned subpatternId)
     skipIncrement.link(this);
 
     // check if we're at the end of backref (if we are, success!)
-    Jump endOfBackRef = je32(Address(output, ((2 * subpatternId) + 1) * sizeof(int)), repeatCount);
+    Jump endOfBackRef = branch32(Equal, Address(output, ((2 * subpatternId) + 1) * sizeof(int)), repeatCount);
 
     load16(BaseIndex(input, repeatCount, MacroAssembler::TimesTwo), character);
 
     // check if we've run out of input (this would be a can o'fail)
-    Jump endOfInput = je32(length, index);
+    Jump endOfInput = branch32(Equal, length, index);
 
-    je16(character, BaseIndex(input, index, TimesTwo), topOfLoop);
+    branch16(Equal, BaseIndex(input, index, TimesTwo), character, topOfLoop);
 
     endOfInput.link(this);
 
index af4101a934c4f2bbc31c0790f8d82afd4bf5aa9f..8562cac9b3710fd1b8724999b392cd44374dd918 100644 (file)
@@ -62,13 +62,29 @@ namespace JSC {
         {
         }
 
+#if PLATFORM(X86)
         static const RegisterID input = X86::eax;
-        static const RegisterID length = X86::ecx;
         static const RegisterID index = X86::edx;
-        static const RegisterID character = X86::esi;
+        static const RegisterID length = X86::ecx;
         static const RegisterID output = X86::edi;
+
+        static const RegisterID character = X86::esi;
         static const RegisterID repeatCount = X86::ebx; // How many times the current atom repeats in the current match.
-        
+
+        static const RegisterID returnRegister = X86::eax;
+#endif
+#if PLATFORM(X86_64)
+        static const RegisterID input = X86::edi;
+        static const RegisterID index = X86::esi;
+        static const RegisterID length = X86::edx;
+        static const RegisterID output = X86::ecx;
+
+        static const RegisterID character = X86::eax;
+        static const RegisterID repeatCount = X86::ebx; // How many times the current atom repeats in the current match.
+
+        static const RegisterID returnRegister = X86::eax;
+#endif
+
         void generateEnter();
         void generateSaveIndex();
         void generateIncrementIndex(Jump* failure = 0);
index 0c2ca70d5d7ccc6152d57de8377fdb39a595ffda..0c3c29fb3acf22d188f899f019f70768d8a65366 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -149,4 +149,18 @@ namespace WTF {
     inline bool isASCIIPrintable(int c) { return c >= ' ' && c <= '~'; }
 }
 
+using WTF::isASCII;
+using WTF::isASCIIAlpha;
+using WTF::isASCIIAlphanumeric;
+using WTF::isASCIIDigit;
+using WTF::isASCIIHexDigit;
+using WTF::isASCIILower;
+using WTF::isASCIIOctalDigit;
+using WTF::isASCIIPrintable;
+using WTF::isASCIISpace;
+using WTF::isASCIIUpper;
+using WTF::toASCIIHexValue;
+using WTF::toASCIILower;
+using WTF::toASCIIUpper;
+
 #endif
index 18db8ff4596833d014de127e553c9cc5a58422b4..d7470e7f956588eacbb6362efc591f4de74baeb6 100644 (file)
@@ -764,7 +764,7 @@ AVLTree<Abstractor, maxDepth, BSet>::remove(key k)
 
     handle h = abs.root;
     handle parent = null(), child;
-    int cmp, cmp_shortened_sub_with_path;
+    int cmp, cmp_shortened_sub_with_path = 0;
 
     for (;;) {
         if (h == null())
index d629545b46590fb769da1af3c439dd8ceee6a405..4b261ca0cdbe389b092a63df9c8f3dfd71acbfaf 100644 (file)
@@ -32,7 +32,7 @@
 
 #include <CoreFoundation/CFString.h>
 
-#if COMPILER(MSVC) && !PLATFORM(WIN_CE)
+#if COMPILER(MSVC) && !PLATFORM(WINCE)
 #ifndef WINVER
 #define WINVER 0x0500
 #endif
@@ -51,7 +51,7 @@ static void vprintf_stderr_common(const char* format, va_list args)
     if (strstr(format, "%@")) {
         CFStringRef cfFormat = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8);
         CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, cfFormat, args);
-        
+
         int length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8);
         char* buffer = (char*)malloc(length + 1);
 
index c17e501fa246f130af918f31df6ee519dc2a42c7..7e585a5e77f4d52c66dab305c447987df7544de4 100644 (file)
@@ -44,6 +44,8 @@
 
 #include "Platform.h"
 
+#include <stdbool.h>
+
 #if COMPILER(MSVC)
 #include <stddef.h>
 #else
 #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) 
 #endif
 
+/* This macro is needed to prevent the clang static analyzer from generating false-positive reports in ASSERT() macros. */
+#ifdef __clang__
+#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
+#else
+#define CLANG_ANALYZER_NORETURN
+#endif
+
 /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
 
 #ifdef __cplusplus
@@ -105,10 +114,10 @@ typedef struct {
     WTFLogChannelState state;
 } WTFLogChannel;
 
-void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
-void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
-void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
-void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
+void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion) CLANG_ANALYZER_NORETURN;
+void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) CLANG_ANALYZER_NORETURN WTF_ATTRIBUTE_PRINTF(5, 6);
+void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion) CLANG_ANALYZER_NORETURN;
+void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) CLANG_ANALYZER_NORETURN WTF_ATTRIBUTE_PRINTF(4, 5);
 void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
 void WTFLog(WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
 void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
@@ -128,7 +137,7 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
 
 /* ASSERT, ASSERT_WITH_MESSAGE, ASSERT_NOT_REACHED */
 
-#if PLATFORM(WIN_CE)
+#if PLATFORM(WINCE) && !PLATFORM(TORCHMOBILE)
 /* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
 #include <windows.h>
 #undef min
@@ -194,7 +203,7 @@ while (0)
 
 /* COMPILE_ASSERT */
 #ifndef COMPILE_ASSERT
-#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
+#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
 #endif
 
 /* FATAL */
index 865c30ec231c70c3bb861ca8a00f5433220446da..33f0877f06e5510d720cacf1bc1f321033f651ec 100644 (file)
@@ -69,8 +69,7 @@ namespace WTF {
 
     private:
         ByteArray(size_t size)
-            : RefCountedBase(1)
-            , m_size(size)
+            : m_size(size)
         {
         }
         size_t m_size;
diff --git a/wtf/CrossThreadRefCounted.h b/wtf/CrossThreadRefCounted.h
new file mode 100644 (file)
index 0000000..103b2a1
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CrossThreadRefCounted_h
+#define CrossThreadRefCounted_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Threading.h>
+
+namespace WTF {
+
+    // Used to allowing sharing data across classes and threads (like ThreadedSafeShared).
+    //
+    // Why not just use ThreadSafeShared?
+    // ThreadSafeShared can have a significant perf impact when used in low level classes
+    // (like UString) that get ref/deref'ed a lot. This class has the benefit of doing fast ref
+    // counts like RefPtr whenever possible, but it has the downside that you need to copy it
+    // to use it on another thread.
+    //
+    // Is this class threadsafe?
+    // While each instance of the class is not threadsafe, the copied instance is threadsafe
+    // with respect to the original and any other copies.  The underlying m_data is jointly
+    // owned by the original instance and all copies.
+    template<class T>
+    class CrossThreadRefCounted : Noncopyable {
+    public:
+        static PassRefPtr<CrossThreadRefCounted<T> > create(T* data)
+        {
+            return adoptRef(new CrossThreadRefCounted<T>(data, 0));
+        }
+
+        // Used to make an instance that can be used on another thread.
+        PassRefPtr<CrossThreadRefCounted<T> > crossThreadCopy();
+
+        void ref();
+        void deref();
+        T* release();
+
+        bool isShared() const
+        {
+            return !m_refCounter.hasOneRef() || (m_threadSafeRefCounter && !m_threadSafeRefCounter->hasOneRef());
+        }
+
+#ifndef NDEBUG
+        bool mayBePassedToAnotherThread() const { ASSERT(!m_threadId); return m_refCounter.hasOneRef(); }
+#endif
+
+    private:
+        CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter)
+            : m_threadSafeRefCounter(threadedCounter)
+            , m_data(data)
+#ifndef NDEBUG
+            , m_threadId(0)
+#endif
+        {
+        }
+
+        ~CrossThreadRefCounted()
+        {
+            if (!m_threadSafeRefCounter)
+                delete m_data;
+        }
+
+        void threadSafeDeref();
+
+        RefCountedBase m_refCounter;
+        ThreadSafeSharedBase* m_threadSafeRefCounter;
+        T* m_data;
+#ifndef NDEBUG
+        ThreadIdentifier m_threadId;
+#endif
+    };
+
+    template<class T>
+    void CrossThreadRefCounted<T>::ref()
+    {
+        
+        // MobileSafari allocates content on the UI thread then
+        // frees it on the Web thread. This is ok. This occurs in a
+        // couple of places. In particular, http://maps.google.com
+        // which uses JS to add an iFrame with an about:blank URL and 
+        // then executes some JS. Much of this work happens on the
+        // main (UI) thread.
+        // Ideally we want to have this assert here:
+        // ASSERT(WebThreadIsLockedOrDisabled())
+        // but then we would need to include code from
+        // WebCore. So just don't do any ASSERTs here.
+        m_refCounter.ref();
+#ifndef NDEBUG
+        // Store the threadId as soon as the ref count gets to 2.
+        // The class gets created with a ref count of 1 and then passed
+        // to another thread where to ref count get increased.  This
+        // is a heuristic but it seems to always work and has helped
+        // find some bugs.
+        if (!m_threadId && m_refCounter.refCount() == 2)
+            m_threadId = currentThread();
+#endif
+    }
+
+    template<class T>
+    void CrossThreadRefCounted<T>::deref()
+    {
+        // MobileSafari allocates content on the UI thread then
+        // frees it on the Web thread. This is ok. This occurs in a
+        // couple of places. In particular, http://maps.google.com
+        // which uses JS to add an iFrame with an about:blank URL and 
+        // then executes some JS. Much of this work happens on the
+        // main (UI) thread.
+        // Ideally we want to have this assert here:
+        // ASSERT(WebThreadIsLockedOrDisabled())
+        // but then we would need to include code from
+        // WebCore. So just don't do any ASSERTs here.
+        if (m_refCounter.derefBase()) {
+            threadSafeDeref();
+            delete this;
+        } else {
+#ifndef NDEBUG
+            // Clear the threadId when the ref goes to 1 because it
+            // is safe to be passed to another thread at this point.
+            if (m_threadId && m_refCounter.refCount() == 1)
+                m_threadId = 0;
+#endif
+        }
+    }
+
+    template<class T>
+    T* CrossThreadRefCounted<T>::release()
+    {
+        ASSERT(!isShared());
+
+        T* data = m_data;
+        m_data = 0;
+        return data;
+    }
+
+    template<class T>
+    PassRefPtr<CrossThreadRefCounted<T> > CrossThreadRefCounted<T>::crossThreadCopy()
+    {
+        if (m_threadSafeRefCounter)
+            m_threadSafeRefCounter->ref();
+        else
+            m_threadSafeRefCounter = new ThreadSafeSharedBase(2);
+        return adoptRef(new CrossThreadRefCounted<T>(m_data, m_threadSafeRefCounter));
+    }
+
+
+    template<class T>
+    void CrossThreadRefCounted<T>::threadSafeDeref()
+    {
+        if (m_threadSafeRefCounter && m_threadSafeRefCounter->derefBase()) {
+            delete m_threadSafeRefCounter;
+            m_threadSafeRefCounter = 0;
+        }
+    }
+} // namespace WTF
+
+using WTF::CrossThreadRefCounted;
+
+#endif // CrossThreadRefCounted_h
index f23495fa6840e4d89cf2e5c70274f3ce4fd559b4..38bc4ef6bcff45f255aa3129223dc6cbaad86df9 100644 (file)
 #include "config.h"
 #include "CurrentTime.h"
 
-#if PLATFORM(MAC)
-#include <CoreFoundation/CFDate.h>
-#elif PLATFORM(GTK)
-#include <glib.h>
-#elif PLATFORM(WX)
-#include <wx/datetime.h>
-#elif PLATFORM(WIN_OS)
+#if PLATFORM(WIN_OS)
+// Windows is first since we want to use hires timers, despite PLATFORM(CF)
+// being defined.
 // If defined, WIN32_LEAN_AND_MEAN disables timeBeginPeriod/timeEndPeriod.
 #undef WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <sys/timeb.h>
 #include <sys/types.h>
 #include <time.h>
+#elif PLATFORM(CF)
+#include <CoreFoundation/CFDate.h>
+#elif PLATFORM(GTK)
+#include <glib.h>
+#elif PLATFORM(WX)
+#include <wx/datetime.h>
 #else // Posix systems relying on the gettimeofday()
 #include <sys/time.h>
 #endif
@@ -55,35 +57,7 @@ namespace WTF {
 
 const double msPerSecond = 1000.0;
 
-#if PLATFORM(MAC)
-
-double currentTime()
-{
-    return CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970;
-}
-
-#elif PLATFORM(GTK)
-
-// Note: GTK on Windows will pick up the PLATFORM(WIN) implementation above which provides
-// better accuracy compared with Windows implementation of g_get_current_time:
-// (http://www.google.com/codesearch/p?hl=en#HHnNRjks1t0/glib-2.5.2/glib/gmain.c&q=g_get_current_time).
-// Non-Windows GTK builds could use gettimeofday() directly but for the sake of consistency lets use GTK function.
-double currentTime()
-{
-    GTimeVal now;
-    g_get_current_time(&now);
-    return static_cast<double>(now.tv_sec) + static_cast<double>(now.tv_usec / 1000000.0);
-}
-
-#elif PLATFORM(WX)
-
-double currentTime()
-{
-    wxDateTime now = wxDateTime::UNow();
-    return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0);
-}
-
-#elif PLATFORM(WIN_OS)
+#if PLATFORM(WIN_OS)
 
 static LARGE_INTEGER qpcFrequency;
 static bool syncedTime;
@@ -133,7 +107,7 @@ static double highResUpTime()
 
 static double lowResUTCTime()
 {
-#if PLATFORM(WIN_CE)
+#if PLATFORM(WINCE)
     SYSTEMTIME systemTime;
     GetSystemTime(&systemTime);
     struct tm tmtime;
@@ -146,11 +120,11 @@ static double lowResUTCTime()
     tmtime.tm_sec = systemTime.wSecond;
     time_t timet = mktime(&tmtime);
     return timet * msPerSecond + systemTime.wMilliseconds;
-#else // PLATFORM(WIN_CE)
+#else
     struct _timeb timebuffer;
     _ftime(&timebuffer);
     return timebuffer.time * msPerSecond + timebuffer.millitm;
-#endif // PLATFORM(WIN_CE)
+#endif
 }
 
 static bool qpcAvailable()
@@ -210,6 +184,34 @@ double currentTime()
     return utc / 1000.0;
 }
 
+#elif PLATFORM(CF)
+
+double currentTime()
+{
+    return CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970;
+}
+
+#elif PLATFORM(GTK)
+
+// Note: GTK on Windows will pick up the PLATFORM(WIN) implementation above which provides
+// better accuracy compared with Windows implementation of g_get_current_time:
+// (http://www.google.com/codesearch/p?hl=en#HHnNRjks1t0/glib-2.5.2/glib/gmain.c&q=g_get_current_time).
+// Non-Windows GTK builds could use gettimeofday() directly but for the sake of consistency lets use GTK function.
+double currentTime()
+{
+    GTimeVal now;
+    g_get_current_time(&now);
+    return static_cast<double>(now.tv_sec) + static_cast<double>(now.tv_usec / 1000000.0);
+}
+
+#elif PLATFORM(WX)
+
+double currentTime()
+{
+    wxDateTime now = wxDateTime::UNow();
+    return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0);
+}
+
 #else // Other Posix systems rely on the gettimeofday().
 
 double currentTime()
index 2e75c2f39110fa3b88a79990355370ba095f62a9..31f1ec8753057991deeb06bb62cab7608621907b 100644 (file)
@@ -36,7 +36,7 @@ namespace WTF {
 
     // Returns the current system (UTC) time in seconds, starting January 1, 1970.
     // Precision varies depending on a platform but usually is as good or better 
-    // then a millisecond.
+    // than a millisecond.
     double currentTime();
 
 } // namespace WTF
diff --git a/wtf/DateMath.cpp b/wtf/DateMath.cpp
new file mode 100644 (file)
index 0000000..1d480ee
--- /dev/null
@@ -0,0 +1,912 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. 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
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above.  If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#include "config.h"
+#include "DateMath.h"
+
+#include "Assertions.h"
+#include "ASCIICType.h"
+#include "CurrentTime.h"
+#include "MathExtras.h"
+#include "StringExtras.h"
+
+#include <algorithm>
+#include <limits.h>
+#include <limits>
+#include <stdint.h>
+#include <time.h>
+
+
+#if HAVE(ERRNO_H)
+#include <errno.h>
+#endif
+
+#if PLATFORM(DARWIN)
+#include <notify.h>
+#endif
+
+#if HAVE(SYS_TIME_H)
+#include <sys/time.h>
+#endif
+
+#if HAVE(SYS_TIMEB_H)
+#include <sys/timeb.h>
+#endif
+
+#define NaN std::numeric_limits<double>::quiet_NaN()
+
+namespace WTF {
+
+/* Constants */
+
+static const double minutesPerDay = 24.0 * 60.0;
+static const double secondsPerDay = 24.0 * 60.0 * 60.0;
+static const double secondsPerYear = 24.0 * 60.0 * 60.0 * 365.0;
+
+static const double usecPerSec = 1000000.0;
+
+static const double maxUnixTime = 2145859200.0; // 12/31/2037
+
+// Day of year for the first day of each month, where index 0 is January, and day 0 is January 1.
+// First for non-leap years, then for leap years.
+static const int firstDayOfMonth[2][12] = {
+    {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
+    {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
+};
+
+static inline bool isLeapYear(int year)
+{
+    if (year % 4 != 0)
+        return false;
+    if (year % 400 == 0)
+        return true;
+    if (year % 100 == 0)
+        return false;
+    return true;
+}
+
+static inline int daysInYear(int year)
+{
+    return 365 + isLeapYear(year);
+}
+
+static inline double daysFrom1970ToYear(int year)
+{
+    // The Gregorian Calendar rules for leap years:
+    // Every fourth year is a leap year.  2004, 2008, and 2012 are leap years.
+    // However, every hundredth year is not a leap year.  1900 and 2100 are not leap years.
+    // Every four hundred years, there's a leap year after all.  2000 and 2400 are leap years.
+
+    static const int leapDaysBefore1971By4Rule = 1970 / 4;
+    static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100;
+    static const int leapDaysBefore1971By400Rule = 1970 / 400;
+
+    const double yearMinusOne = year - 1;
+    const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule;
+    const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule;
+    const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefore1971By400Rule;
+
+    return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule;
+}
+
+static inline double msToDays(double ms)
+{
+    return floor(ms / msPerDay);
+}
+
+static inline int msToYear(double ms)
+{
+    int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970);
+    double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear);
+    if (msFromApproxYearTo1970 > ms)
+        return approxYear - 1;
+    if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms)
+        return approxYear + 1;
+    return approxYear;
+}
+
+static inline int dayInYear(double ms, int year)
+{
+    return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year));
+}
+
+static inline double msToMilliseconds(double ms)
+{
+    double result = fmod(ms, msPerDay);
+    if (result < 0)
+        result += msPerDay;
+    return result;
+}
+
+// 0: Sunday, 1: Monday, etc.
+static inline int msToWeekDay(double ms)
+{
+    int wd = (static_cast<int>(msToDays(ms)) + 4) % 7;
+    if (wd < 0)
+        wd += 7;
+    return wd;
+}
+
+static inline int msToSeconds(double ms)
+{
+    double result = fmod(floor(ms / msPerSecond), secondsPerMinute);
+    if (result < 0)
+        result += secondsPerMinute;
+    return static_cast<int>(result);
+}
+
+static inline int msToMinutes(double ms)
+{
+    double result = fmod(floor(ms / msPerMinute), minutesPerHour);
+    if (result < 0)
+        result += minutesPerHour;
+    return static_cast<int>(result);
+}
+
+static inline int msToHours(double ms)
+{
+    double result = fmod(floor(ms/msPerHour), hoursPerDay);
+    if (result < 0)
+        result += hoursPerDay;
+    return static_cast<int>(result);
+}
+
+static inline int monthFromDayInYear(int dayInYear, bool leapYear)
+{
+    const int d = dayInYear;
+    int step;
+
+    if (d < (step = 31))
+        return 0;
+    step += (leapYear ? 29 : 28);
+    if (d < step)
+        return 1;
+    if (d < (step += 31))
+        return 2;
+    if (d < (step += 30))
+        return 3;
+    if (d < (step += 31))
+        return 4;
+    if (d < (step += 30))
+        return 5;
+    if (d < (step += 31))
+        return 6;
+    if (d < (step += 31))
+        return 7;
+    if (d < (step += 30))
+        return 8;
+    if (d < (step += 31))
+        return 9;
+    if (d < (step += 30))
+        return 10;
+    return 11;
+}
+
+static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& startDayOfNextMonth, int daysInThisMonth)
+{
+    startDayOfThisMonth = startDayOfNextMonth;
+    startDayOfNextMonth += daysInThisMonth;
+    return (dayInYear <= startDayOfNextMonth);
+}
+
+static inline int dayInMonthFromDayInYear(int dayInYear, bool leapYear)
+{
+    const int d = dayInYear;
+    int step;
+    int next = 30;
+
+    if (d <= next)
+        return d + 1;
+    const int daysInFeb = (leapYear ? 29 : 28);
+    if (checkMonth(d, step, next, daysInFeb))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 30))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 30))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 30))
+        return d - step;
+    if (checkMonth(d, step, next, 31))
+        return d - step;
+    if (checkMonth(d, step, next, 30))
+        return d - step;
+    step = next;
+    return d - step;
+}
+
+static inline int monthToDayInYear(int month, bool isLeapYear)
+{
+    return firstDayOfMonth[isLeapYear][month];
+}
+
+static inline double timeToMS(double hour, double min, double sec, double ms)
+{
+    return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);
+}
+
+static int dateToDayInYear(int year, int month, int day)
+{
+    year += month / 12;
+
+    month %= 12;
+    if (month < 0) {
+        month += 12;
+        --year;
+    }
+
+    int yearday = static_cast<int>(floor(daysFrom1970ToYear(year)));
+    int monthday = monthToDayInYear(month, isLeapYear(year));
+
+    return yearday + monthday + day - 1;
+}
+
+double getCurrentUTCTime()
+{
+    return floor(getCurrentUTCTimeWithMicroseconds());
+}
+
+// Returns current time in milliseconds since 1 Jan 1970.
+double getCurrentUTCTimeWithMicroseconds()
+{
+    return currentTime() * 1000.0; 
+}
+
+void getLocalTime(const time_t* localTime, struct tm* localTM)
+{
+#if COMPILER(MSVC7) || COMPILER(MINGW) || PLATFORM(WINCE)
+    *localTM = *localtime(localTime);
+#elif COMPILER(MSVC)
+    localtime_s(localTM, localTime);
+#else
+    localtime_r(localTime, localTM);
+#endif
+}
+
+// There is a hard limit at 2038 that we currently do not have a workaround
+// for (rdar://problem/5052975).
+static inline int maximumYearForDST()
+{
+    return 2037;
+}
+
+static inline int minimumYearForDST()
+{
+    // Because of the 2038 issue (see maximumYearForDST) if the current year is
+    // greater than the max year minus 27 (2010), we want to use the max year
+    // minus 27 instead, to ensure there is a range of 28 years that all years
+    // can map to.
+    return std::min(msToYear(getCurrentUTCTime()), maximumYearForDST() - 27) ;
+}
+
+/*
+ * Find an equivalent year for the one given, where equivalence is deterined by
+ * the two years having the same leapness and the first day of the year, falling
+ * on the same day of the week.
+ *
+ * This function returns a year between this current year and 2037, however this
+ * function will potentially return incorrect results if the current year is after
+ * 2010, (rdar://problem/5052975), if the year passed in is before 1900 or after
+ * 2100, (rdar://problem/5055038).
+ */
+int equivalentYearForDST(int year)
+{
+    // It is ok if the cached year is not the current year as long as the rules
+    // for DST did not change between the two years; if they did the app would need
+    // to be restarted.
+    static int minYear = minimumYearForDST();
+    int maxYear = maximumYearForDST();
+
+    int difference;
+    if (year > maxYear)
+        difference = minYear - year;
+    else if (year < minYear)
+        difference = maxYear - year;
+    else
+        return year;
+
+    int quotient = difference / 28;
+    int product = (quotient) * 28;
+
+    year += product;
+    ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cast<int>(NaN)));
+    return year;
+}
+
+static int32_t calculateUTCOffset()
+{
+    time_t localTime = time(0);
+    tm localt;
+    getLocalTime(&localTime, &localt);
+
+    // Get the difference between this time zone and UTC on the 1st of January of this year.
+    localt.tm_sec = 0;
+    localt.tm_min = 0;
+    localt.tm_hour = 0;
+    localt.tm_mday = 1;
+    localt.tm_mon = 0;
+    // Not setting localt.tm_year!
+    localt.tm_wday = 0;
+    localt.tm_yday = 0;
+    localt.tm_isdst = 0;
+#if PLATFORM(WIN_OS) || PLATFORM(SOLARIS) || COMPILER(RVCT)
+    // Using a canned date of 01/01/2009 on platforms with weaker date-handling foo.
+    localt.tm_year = 109;
+    time_t utcOffset = 1230768000 - mktime(&localt);
+#else
+    localt.tm_zone = 0;
+    localt.tm_gmtoff = 0;
+    time_t utcOffset = timegm(&localt) - mktime(&localt);
+#endif
+
+    return static_cast<int32_t>(utcOffset * 1000);
+}
+
+#if PLATFORM(DARWIN)
+static int32_t s_cachedUTCOffset; // In milliseconds. An assumption here is that access to an int32_t variable is atomic on platforms that take this code path.
+static bool s_haveCachedUTCOffset;
+static int s_notificationToken;
+#endif
+
+/*
+ * Get the difference in milliseconds between this time zone and UTC (GMT)
+ * NOT including DST.
+ */
+double getUTCOffset()
+{
+#if PLATFORM(DARWIN)
+    if (s_haveCachedUTCOffset) {
+        int notified;
+        uint32_t status = notify_check(s_notificationToken, &notified);
+        if (status == NOTIFY_STATUS_OK && !notified)
+            return s_cachedUTCOffset;
+    }
+#endif
+
+    int32_t utcOffset = calculateUTCOffset();
+
+#if PLATFORM(DARWIN)
+    // Theoretically, it is possible that several threads will be executing this code at once, in which case we will have a race condition,
+    // and a newer value may be overwritten. In practice, time zones don't change that often.
+    s_cachedUTCOffset = utcOffset;
+#endif
+
+    return utcOffset;
+}
+
+/*
+ * Get the DST offset for the time passed in.  Takes
+ * seconds (not milliseconds) and cannot handle dates before 1970
+ * on some OS'
+ */
+static double getDSTOffsetSimple(double localTimeSeconds, double utcOffset)
+{
+    if (localTimeSeconds > maxUnixTime)
+        localTimeSeconds = maxUnixTime;
+    else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0)
+        localTimeSeconds += secondsPerDay;
+
+    //input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset()
+    double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset;
+
+    // Offset from UTC but doesn't include DST obviously
+    int offsetHour =  msToHours(offsetTime);
+    int offsetMinute =  msToMinutes(offsetTime);
+
+    // FIXME: time_t has a potential problem in 2038
+    time_t localTime = static_cast<time_t>(localTimeSeconds);
+
+    tm localTM;
+    getLocalTime(&localTime, &localTM);
+
+    double diff = ((localTM.tm_hour - offsetHour) * secondsPerHour) + ((localTM.tm_min - offsetMinute) * 60);
+
+    if (diff < 0)
+        diff += secondsPerDay;
+
+    return (diff * msPerSecond);
+}
+
+// Get the DST offset, given a time in UTC
+static double getDSTOffset(double ms, double utcOffset)
+{
+    // On Mac OS X, the call to localtime (see getDSTOffsetSimple) will return historically accurate
+    // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript
+    // standard explicitly dictates that historical information should not be considered when
+    // determining DST. For this reason we shift away from years that localtime can handle but would
+    // return historically accurate information.
+    int year = msToYear(ms);
+    int equivalentYear = equivalentYearForDST(year);
+    if (year != equivalentYear) {
+        bool leapYear = isLeapYear(year);
+        int dayInYearLocal = dayInYear(ms, year);
+        int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear);
+        int month = monthFromDayInYear(dayInYearLocal, leapYear);
+        int day = dateToDayInYear(equivalentYear, month, dayInMonth);
+        ms = (day * msPerDay) + msToMilliseconds(ms);
+    }
+
+    return getDSTOffsetSimple(ms / msPerSecond, utcOffset);
+}
+
+double gregorianDateTimeToMS(const GregorianDateTime& t, double milliSeconds, bool inputIsUTC)
+{
+    int day = dateToDayInYear(t.year + 1900, t.month, t.monthDay);
+    double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds);
+    double result = (day * msPerDay) + ms;
+
+    if (!inputIsUTC) { // convert to UTC
+        double utcOffset = getUTCOffset();
+        result -= utcOffset;
+        result -= getDSTOffset(result, utcOffset);
+    }
+
+    return result;
+}
+
+void msToGregorianDateTime(double ms, bool outputIsUTC, GregorianDateTime& tm)
+{
+    // input is UTC
+    double dstOff = 0.0;
+    const double utcOff = getUTCOffset();
+
+    if (!outputIsUTC) {  // convert to local time
+        dstOff = getDSTOffset(ms, utcOff);
+        ms += dstOff + utcOff;
+    }
+
+    const int year = msToYear(ms);
+    tm.second   =  msToSeconds(ms);
+    tm.minute   =  msToMinutes(ms);
+    tm.hour     =  msToHours(ms);
+    tm.weekDay  =  msToWeekDay(ms);
+    tm.yearDay  =  dayInYear(ms, year);
+    tm.monthDay =  dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year));
+    tm.month    =  monthFromDayInYear(tm.yearDay, isLeapYear(year));
+    tm.year     =  year - 1900;
+    tm.isDST    =  dstOff != 0.0;
+
+    tm.utcOffset = outputIsUTC ? 0 : static_cast<long>((dstOff + utcOff) / msPerSecond);
+    tm.timeZone = NULL;
+}
+
+void initializeDates()
+{
+#ifndef NDEBUG
+    static bool alreadyInitialized;
+    ASSERT(!alreadyInitialized++);
+#endif
+
+    equivalentYearForDST(2000); // Need to call once to initialize a static used in this function.
+#if PLATFORM(DARWIN)
+    // Register for a notification whenever the time zone changes.
+    uint32_t status = notify_register_check("com.apple.system.timezone", &s_notificationToken);
+    if (status == NOTIFY_STATUS_OK) {
+        s_cachedUTCOffset = calculateUTCOffset();
+        s_haveCachedUTCOffset = true;
+    }
+#endif
+}
+
+static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, int second)
+{
+    double days = (day - 32075)
+        + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4)
+        + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12
+        - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4)
+        - 2440588;
+    return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMinute + second;
+}
+
+// We follow the recommendation of RFC 2822 to consider all
+// obsolete time zones not listed here equivalent to "-0000".
+static const struct KnownZone {
+#if !PLATFORM(WIN_OS)
+    const
+#endif
+        char tzName[4];
+    int tzOffset;
+} known_zones[] = {
+    { "UT", 0 },
+    { "GMT", 0 },
+    { "EST", -300 },
+    { "EDT", -240 },
+    { "CST", -360 },
+    { "CDT", -300 },
+    { "MST", -420 },
+    { "MDT", -360 },
+    { "PST", -480 },
+    { "PDT", -420 }
+};
+
+inline static void skipSpacesAndComments(const char*& s)
+{
+    int nesting = 0;
+    char ch;
+    while ((ch = *s)) {
+        if (!isASCIISpace(ch)) {
+            if (ch == '(')
+                nesting++;
+            else if (ch == ')' && nesting > 0)
+                nesting--;
+            else if (nesting == 0)
+                break;
+        }
+        s++;
+    }
+}
+
+// returns 0-11 (Jan-Dec); -1 on failure
+static int findMonth(const char* monthStr)
+{
+    ASSERT(monthStr);
+    char needle[4];
+    for (int i = 0; i < 3; ++i) {
+        if (!*monthStr)
+            return -1;
+        needle[i] = static_cast<char>(toASCIILower(*monthStr++));
+    }
+    needle[3] = '\0';
+    const char *haystack = "janfebmaraprmayjunjulaugsepoctnovdec";
+    const char *str = strstr(haystack, needle);
+    if (str) {
+        int position = static_cast<int>(str - haystack);
+        if (position % 3 == 0)
+            return position / 3;
+    }
+    return -1;
+}
+
+static bool parseLong(const char* string, char** stopPosition, int base, long* result)
+{
+    *result = strtol(string, stopPosition, base);
+    // Avoid the use of errno as it is not available on Windows CE
+    if (string == *stopPosition || *result == LONG_MIN || *result == LONG_MAX)
+        return false;
+    return true;
+}
+
+double parseDateFromNullTerminatedCharacters(const char* dateString)
+{
+    // This parses a date in the form:
+    //     Tuesday, 09-Nov-99 23:12:40 GMT
+    // or
+    //     Sat, 01-Jan-2000 08:00:00 GMT
+    // or
+    //     Sat, 01 Jan 2000 08:00:00 GMT
+    // or
+    //     01 Jan 99 22:00 +0100    (exceptions in rfc822/rfc2822)
+    // ### non RFC formats, added for Javascript:
+    //     [Wednesday] January 09 1999 23:12:40 GMT
+    //     [Wednesday] January 09 23:12:40 GMT 1999
+    //
+    // We ignore the weekday.
+     
+    // Skip leading space
+    skipSpacesAndComments(dateString);
+
+    long month = -1;
+    const char *wordStart = dateString;
+    // Check contents of first words if not number
+    while (*dateString && !isASCIIDigit(*dateString)) {
+        if (isASCIISpace(*dateString) || *dateString == '(') {
+            if (dateString - wordStart >= 3)
+                month = findMonth(wordStart);
+            skipSpacesAndComments(dateString);
+            wordStart = dateString;
+        } else
+           dateString++;
+    }
+
+    // Missing delimiter between month and day (like "January29")?
+    if (month == -1 && wordStart != dateString)
+        month = findMonth(wordStart);
+
+    skipSpacesAndComments(dateString);
+
+    if (!*dateString)
+        return NaN;
+
+    // ' 09-Nov-99 23:12:40 GMT'
+    char* newPosStr;
+    long day;
+    if (!parseLong(dateString, &newPosStr, 10, &day))
+        return NaN;
+    dateString = newPosStr;
+
+    if (!*dateString)
+        return NaN;
+
+    if (day < 0)
+        return NaN;
+
+    long year = 0;
+    if (day > 31) {
+        // ### where is the boundary and what happens below?
+        if (*dateString != '/')
+            return NaN;
+        // looks like a YYYY/MM/DD date
+        if (!*++dateString)
+            return NaN;
+        year = day;
+        if (!parseLong(dateString, &newPosStr, 10, &month))
+            return NaN;
+        month -= 1;
+        dateString = newPosStr;
+        if (*dateString++ != '/' || !*dateString)
+            return NaN;
+        if (!parseLong(dateString, &newPosStr, 10, &day))
+            return NaN;
+        dateString = newPosStr;
+    } else if (*dateString == '/' && month == -1) {
+        dateString++;
+        // This looks like a MM/DD/YYYY date, not an RFC date.
+        month = day - 1; // 0-based
+        if (!parseLong(dateString, &newPosStr, 10, &day))
+            return NaN;
+        if (day < 1 || day > 31)
+            return NaN;
+        dateString = newPosStr;
+        if (*dateString == '/')
+            dateString++;
+        if (!*dateString)
+            return NaN;
+     } else {
+        if (*dateString == '-')
+            dateString++;
+
+        skipSpacesAndComments(dateString);
+
+        if (*dateString == ',')
+            dateString++;
+
+        if (month == -1) { // not found yet
+            month = findMonth(dateString);
+            if (month == -1)
+                return NaN;
+
+            while (*dateString && *dateString != '-' && *dateString != ',' && !isASCIISpace(*dateString))
+                dateString++;
+
+            if (!*dateString)
+                return NaN;
+
+            // '-99 23:12:40 GMT'
+            if (*dateString != '-' && *dateString != '/' && *dateString != ',' && !isASCIISpace(*dateString))
+                return NaN;
+            dateString++;
+        }
+    }
+
+    if (month < 0 || month > 11)
+        return NaN;
+
+    // '99 23:12:40 GMT'
+    if (year <= 0 && *dateString) {
+        if (!parseLong(dateString, &newPosStr, 10, &year))
+            return NaN;
+    }
+
+    // Don't fail if the time is missing.
+    long hour = 0;
+    long minute = 0;
+    long second = 0;
+    if (!*newPosStr)
+        dateString = newPosStr;
+    else {
+        // ' 23:12:40 GMT'
+        if (!(isASCIISpace(*newPosStr) || *newPosStr == ',')) {
+            if (*newPosStr != ':')
+                return NaN;
+            // There was no year; the number was the hour.
+            year = -1;
+        } else {
+            // in the normal case (we parsed the year), advance to the next number
+            dateString = ++newPosStr;
+            skipSpacesAndComments(dateString);
+        }
+
+        parseLong(dateString, &newPosStr, 10, &hour);
+        // Do not check for errno here since we want to continue
+        // even if errno was set becasue we are still looking
+        // for the timezone!
+
+        // Read a number? If not, this might be a timezone name.
+        if (newPosStr != dateString) {
+            dateString = newPosStr;
+
+            if (hour < 0 || hour > 23)
+                return NaN;
+
+            if (!*dateString)
+                return NaN;
+
+            // ':12:40 GMT'
+            if (*dateString++ != ':')
+                return NaN;
+
+            if (!parseLong(dateString, &newPosStr, 10, &minute))
+                return NaN;
+            dateString = newPosStr;
+
+            if (minute < 0 || minute > 59)
+                return NaN;
+
+            // ':40 GMT'
+            if (*dateString && *dateString != ':' && !isASCIISpace(*dateString))
+                return NaN;
+
+            // seconds are optional in rfc822 + rfc2822
+            if (*dateString ==':') {
+                dateString++;
+
+                if (!parseLong(dateString, &newPosStr, 10, &second))
+                    return NaN;
+                dateString = newPosStr;
+
+                if (second < 0 || second > 59)
+                    return NaN;
+            }
+
+            skipSpacesAndComments(dateString);
+
+            if (strncasecmp(dateString, "AM", 2) == 0) {
+                if (hour > 12)
+                    return NaN;
+                if (hour == 12)
+                    hour = 0;
+                dateString += 2;
+                skipSpacesAndComments(dateString);
+            } else if (strncasecmp(dateString, "PM", 2) == 0) {
+                if (hour > 12)
+                    return NaN;
+                if (hour != 12)
+                    hour += 12;
+                dateString += 2;
+                skipSpacesAndComments(dateString);
+            }
+        }
+    }
+
+    bool haveTZ = false;
+    int offset = 0;
+
+    // Don't fail if the time zone is missing. 
+    // Some websites omit the time zone (4275206).
+    if (*dateString) {
+        if (strncasecmp(dateString, "GMT", 3) == 0 || strncasecmp(dateString, "UTC", 3) == 0) {
+            dateString += 3;
+            haveTZ = true;
+        }
+
+        if (*dateString == '+' || *dateString == '-') {
+            long o;
+            if (!parseLong(dateString, &newPosStr, 10, &o))
+                return NaN;
+            dateString = newPosStr;
+
+            if (o < -9959 || o > 9959)
+                return NaN;
+
+            int sgn = (o < 0) ? -1 : 1;
+            o = abs(o);
+            if (*dateString != ':') {
+                offset = ((o / 100) * 60 + (o % 100)) * sgn;
+            } else { // GMT+05:00
+                long o2;
+                if (!parseLong(dateString, &newPosStr, 10, &o2))
+                    return NaN;
+                dateString = newPosStr;
+                offset = (o * 60 + o2) * sgn;
+            }
+            haveTZ = true;
+        } else {
+            for (int i = 0; i < int(sizeof(known_zones) / sizeof(KnownZone)); i++) {
+                if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) {
+                    offset = known_zones[i].tzOffset;
+                    dateString += strlen(known_zones[i].tzName);
+                    haveTZ = true;
+                    break;
+                }
+            }
+        }
+    }
+
+    skipSpacesAndComments(dateString);
+
+    if (*dateString && year == -1) {
+        if (!parseLong(dateString, &newPosStr, 10, &year))
+            return NaN;
+        dateString = newPosStr;
+    }
+
+    skipSpacesAndComments(dateString);
+
+    // Trailing garbage
+    if (*dateString)
+        return NaN;
+
+    // Y2K: Handle 2 digit years.
+    if (year >= 0 && year < 100) {
+        if (year < 50)
+            year += 2000;
+        else
+            year += 1900;
+    }
+
+    // fall back to local timezone
+    if (!haveTZ) {
+        GregorianDateTime t;
+        t.monthDay = day;
+        t.month = month;
+        t.year = year - 1900;
+        t.isDST = -1;
+        t.second = second;
+        t.minute = minute;
+        t.hour = hour;
+
+        // Use our gregorianDateTimeToMS() rather than mktime() as the latter can't handle the full year range.
+        return gregorianDateTimeToMS(t, 0, false);
+    }
+
+    return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond;
+}
+
+double timeClip(double t)
+{
+    if (!isfinite(t))
+        return NaN;
+    if (fabs(t) > 8.64E15)
+        return NaN;
+    return trunc(t);
+}
+
+
+} // namespace WTF
diff --git a/wtf/DateMath.h b/wtf/DateMath.h
new file mode 100644 (file)
index 0000000..8690a49
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ */
+
+#ifndef DateMath_h
+#define DateMath_h
+
+#include <time.h>
+#include <string.h>
+#include <wtf/Noncopyable.h>
+
+namespace WTF {
+
+struct GregorianDateTime;
+
+void initializeDates();
+void msToGregorianDateTime(double, bool outputIsUTC, GregorianDateTime&);
+double gregorianDateTimeToMS(const GregorianDateTime&, double, bool inputIsUTC);
+double getUTCOffset();
+int equivalentYearForDST(int year);
+double getCurrentUTCTime();
+double getCurrentUTCTimeWithMicroseconds();
+void getLocalTime(const time_t*, tm*);
+
+// Not really math related, but this is currently the only shared place to put these.  
+double parseDateFromNullTerminatedCharacters(const char*);
+double timeClip(double);
+
+const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+const double hoursPerDay = 24.0;
+const double minutesPerHour = 60.0;
+const double secondsPerHour = 60.0 * 60.0;
+const double secondsPerMinute = 60.0;
+const double msPerSecond = 1000.0;
+const double msPerMinute = 60.0 * 1000.0;
+const double msPerHour = 60.0 * 60.0 * 1000.0;
+const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0;
+
+// Intentionally overridding the default tm of the system
+// Tee members of tm differ on various operating systems.
+struct GregorianDateTime : Noncopyable {
+    GregorianDateTime()
+        : second(0)
+        , minute(0)
+        , hour(0)
+        , weekDay(0)
+        , monthDay(0)
+        , yearDay(0)
+        , month(0)
+        , year(0)
+        , isDST(0)
+        , utcOffset(0)
+        , timeZone(0)
+    {
+    }
+
+    ~GregorianDateTime()
+    {
+        delete [] timeZone;
+    }
+
+    GregorianDateTime(const tm& inTm)
+        : second(inTm.tm_sec)
+        , minute(inTm.tm_min)
+        , hour(inTm.tm_hour)
+        , weekDay(inTm.tm_wday)
+        , monthDay(inTm.tm_mday)
+        , yearDay(inTm.tm_yday)
+        , month(inTm.tm_mon)
+        , year(inTm.tm_year)
+        , isDST(inTm.tm_isdst)
+    {
+#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT)
+        utcOffset = static_cast<int>(inTm.tm_gmtoff);
+
+        int inZoneSize = strlen(inTm.tm_zone) + 1;
+        timeZone = new char[inZoneSize];
+        strncpy(timeZone, inTm.tm_zone, inZoneSize);
+#else
+        utcOffset = static_cast<int>(getUTCOffset() / msPerSecond + (isDST ? secondsPerHour : 0));
+        timeZone = 0;
+#endif
+    }
+
+    operator tm() const
+    {
+        tm ret;
+        memset(&ret, 0, sizeof(ret));
+
+        ret.tm_sec   =  second;
+        ret.tm_min   =  minute;
+        ret.tm_hour  =  hour;
+        ret.tm_wday  =  weekDay;
+        ret.tm_mday  =  monthDay;
+        ret.tm_yday  =  yearDay;
+        ret.tm_mon   =  month;
+        ret.tm_year  =  year;
+        ret.tm_isdst =  isDST;
+
+#if !PLATFORM(WIN_OS) && !PLATFORM(SOLARIS) && !COMPILER(RVCT)
+        ret.tm_gmtoff = static_cast<long>(utcOffset);
+        ret.tm_zone = timeZone;
+#endif
+
+        return ret;
+    }
+
+    void copyFrom(const GregorianDateTime& rhs)
+    {
+        second = rhs.second;
+        minute = rhs.minute;
+        hour = rhs.hour;
+        weekDay = rhs.weekDay;
+        monthDay = rhs.monthDay;
+        yearDay = rhs.yearDay;
+        month = rhs.month;
+        year = rhs.year;
+        isDST = rhs.isDST;
+        utcOffset = rhs.utcOffset;
+        if (rhs.timeZone) {
+            int inZoneSize = strlen(rhs.timeZone) + 1;
+            timeZone = new char[inZoneSize];
+            strncpy(timeZone, rhs.timeZone, inZoneSize);
+        } else
+            timeZone = 0;
+    }
+
+    int second;
+    int minute;
+    int hour;
+    int weekDay;
+    int monthDay;
+    int yearDay;
+    int month;
+    int year;
+    int isDST;
+    int utcOffset;
+    char* timeZone;
+};
+
+static inline int gmtoffset(const GregorianDateTime& t)
+{
+    return t.utcOffset;
+}
+
+} // namespace WTF
+
+#endif // DateMath_h
index 70c546b81666f522443cfae2122c58508035294b..3c3d378fc5896fedf28d1cf4b2bd643a238cd18f 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,7 +44,7 @@ namespace WTF {
     template<typename T> class DequeConstReverseIterator;
 
     template<typename T>
-    class Deque {
+    class Deque : public FastAllocBase {
     public:
         typedef DequeIterator<T> iterator;
         typedef DequeConstIterator<T> const_iterator;
@@ -75,9 +76,14 @@ namespace WTF {
         template<typename U> void append(const U&);
         template<typename U> void prepend(const U&);
         void removeFirst();
+        void remove(iterator&);
+        void remove(const_iterator&);
 
         void clear();
 
+        template<typename Predicate>
+        iterator findIf(Predicate&);
+
     private:
         friend class DequeIteratorBase<T>;
 
@@ -85,6 +91,7 @@ namespace WTF {
         typedef VectorTypeOperations<T> TypeOperations;
         typedef DequeIteratorBase<T> IteratorBase;
 
+        void remove(size_t position);
         void invalidateIterators();
         void destroyAll();
         void checkValidity() const;
@@ -124,6 +131,7 @@ namespace WTF {
 
     private:
         void addToIteratorsList();
+        void removeFromIteratorsList();
         void checkValidity() const;
         void checkValidity(const Base&) const;
 
@@ -348,7 +356,7 @@ namespace WTF {
         destroyAll();
     }
 
-    template <typename T>
+    template<typename T>
     inline void Deque<T>::swap(Deque<T>& other)
     {
         checkValidity();
@@ -361,7 +369,7 @@ namespace WTF {
         other.checkValidity();
     }
 
-    template <typename T>
+    template<typename T>
     inline void Deque<T>::clear()
     {
         checkValidity();
@@ -372,6 +380,18 @@ namespace WTF {
         checkValidity();
     }
 
+    template<typename T>
+    template<typename Predicate>
+    inline DequeIterator<T> Deque<T>::findIf(Predicate& predicate)
+    {
+        iterator end_iterator = end();
+        for (iterator it = begin(); it != end_iterator; ++it) {
+            if (predicate(*it))
+                return it;
+        }
+        return end_iterator;
+    }
+
     template<typename T>
     inline void Deque<T>::expandCapacityIfNeeded()
     {
@@ -447,10 +467,48 @@ namespace WTF {
         checkValidity();
     }
 
+    template<typename T>
+    inline void Deque<T>::remove(iterator& it)
+    {
+        it.checkValidity();
+        remove(it.m_index);
+    }
+
+    template<typename T>
+    inline void Deque<T>::remove(const_iterator& it)
+    {
+        it.checkValidity();
+        remove(it.m_index);
+    }
+
+    template<typename T>
+    inline void Deque<T>::remove(size_t position)
+    {
+        if (position == m_end)
+            return;
+
+        checkValidity();
+        invalidateIterators();
+
+        T* buffer = m_buffer.buffer();
+        TypeOperations::destruct(&buffer[position], &buffer[position + 1]);
+
+        // Find which segment of the circular buffer contained the remove element, and only move elements in that part.
+        if (position >= m_start) {
+            TypeOperations::moveOverlapping(buffer + m_start, buffer + position, buffer + m_start + 1);
+            m_start = (m_start + 1) % m_buffer.capacity();
+        } else {
+            TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_end, buffer + position);
+            m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity();
+        }
+        checkValidity();
+    }
+
 #ifdef NDEBUG
     template<typename T> inline void DequeIteratorBase<T>::checkValidity() const { }
     template<typename T> inline void DequeIteratorBase<T>::checkValidity(const DequeIteratorBase<T>&) const { }
     template<typename T> inline void DequeIteratorBase<T>::addToIteratorsList() { }
+    template<typename T> inline void DequeIteratorBase<T>::removeFromIteratorsList() { }
 #else
     template<typename T>
     void DequeIteratorBase<T>::checkValidity() const
@@ -480,6 +538,30 @@ namespace WTF {
         }
         m_previous = 0;
     }
+
+    template<typename T>
+    void DequeIteratorBase<T>::removeFromIteratorsList()
+    {
+        if (!m_deque) {
+            ASSERT(!m_next);
+            ASSERT(!m_previous);
+        } else {
+            if (m_next) {
+                ASSERT(m_next->m_previous == this);
+                m_next->m_previous = m_previous;
+            }
+            if (m_previous) {
+                ASSERT(m_deque->m_iterators != this);
+                ASSERT(m_previous->m_next == this);
+                m_previous->m_next = m_next;
+            } else {
+                ASSERT(m_deque->m_iterators == this);
+                m_deque->m_iterators = m_next;
+            }
+        }
+        m_next = 0;
+        m_previous = 0;
+    }
 #endif
 
     template<typename T>
@@ -506,31 +588,26 @@ namespace WTF {
         checkValidity();
     }
 
+    template<typename T>
+    inline DequeIteratorBase<T>& DequeIteratorBase<T>::operator=(const Base& other)
+    {
+        checkValidity();
+        other.checkValidity();
+        removeFromIteratorsList();
+
+        m_deque = other.m_deque;
+        m_index = other.m_index;
+        addToIteratorsList();
+        checkValidity();
+        return *this;
+    }
+
     template<typename T>
     inline DequeIteratorBase<T>::~DequeIteratorBase()
     {
 #ifndef NDEBUG
-        // Delete iterator from doubly-linked list of iterators.
-        if (!m_deque) {
-            ASSERT(!m_next);
-            ASSERT(!m_previous);
-        } else {
-            if (m_next) {
-                ASSERT(m_next->m_previous == this);
-                m_next->m_previous = m_previous;
-            }
-            if (m_previous) {
-                ASSERT(m_deque->m_iterators != this);
-                ASSERT(m_previous->m_next == this);
-                m_previous->m_next = m_next;
-            } else {
-                ASSERT(m_deque->m_iterators == this);
-                m_deque->m_iterators = m_next;
-            }
-        }
+        removeFromIteratorsList();
         m_deque = 0;
-        m_next = 0;
-        m_previous = 0;
 #endif
     }
 
index 5dccb0e8ea99a6adce422c69e57adba6ea0433db..693e9b78a0b36f10362d962fecae6c96cc5cc0de 100644 (file)
 #ifndef WTF_DisallowCType_h
 #define WTF_DisallowCType_h
 
+#include "Platform.h"
+
+#define _DONT_USE_CTYPE_INLINE_
+
 // The behavior of many of the functions in the <ctype.h> header is dependent
 // on the current locale. But almost all uses of these functions are for
 // locale-independent, ASCII-specific purposes. In WebKit code we use our own
diff --git a/wtf/FastAllocBase.h b/wtf/FastAllocBase.h
new file mode 100644 (file)
index 0000000..9fcbbc1
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2008, 2009 Paul Pedriana <ppedriana@ea.com>. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FastAllocBase_h
+#define FastAllocBase_h
+
+// Provides customizable overrides of fastMalloc/fastFree and operator new/delete
+//
+// Provided functionality:
+//    namespace WTF {
+//        class FastAllocBase;
+//
+//        T*    fastNew<T>();
+//        T*    fastNew<T>(arg);
+//        T*    fastNew<T>(arg, arg);
+//        T*    fastNewArray<T>(count);
+//        void  fastDelete(T* p);
+//        void  fastDeleteArray(T* p);
+//        void  fastNonNullDelete(T* p);
+//        void  fastNonNullDeleteArray(T* p);
+//    }
+//
+// FastDelete assumes that the underlying
+//
+// Example usage:
+//    class Widget : public FastAllocBase { ... };
+//
+//    char* charPtr = fastNew<char>();
+//    fastDelete(charPtr);
+//
+//    char* charArrayPtr = fastNewArray<char>(37);
+//    fastDeleteArray(charArrayPtr);
+//
+//    void** voidPtrPtr = fastNew<void*>();
+//    fastDelete(voidPtrPtr);
+//
+//    void** voidPtrArrayPtr = fastNewArray<void*>(37);
+//    fastDeleteArray(voidPtrArrayPtr);
+//
+//    POD* podPtr = fastNew<POD>();
+//    fastDelete(podPtr);
+//
+//    POD* podArrayPtr = fastNewArray<POD>(37);
+//    fastDeleteArray(podArrayPtr);
+//
+//    Object* objectPtr = fastNew<Object>();
+//    fastDelete(objectPtr);
+//
+//    Object* objectArrayPtr = fastNewArray<Object>(37);
+//    fastDeleteArray(objectArrayPtr);
+//
+
+#include <new>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "Assertions.h"
+#include "FastMalloc.h"
+#include "TypeTraits.h"
+
+namespace WTF {
+
+    class FastAllocBase {
+    public:
+        // Placement operator new.
+        void* operator new(size_t, void* p) { return p; }
+        void* operator new[](size_t, void* p) { return p; }
+
+        void* operator new(size_t size)
+        {
+            void* p = fastMalloc(size);
+            fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNew);
+            return p;
+        }
+
+        void operator delete(void* p)
+        {
+            fastMallocMatchValidateFree(p, Internal::AllocTypeClassNew);
+            fastFree(p);
+        }
+
+        void* operator new[](size_t size)
+        {
+            void* p = fastMalloc(size);
+            fastMallocMatchValidateMalloc(p, Internal::AllocTypeClassNewArray);
+            return p;
+        }
+
+        void operator delete[](void* p)
+        {
+            fastMallocMatchValidateFree(p, Internal::AllocTypeClassNewArray);
+            fastFree(p);
+        }
+    };
+
+    // fastNew / fastDelete
+
+    template <typename T>
+    inline T* fastNew()
+    {
+        void* p = fastMalloc(sizeof(T));
+
+        if (!p)
+            return 0;
+
+        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
+        return ::new(p) T;
+    }
+
+    template <typename T, typename Arg1>
+    inline T* fastNew(Arg1 arg1)
+    {
+        void* p = fastMalloc(sizeof(T));
+
+        if (!p)
+            return 0;
+
+        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
+        return ::new(p) T(arg1);
+    }
+
+    template <typename T, typename Arg1, typename Arg2>
+    inline T* fastNew(Arg1 arg1, Arg2 arg2)
+    {
+        void* p = fastMalloc(sizeof(T));
+
+        if (!p)
+            return 0;
+
+        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
+        return ::new(p) T(arg1, arg2);
+    }
+
+    template <typename T, typename Arg1, typename Arg2, typename Arg3>
+    inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3)
+    {
+        void* p = fastMalloc(sizeof(T));
+
+        if (!p)
+            return 0;
+
+        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
+        return ::new(p) T(arg1, arg2, arg3);
+    }
+
+    template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+    inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
+    {
+        void* p = fastMalloc(sizeof(T));
+
+        if (!p)
+            return 0;
+
+        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
+        return ::new(p) T(arg1, arg2, arg3, arg4);
+    }
+
+    template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+    inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
+    {
+        void* p = fastMalloc(sizeof(T));
+
+        if (!p)
+            return 0;
+
+        fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew);
+        return ::new(p) T(arg1, arg2, arg3, arg4, arg5);
+    }
+
+    namespace Internal {
+
+        // We define a union of pointer to an integer and pointer to T.
+        // When non-POD arrays are allocated we add a few leading bytes to tell what
+        // the size of the array is. We return to the user the pointer to T.
+        // The way to think of it is as if we allocate a struct like so:
+        //    struct Array {
+        //        AllocAlignmentInteger m_size;
+        //        T m_T[array count];
+        //    };
+
+        template <typename T>
+        union ArraySize {
+            AllocAlignmentInteger* size;
+            T* t;
+        };
+
+        // This is a support template for fastNewArray.
+        // This handles the case wherein T has a trivial ctor and a trivial dtor.
+        template <typename T, bool trivialCtor, bool trivialDtor>
+        struct NewArrayImpl {
+            static T* fastNewArray(size_t count)
+            {
+                T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
+                fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
+                return p;
+            }
+        };
+
+        // This is a support template for fastNewArray.
+        // This handles the case wherein T has a non-trivial ctor and a trivial dtor.
+        template <typename T>
+        struct NewArrayImpl<T, false, true> {
+            static T* fastNewArray(size_t count)
+            {
+                T* p = static_cast<T*>(fastMalloc(sizeof(T) * count));
+
+                if (!p)
+                    return 0;
+
+                fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
+
+                for (T* pObject = p, *pObjectEnd = pObject + count; pObject != pObjectEnd; ++pObject)
+                    ::new(pObject) T;
+
+                return p;
+            }
+        };
+
+        // This is a support template for fastNewArray.
+        // This handles the case wherein T has a trivial ctor and a non-trivial dtor.
+        template <typename T>
+        struct NewArrayImpl<T, true, false> {
+            static T* fastNewArray(size_t count)
+            {
+                void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
+                ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
+
+                if (!p)
+                    return 0;
+
+                fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
+                *a.size++ = count;
+                // No need to construct the objects in this case.
+
+                return a.t;
+            }
+        };
+
+        // This is a support template for fastNewArray.
+        // This handles the case wherein T has a non-trivial ctor and a non-trivial dtor.
+        template <typename T>
+        struct NewArrayImpl<T, false, false> {
+            static T* fastNewArray(size_t count)
+            {
+                void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count));
+                ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) };
+
+                if (!p)
+                    return 0;
+
+                fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray);
+                *a.size++ = count;
+
+                for (T* pT = a.t, *pTEnd = pT + count; pT != pTEnd; ++pT)
+                    ::new(pT) T;
+
+                return a.t;
+            }
+        };
+    } // namespace Internal
+
+    template <typename T>
+    inline T* fastNewArray(size_t count)
+    {
+        return Internal::NewArrayImpl<T, WTF::HasTrivialConstructor<T>::value, WTF::HasTrivialDestructor<T>::value>::fastNewArray(count);
+    }
+
+    template <typename T>
+    inline void fastDelete(T* p)
+    {
+        if (!p)
+            return;
+
+        fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
+        p->~T();
+        fastFree(p);
+    }
+
+    namespace Internal {
+        // This is a support template for fastDeleteArray.
+        // This handles the case wherein T has a trivial dtor.
+        template <typename T, bool trivialDtor>
+        struct DeleteArrayImpl {
+            static void fastDeleteArray(void* p)
+            {
+                // No need to destruct the objects in this case.
+                // We expect that fastFree checks for null.
+                fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
+                fastFree(p);
+            }
+        };
+
+        // This is a support template for fastDeleteArray.
+        // This handles the case wherein T has a non-trivial dtor.
+        template <typename T>
+        struct DeleteArrayImpl<T, false> {
+            static void fastDeleteArray(T* p)
+            {
+                if (!p)
+                    return;
+
+                ArraySize<T> a;
+                a.t = p;
+                a.size--; // Decrement size pointer
+
+                T* pEnd = p + *a.size;
+                while (pEnd-- != p)
+                    pEnd->~T();
+
+                fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
+                fastFree(a.size);
+            }
+        };
+
+    } // namespace Internal
+
+    template <typename T>
+    void fastDeleteArray(T* p)
+    {
+        Internal::DeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastDeleteArray(p);
+    }
+
+
+    template <typename T>
+    inline void fastNonNullDelete(T* p)
+    {
+        fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew);
+        p->~T();
+        fastFree(p);
+    }
+
+    namespace Internal {
+        // This is a support template for fastDeleteArray.
+        // This handles the case wherein T has a trivial dtor.
+        template <typename T, bool trivialDtor>
+        struct NonNullDeleteArrayImpl {
+            static void fastNonNullDeleteArray(void* p)
+            {
+                fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray);
+                // No need to destruct the objects in this case.
+                fastFree(p);
+            }
+        };
+
+        // This is a support template for fastDeleteArray.
+        // This handles the case wherein T has a non-trivial dtor.
+        template <typename T>
+        struct NonNullDeleteArrayImpl<T, false> {
+            static void fastNonNullDeleteArray(T* p)
+            {
+                ArraySize<T> a;
+                a.t = p;
+                a.size--;
+
+                T* pEnd = p + *a.size;
+                while (pEnd-- != p)
+                    pEnd->~T();
+
+                fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray);
+                fastFree(a.size);
+            }
+        };
+
+    } // namespace Internal
+
+    template <typename T>
+    void fastNonNullDeleteArray(T* p)
+    {
+        Internal::NonNullDeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastNonNullDeleteArray(p);
+    }
+
+
+} // namespace WTF
+
+// Using WTF::FastAllocBase to avoid using FastAllocBase's explicit qualification by WTF::.
+using WTF::FastAllocBase;
+
+#endif // FastAllocBase_h
index 15c42b25a3c368d5c195ae9c06fdb6ea8044dd32..f2843d3745d4609d0d3a5026530f95d88594cf32 100644 (file)
 #include "FastMalloc.h"
 
 #include "Assertions.h"
+#include <limits>
 #if ENABLE(JSC_MULTIPLE_THREADS)
 #include <pthread.h>
 #endif
 
-#include <Availability.h>
-
 #ifndef NO_TCMALLOC_SAMPLES
 #ifdef WTF_CHANGES
 #define NO_TCMALLOC_SAMPLES
 #define FORCE_SYSTEM_MALLOC 1
 #endif
 
-#define TCMALLOC_TRACK_DECOMMITED_SPANS (HAVE(VIRTUALALLOC))
+
+// Use a background thread to periodically scavenge memory to release back to the system
+// https://bugs.webkit.org/show_bug.cgi?id=27900: don't turn this on for Tiger until we have figured out why it caused a crash.
+#define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 0
 
 #ifndef NDEBUG
 namespace WTF {
@@ -153,6 +155,19 @@ void fastMallocAllow()
 
 namespace WTF {
 
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+
+namespace Internal {
+
+void fastMallocMatchFailed(void*)
+{
+    CRASH();
+}
+
+} // namespace Internal
+
+#endif
+
 void* fastZeroedMalloc(size_t n) 
 {
     void* result = fastMalloc(n);
@@ -185,13 +200,34 @@ namespace WTF {
 void* tryFastMalloc(size_t n) 
 {
     ASSERT(!isForbidden());
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= n)  // If overflow would occur...
+        return 0;
+
+    void* result = malloc(n + sizeof(AllocAlignmentInteger));
+    if (!result)
+        return 0;
+
+    *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc;
+    result = static_cast<AllocAlignmentInteger*>(result) + 1;
+
+    return result;
+#else
     return malloc(n);
+#endif
 }
 
 void* fastMalloc(size_t n) 
 {
     ASSERT(!isForbidden());
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    void* result = tryFastMalloc(n);
+#else
     void* result = malloc(n);
+#endif
+
     if (!result)
         CRASH();
     return result;
@@ -200,13 +236,36 @@ void* fastMalloc(size_t n)
 void* tryFastCalloc(size_t n_elements, size_t element_size)
 {
     ASSERT(!isForbidden());
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    size_t totalBytes = n_elements * element_size;
+    if (n_elements > 1 && element_size && (totalBytes / element_size) != n_elements || (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= totalBytes))
+        return 0;
+
+    totalBytes += sizeof(AllocAlignmentInteger);
+    void* result = malloc(totalBytes);
+    if (!result)
+        return 0;
+
+    memset(result, 0, totalBytes);
+    *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc;
+    result = static_cast<AllocAlignmentInteger*>(result) + 1;
+    return result;
+#else
     return calloc(n_elements, element_size);
+#endif
 }
 
 void* fastCalloc(size_t n_elements, size_t element_size)
 {
     ASSERT(!isForbidden());
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    void* result = tryFastCalloc(n_elements, element_size);
+#else
     void* result = calloc(n_elements, element_size);
+#endif
+
     if (!result)
         CRASH();
     return result;
@@ -215,19 +274,57 @@ void* fastCalloc(size_t n_elements, size_t element_size)
 void fastFree(void* p)
 {
     ASSERT(!isForbidden());
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    if (!p)
+        return;
+
+    AllocAlignmentInteger* header = Internal::fastMallocMatchValidationValue(p);
+    if (*header != Internal::AllocTypeMalloc)
+        Internal::fastMallocMatchFailed(p);
+    free(header);
+#else
     free(p);
+#endif
 }
 
 void* tryFastRealloc(void* p, size_t n)
 {
     ASSERT(!isForbidden());
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    if (p) {
+        if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= n)  // If overflow would occur...
+            return 0;
+        AllocAlignmentInteger* header = Internal::fastMallocMatchValidationValue(p);
+        if (*header != Internal::AllocTypeMalloc)
+            Internal::fastMallocMatchFailed(p);
+        void* result = realloc(header, n + sizeof(AllocAlignmentInteger));
+        if (!result)
+            return 0;
+
+        // This should not be needed because the value is already there:
+        // *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc;
+        result = static_cast<AllocAlignmentInteger*>(result) + 1;
+        return result;
+    } else {
+        return fastMalloc(n);
+    }
+#else
     return realloc(p, n);
+#endif
 }
 
 void* fastRealloc(void* p, size_t n)
 {
     ASSERT(!isForbidden());
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    void* result = tryFastRealloc(p, n);
+#else
     void* result = realloc(p, n);
+#endif
+
     if (!result)
         CRASH();
     return result;
@@ -267,6 +364,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0;
 #include "TCSystemAlloc.h"
 #include <algorithm>
 #include <errno.h>
+#include <limits>
 #include <new>
 #include <pthread.h>
 #include <stdarg.h>
@@ -323,9 +421,11 @@ namespace WTF {
 #define CHECK_CONDITION ASSERT
 
 #if PLATFORM(DARWIN)
+class Span;
+class TCMalloc_Central_FreeListPadded;
 class TCMalloc_PageHeap;
 class TCMalloc_ThreadCache;
-class TCMalloc_Central_FreeListPadded;
+template <typename T> class PageHeapAllocator;
 
 class FastMallocZone {
 public:
@@ -341,7 +441,7 @@ public:
     static void statistics(malloc_zone_t*, malloc_statistics_t* stats) { memset(stats, 0, sizeof(malloc_statistics_t)); }
 
 private:
-    FastMallocZone(TCMalloc_PageHeap*, TCMalloc_ThreadCache**, TCMalloc_Central_FreeListPadded*);
+    FastMallocZone(TCMalloc_PageHeap*, TCMalloc_ThreadCache**, TCMalloc_Central_FreeListPadded*, PageHeapAllocator<Span>*, PageHeapAllocator<TCMalloc_ThreadCache>*);
     static size_t size(malloc_zone_t*, const void*);
     static void* zoneMalloc(malloc_zone_t*, size_t);
     static void* zoneCalloc(malloc_zone_t*, size_t numItems, size_t size);
@@ -354,6 +454,8 @@ private:
     TCMalloc_PageHeap* m_pageHeap;
     TCMalloc_ThreadCache** m_threadHeaps;
     TCMalloc_Central_FreeListPadded* m_centralCaches;
+    PageHeapAllocator<Span>* m_spanAllocator;
+    PageHeapAllocator<TCMalloc_ThreadCache>* m_pageHeapAllocator;
 };
 
 #endif
@@ -822,6 +924,9 @@ class PageHeapAllocator {
   char* free_area_;
   size_t free_avail_;
 
+  // Linked list of all regions allocated by this allocator
+  void* allocated_regions_;
+
   // Free list of already carved objects
   void* free_list_;
 
@@ -832,6 +937,7 @@ class PageHeapAllocator {
   void Init() {
     ASSERT(kAlignedSize <= kAllocIncrement);
     inuse_ = 0;
+    allocated_regions_ = 0;
     free_area_ = NULL;
     free_avail_ = 0;
     free_list_ = NULL;
@@ -846,9 +952,14 @@ class PageHeapAllocator {
     } else {
       if (free_avail_ < kAlignedSize) {
         // Need more room
-        free_area_ = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));
-        if (free_area_ == NULL) CRASH();
-        free_avail_ = kAllocIncrement;
+        char* new_allocation = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement));
+        if (!new_allocation)
+          CRASH();
+
+        *(void**)new_allocation = allocated_regions_;
+        allocated_regions_ = new_allocation;
+        free_area_ = new_allocation + kAlignedSize;
+        free_avail_ = kAllocIncrement - kAlignedSize;
       }
       result = free_area_;
       free_area_ += kAlignedSize;
@@ -865,6 +976,18 @@ class PageHeapAllocator {
   }
 
   int inuse() const { return inuse_; }
+
+#if defined(WTF_CHANGES) && PLATFORM(DARWIN)
+  template <class Recorder>
+  void recordAdministrativeRegions(Recorder& recorder, const RemoteMemoryReader& reader)
+  {
+      vm_address_t adminAllocation = reinterpret_cast<vm_address_t>(allocated_regions_);
+      while (adminAllocation) {
+          recorder.recordRegion(adminAllocation, kAllocIncrement);
+          adminAllocation = *reader(reinterpret_cast<vm_address_t*>(adminAllocation));
+      }
+  }
+#endif
 };
 
 // -------------------------------------------------------------------------
@@ -923,11 +1046,7 @@ struct Span {
 #endif
 };
 
-#if TCMALLOC_TRACK_DECOMMITED_SPANS
 #define ASSERT_SPAN_COMMITTED(span) ASSERT(!span->decommitted)
-#else
-#define ASSERT_SPAN_COMMITTED(span)
-#endif
 
 #ifdef SPAN_HISTORY
 void Event(Span* span, char op, int v = 0) {
@@ -1073,6 +1192,32 @@ template <> class MapSelector<32> {
 // contiguous runs of pages (called a "span").
 // -------------------------------------------------------------------------
 
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+// The central page heap collects spans of memory that have been deleted but are still committed until they are released
+// back to the system.  We use a background thread to periodically scan the list of free spans and release some back to the
+// system.  Every 5 seconds, the background thread wakes up and does the following:
+// - Check if we needed to commit memory in the last 5 seconds.  If so, skip this scavenge because it's a sign that we are short
+// of free committed pages and so we should not release them back to the system yet.
+// - Otherwise, go through the list of free spans (from largest to smallest) and release up to a fraction of the free committed pages
+// back to the system.
+// - If the number of free committed pages reaches kMinimumFreeCommittedPageCount, we can stop the scavenging and block the
+// scavenging thread until the number of free committed pages goes above kMinimumFreeCommittedPageCount.
+
+// Background thread wakes up every 5 seconds to scavenge as long as there is memory available to return to the system.
+static const int kScavengeTimerDelayInSeconds = 5;
+
+// Number of free committed pages that we want to keep around.
+static const size_t kMinimumFreeCommittedPageCount = 512;
+
+// During a scavenge, we'll release up to a fraction of the free committed pages.
+#if PLATFORM(WIN)
+// We are slightly less aggressive in releasing memory on Windows due to performance reasons.
+static const int kMaxScavengeAmountFactor = 3;
+#else
+static const int kMaxScavengeAmountFactor = 2;
+#endif
+#endif
+
 class TCMalloc_PageHeap {
  public:
   void init();
@@ -1172,6 +1317,14 @@ class TCMalloc_PageHeap {
   // Bytes allocated from system
   uint64_t system_bytes_;
 
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+  // Number of pages kept in free lists that are still committed.
+  Length free_committed_pages_;
+
+  // Number of pages that we committed in the last scavenge wait interval.
+  Length pages_committed_since_last_scavenge_;
+#endif
+
   bool GrowHeap(Length n);
 
   // REQUIRES   span->length >= n
@@ -1194,9 +1347,11 @@ class TCMalloc_PageHeap {
   // span of exactly the specified length.  Else, returns NULL.
   Span* AllocLarge(Length n);
 
+#if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
   // Incrementally release some memory to the system.
   // IncrementalScavenge(n) is called whenever n pages are freed.
   void IncrementalScavenge(Length n);
+#endif
 
   // Number of pages to deallocate before doing more scavenging
   int64_t scavenge_counter_;
@@ -1207,6 +1362,24 @@ class TCMalloc_PageHeap {
 #if defined(WTF_CHANGES) && PLATFORM(DARWIN)
   friend class FastMallocZone;
 #endif
+
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+  static NO_RETURN void* runScavengerThread(void*);
+
+  NO_RETURN void scavengerThread();
+
+  void scavenge();
+
+  inline bool shouldContinueScavenging() const;
+
+  pthread_mutex_t m_scavengeMutex;
+
+  pthread_cond_t m_scavengeCondition;
+
+  // Keeps track of whether the background thread is actively scavenging memory every kScavengeTimerDelayInSeconds, or
+  // it's blocked waiting for more pages to be deleted.
+  bool m_scavengeThreadActive;
+#endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
 };
 
 void TCMalloc_PageHeap::init()
@@ -1215,6 +1388,12 @@ void TCMalloc_PageHeap::init()
   pagemap_cache_ = PageMapCache(0);
   free_pages_ = 0;
   system_bytes_ = 0;
+
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+  free_committed_pages_ = 0;
+  pages_committed_since_last_scavenge_ = 0;
+#endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+
   scavenge_counter_ = 0;
   // Start scavenging at kMaxPages list
   scavenge_index_ = kMaxPages-1;
@@ -1225,8 +1404,68 @@ void TCMalloc_PageHeap::init()
     DLL_Init(&free_[i].normal);
     DLL_Init(&free_[i].returned);
   }
+
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+  pthread_mutex_init(&m_scavengeMutex, 0);
+  pthread_cond_init(&m_scavengeCondition, 0);
+  m_scavengeThreadActive = true;
+  pthread_t thread;
+  pthread_create(&thread, 0, runScavengerThread, this);
+#endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
 }
 
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+void* TCMalloc_PageHeap::runScavengerThread(void* context)
+{
+  static_cast<TCMalloc_PageHeap*>(context)->scavengerThread();
+#if COMPILER(MSVC)
+  // Without this, Visual Studio will complain that this method does not return a value.
+  return 0;
+#endif
+}
+
+void TCMalloc_PageHeap::scavenge() 
+{
+    // If we have to commit memory in the last 5 seconds, it means we don't have enough free committed pages
+    // for the amount of allocations that we do.  So hold off on releasing memory back to the system.
+    if (pages_committed_since_last_scavenge_ > 0) {
+        pages_committed_since_last_scavenge_ = 0;
+        return;
+    }
+    Length pagesDecommitted = 0;
+    for (int i = kMaxPages; i >= 0; i--) {
+        SpanList* slist = (static_cast<size_t>(i) == kMaxPages) ? &large_ : &free_[i];
+        if (!DLL_IsEmpty(&slist->normal)) {
+            // Release the last span on the normal portion of this list
+            Span* s = slist->normal.prev; 
+            // Only decommit up to a fraction of the free committed pages if pages_allocated_since_last_scavenge_ > 0.
+            if ((pagesDecommitted + s->length) * kMaxScavengeAmountFactor > free_committed_pages_)
+                continue;
+            DLL_Remove(s);
+            TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
+                                   static_cast<size_t>(s->length << kPageShift));
+            if (!s->decommitted) {
+                pagesDecommitted += s->length;
+                s->decommitted = true;
+            }
+            DLL_Prepend(&slist->returned, s);
+            // We can stop scavenging if the number of free committed pages left is less than or equal to the minimum number we want to keep around.
+            if (free_committed_pages_ <= kMinimumFreeCommittedPageCount + pagesDecommitted)
+                break;
+        }
+    }
+    pages_committed_since_last_scavenge_ = 0;
+    ASSERT(free_committed_pages_ >= pagesDecommitted);
+    free_committed_pages_ -= pagesDecommitted;
+}
+
+inline bool TCMalloc_PageHeap::shouldContinueScavenging() const 
+{
+    return free_committed_pages_ > kMinimumFreeCommittedPageCount; 
+}
+
+#endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+
 inline Span* TCMalloc_PageHeap::New(Length n) {
   ASSERT(Check());
   ASSERT(n > 0);
@@ -1249,12 +1488,21 @@ inline Span* TCMalloc_PageHeap::New(Length n) {
 
     Span* result = ll->next;
     Carve(result, n, released);
-#if TCMALLOC_TRACK_DECOMMITED_SPANS
     if (result->decommitted) {
         TCMalloc_SystemCommit(reinterpret_cast<void*>(result->start << kPageShift), static_cast<size_t>(n << kPageShift));
         result->decommitted = false;
-    }
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+        pages_committed_since_last_scavenge_ += n;
 #endif
+    }
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+    else {
+        // The newly allocated memory is from a span that's in the normal span list (already committed).  Update the
+        // free committed pages count.
+        ASSERT(free_committed_pages_ >= n);
+        free_committed_pages_ -= n;
+    }
+#endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
     ASSERT(Check());
     free_pages_ -= n;
     return result;
@@ -1311,12 +1559,21 @@ Span* TCMalloc_PageHeap::AllocLarge(Length n) {
 
   if (best != NULL) {
     Carve(best, n, from_released);
-#if TCMALLOC_TRACK_DECOMMITED_SPANS
     if (best->decommitted) {
         TCMalloc_SystemCommit(reinterpret_cast<void*>(best->start << kPageShift), static_cast<size_t>(n << kPageShift));
         best->decommitted = false;
-    }
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+        pages_committed_since_last_scavenge_ += n;
 #endif
+    }
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+    else {
+        // The newly allocated memory is from a span that's in the normal span list (already committed).  Update the
+        // free committed pages count.
+        ASSERT(free_committed_pages_ >= n);
+        free_committed_pages_ -= n;
+    }
+#endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
     ASSERT(Check());
     free_pages_ -= n;
     return best;
@@ -1341,14 +1598,10 @@ Span* TCMalloc_PageHeap::Split(Span* span, Length n) {
   return leftover;
 }
 
-#if !TCMALLOC_TRACK_DECOMMITED_SPANS
-static ALWAYS_INLINE void propagateDecommittedState(Span*, Span*) { }
-#else
 static ALWAYS_INLINE void propagateDecommittedState(Span* destination, Span* source)
 {
     destination->decommitted = source->decommitted;
 }
-#endif
 
 inline void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) {
   ASSERT(n > 0);
@@ -1375,15 +1628,17 @@ inline void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) {
   }
 }
 
-#if !TCMALLOC_TRACK_DECOMMITED_SPANS
-static ALWAYS_INLINE void mergeDecommittedStates(Span*, Span*) { }
-#else
 static ALWAYS_INLINE void mergeDecommittedStates(Span* destination, Span* other)
 {
-    if (other->decommitted)
+    if (destination->decommitted && !other->decommitted) {
+        TCMalloc_SystemRelease(reinterpret_cast<void*>(other->start << kPageShift),
+                               static_cast<size_t>(other->length << kPageShift));
+    } else if (other->decommitted && !destination->decommitted) {
+        TCMalloc_SystemRelease(reinterpret_cast<void*>(destination->start << kPageShift),
+                               static_cast<size_t>(destination->length << kPageShift));
         destination->decommitted = true;
+    }
 }
-#endif
 
 inline void TCMalloc_PageHeap::Delete(Span* span) {
   ASSERT(Check());
@@ -1400,10 +1655,10 @@ inline void TCMalloc_PageHeap::Delete(Span* span) {
   // necessary.  We do not bother resetting the stale pagemap
   // entries for the pieces we are merging together because we only
   // care about the pagemap entries for the boundaries.
-  //
-  // Note that the spans we merge into "span" may come out of
-  // a "returned" list.  For simplicity, we move these into the
-  // "normal" list of the appropriate size class.
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+  // Track the total size of the neighboring free spans that are committed.
+  Length neighboringCommittedSpansLength = 0;
+#endif
   const PageID p = span->start;
   const Length n = span->length;
   Span* prev = GetDescriptor(p-1);
@@ -1411,6 +1666,10 @@ inline void TCMalloc_PageHeap::Delete(Span* span) {
     // Merge preceding span into this span
     ASSERT(prev->start + prev->length == p);
     const Length len = prev->length;
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+    if (!prev->decommitted)
+        neighboringCommittedSpansLength += len;
+#endif
     mergeDecommittedStates(span, prev);
     DLL_Remove(prev);
     DeleteSpan(prev);
@@ -1424,6 +1683,10 @@ inline void TCMalloc_PageHeap::Delete(Span* span) {
     // Merge next span into this span
     ASSERT(next->start == p+n);
     const Length len = next->length;
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+    if (!next->decommitted)
+        neighboringCommittedSpansLength += len;
+#endif
     mergeDecommittedStates(span, next);
     DLL_Remove(next);
     DeleteSpan(next);
@@ -1434,17 +1697,40 @@ inline void TCMalloc_PageHeap::Delete(Span* span) {
 
   Event(span, 'D', span->length);
   span->free = 1;
-  if (span->length < kMaxPages) {
-    DLL_Prepend(&free_[span->length].normal, span);
+  if (span->decommitted) {
+    if (span->length < kMaxPages)
+      DLL_Prepend(&free_[span->length].returned, span);
+    else
+      DLL_Prepend(&large_.returned, span);
   } else {
-    DLL_Prepend(&large_.normal, span);
+    if (span->length < kMaxPages)
+      DLL_Prepend(&free_[span->length].normal, span);
+    else
+      DLL_Prepend(&large_.normal, span);
   }
   free_pages_ += n;
 
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+  if (span->decommitted) {
+      // If the merged span is decommitted, that means we decommitted any neighboring spans that were
+      // committed.  Update the free committed pages count.
+      free_committed_pages_ -= neighboringCommittedSpansLength;
+  } else {
+      // If the merged span remains committed, add the deleted span's size to the free committed pages count.
+      free_committed_pages_ += n;
+  }
+
+  // Make sure the scavenge thread becomes active if we have enough freed pages to release some back to the system.
+  if (!m_scavengeThreadActive && shouldContinueScavenging())
+      pthread_cond_signal(&m_scavengeCondition);
+#else
   IncrementalScavenge(n);
+#endif
+
   ASSERT(Check());
 }
 
+#if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
 void TCMalloc_PageHeap::IncrementalScavenge(Length n) {
   // Fast path; not yet time to release memory
   scavenge_counter_ -= n;
@@ -1463,9 +1749,7 @@ void TCMalloc_PageHeap::IncrementalScavenge(Length n) {
       DLL_Remove(s);
       TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
                              static_cast<size_t>(s->length << kPageShift));
-#if TCMALLOC_TRACK_DECOMMITED_SPANS
       s->decommitted = true;
-#endif
       DLL_Prepend(&slist->returned, s);
 
       scavenge_counter_ = std::max<size_t>(16UL, std::min<size_t>(kDefaultReleaseDelay, kDefaultReleaseDelay - (free_pages_ / kDefaultReleaseDelay)));
@@ -1482,6 +1766,7 @@ void TCMalloc_PageHeap::IncrementalScavenge(Length n) {
   // Nothing to scavenge, delay for a while
   scavenge_counter_ = kDefaultReleaseDelay;
 }
+#endif
 
 void TCMalloc_PageHeap::RegisterSizeClass(Span* span, size_t sc) {
   // Associate span object with all interior pages as well
@@ -1593,6 +1878,10 @@ bool TCMalloc_PageHeap::GrowHeap(Length n) {
   }
   ask = actual_size >> kPageShift;
 
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+  pages_committed_since_last_scavenge_ += ask;
+#endif
+
   uint64_t old_system_bytes = system_bytes_;
   system_bytes_ += (ask << kPageShift);
   const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
@@ -1978,6 +2267,38 @@ static inline TCMalloc_PageHeap* getPageHeap()
 
 #define pageheap getPageHeap()
 
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+#if PLATFORM(WIN)
+static void sleep(unsigned seconds)
+{
+    ::Sleep(seconds * 1000);
+}
+#endif
+
+void TCMalloc_PageHeap::scavengerThread()
+{
+#if HAVE(PTHREAD_SETNAME_NP)
+  pthread_setname_np("JavaScriptCore: FastMalloc scavenger");
+#endif
+
+  while (1) {
+      if (!shouldContinueScavenging()) {
+          pthread_mutex_lock(&m_scavengeMutex);
+          m_scavengeThreadActive = false;
+          // Block until there are enough freed pages to release back to the system.
+          pthread_cond_wait(&m_scavengeCondition, &m_scavengeMutex);
+          m_scavengeThreadActive = true;
+          pthread_mutex_unlock(&m_scavengeMutex);
+      }
+      sleep(kScavengeTimerDelayInSeconds);
+      {
+          SpinLockHolder h(&pageheap_lock);
+          pageheap->scavenge();
+      }
+  }
+}
+#endif
+
 // If TLS is available, we also store a copy
 // of the per-thread object in a __thread variable
 // since __thread variables are faster to read
@@ -3268,7 +3589,20 @@ template <bool crashOnFailure>
 ALWAYS_INLINE
 #endif
 void* malloc(size_t size) {
-  void* result = do_malloc(size);
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= size)  // If overflow would occur...
+        return 0;
+    size += sizeof(AllocAlignmentInteger);
+    void* result = do_malloc(size);
+    if (!result)
+        return 0;
+
+    *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc;
+    result = static_cast<AllocAlignmentInteger*>(result) + 1;
+#else
+    void* result = do_malloc(size);
+#endif
+
 #ifndef WTF_CHANGES
   MallocHook::InvokeNewHook(result, size);
 #endif
@@ -3282,7 +3616,18 @@ void free(void* ptr) {
 #ifndef WTF_CHANGES
   MallocHook::InvokeDeleteHook(ptr);
 #endif
-  do_free(ptr);
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    if (!ptr)
+        return;
+
+    AllocAlignmentInteger* header = Internal::fastMallocMatchValidationValue(ptr);
+    if (*header != Internal::AllocTypeMalloc)
+        Internal::fastMallocMatchFailed(ptr);
+    do_free(header);
+#else
+    do_free(ptr);
+#endif
 }
 
 #ifndef WTF_CHANGES
@@ -3305,16 +3650,31 @@ template <bool crashOnFailure>
 ALWAYS_INLINE
 #endif
 void* calloc(size_t n, size_t elem_size) {
-  const size_t totalBytes = n * elem_size;
+  size_t totalBytes = n * elem_size;
     
   // Protect against overflow
   if (n > 1 && elem_size && (totalBytes / elem_size) != n)
     return 0;
-    
-  void* result = do_malloc(totalBytes);
-  if (result != NULL) {
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= totalBytes)  // If overflow would occur...
+        return 0;
+
+    totalBytes += sizeof(AllocAlignmentInteger);
+    void* result = do_malloc(totalBytes);
+    if (!result)
+        return 0;
+
     memset(result, 0, totalBytes);
-  }
+    *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc;
+    result = static_cast<AllocAlignmentInteger*>(result) + 1;
+#else
+    void* result = do_malloc(totalBytes);
+    if (result != NULL) {
+        memset(result, 0, totalBytes);
+    }
+#endif
+
 #ifndef WTF_CHANGES
   MallocHook::InvokeNewHook(result, totalBytes);
 #endif
@@ -3355,9 +3715,13 @@ ALWAYS_INLINE
 #endif
 void* realloc(void* old_ptr, size_t new_size) {
   if (old_ptr == NULL) {
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    void* result = malloc(new_size);
+#else
     void* result = do_malloc(new_size);
 #ifndef WTF_CHANGES
     MallocHook::InvokeNewHook(result, new_size);
+#endif
 #endif
     return result;
   }
@@ -3369,6 +3733,16 @@ void* realloc(void* old_ptr, size_t new_size) {
     return NULL;
   }
 
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= new_size)  // If overflow would occur...
+        return 0;
+    new_size += sizeof(AllocAlignmentInteger);
+    AllocAlignmentInteger* header = Internal::fastMallocMatchValidationValue(old_ptr);
+    if (*header != Internal::AllocTypeMalloc)
+        Internal::fastMallocMatchFailed(old_ptr);
+    old_ptr = header;
+#endif
+
   // Get the size of the old entry
   const PageID p = reinterpret_cast<uintptr_t>(old_ptr) >> kPageShift;
   size_t cl = pageheap->GetSizeClassIfCached(p);
@@ -3405,8 +3779,14 @@ void* realloc(void* old_ptr, size_t new_size) {
     // that we already know the sizeclass of old_ptr.  The benefit
     // would be small, so don't bother.
     do_free(old_ptr);
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    new_ptr = static_cast<AllocAlignmentInteger*>(new_ptr) + 1;
+#endif
     return new_ptr;
   } else {
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+    old_ptr = pByte + sizeof(AllocAlignmentInteger);  // Set old_ptr back to the user pointer.
+#endif
     return old_ptr;
   }
 }
@@ -3576,7 +3956,7 @@ extern "C" struct mallinfo mallinfo(void) {
 
 #if defined(__GLIBC__)
 extern "C" {
-# if defined(__GNUC__) && !defined(__MACH__) && defined(HAVE___ATTRIBUTE__)
+#if COMPILER(GCC) && !defined(__MACH__) && defined(HAVE___ATTRIBUTE__)
   // Potentially faster variants that use the gcc alias extension.
   // Mach-O (Darwin) does not support weak aliases, hence the __MACH__ check.
 # define ALIAS(x) __attribute__ ((weak, alias (x)))
@@ -3635,6 +4015,7 @@ public:
 
     void visit(void* ptr) { m_freeObjects.add(ptr); }
     bool isFreeObject(void* ptr) const { return m_freeObjects.contains(ptr); }
+    bool isFreeObject(vm_address_t ptr) const { return isFreeObject(reinterpret_cast<void*>(ptr)); }
     size_t freeObjectCount() const { return m_freeObjects.size(); }
 
     void findFreeObjects(TCMalloc_ThreadCache* threadCache)
@@ -3685,7 +4066,9 @@ class PageMapMemoryUsageRecorder {
     vm_range_recorder_t* m_recorder;
     const RemoteMemoryReader& m_reader;
     const FreeObjectFinder& m_freeObjectFinder;
-    mutable HashSet<void*> m_seenPointers;
+
+    HashSet<void*> m_seenPointers;
+    Vector<Span*> m_coalescedSpans;
 
 public:
     PageMapMemoryUsageRecorder(task_t task, void* context, unsigned typeMask, vm_range_recorder_t* recorder, const RemoteMemoryReader& reader, const FreeObjectFinder& freeObjectFinder)
@@ -3697,51 +4080,133 @@ public:
         , m_freeObjectFinder(freeObjectFinder)
     { }
 
-    int visit(void* ptr) const
+    ~PageMapMemoryUsageRecorder()
+    {
+        ASSERT(!m_coalescedSpans.size());
+    }
+
+    void recordPendingRegions()
+    {
+        Span* lastSpan = m_coalescedSpans[m_coalescedSpans.size() - 1];
+        vm_range_t ptrRange = { m_coalescedSpans[0]->start << kPageShift, 0 };
+        ptrRange.size = (lastSpan->start << kPageShift) - ptrRange.address + (lastSpan->length * kPageSize);
+
+        // Mark the memory region the spans represent as a candidate for containing pointers
+        if (m_typeMask & MALLOC_PTR_REGION_RANGE_TYPE)
+            (*m_recorder)(m_task, m_context, MALLOC_PTR_REGION_RANGE_TYPE, &ptrRange, 1);
+
+        if (!(m_typeMask & MALLOC_PTR_IN_USE_RANGE_TYPE)) {
+            m_coalescedSpans.clear();
+            return;
+        }
+
+        Vector<vm_range_t, 1024> allocatedPointers;
+        for (size_t i = 0; i < m_coalescedSpans.size(); ++i) {
+            Span *theSpan = m_coalescedSpans[i];
+            if (theSpan->free)
+                continue;
+
+            vm_address_t spanStartAddress = theSpan->start << kPageShift;
+            vm_size_t spanSizeInBytes = theSpan->length * kPageSize;
+
+            if (!theSpan->sizeclass) {
+                // If it's an allocated large object span, mark it as in use
+                if (!m_freeObjectFinder.isFreeObject(spanStartAddress))
+                    allocatedPointers.append((vm_range_t){spanStartAddress, spanSizeInBytes});
+            } else {
+                const size_t objectSize = ByteSizeForClass(theSpan->sizeclass);
+
+                // Mark each allocated small object within the span as in use
+                const vm_address_t endOfSpan = spanStartAddress + spanSizeInBytes;
+                for (vm_address_t object = spanStartAddress; object + objectSize <= endOfSpan; object += objectSize) {
+                    if (!m_freeObjectFinder.isFreeObject(object))
+                        allocatedPointers.append((vm_range_t){object, objectSize});
+                }
+            }
+        }
+
+        (*m_recorder)(m_task, m_context, MALLOC_PTR_IN_USE_RANGE_TYPE, allocatedPointers.data(), allocatedPointers.size());
+
+        m_coalescedSpans.clear();
+    }
+
+    int visit(void* ptr)
     {
         if (!ptr)
             return 1;
 
         Span* span = m_reader(reinterpret_cast<Span*>(ptr));
+        if (!span->start)
+            return 1;
+
         if (m_seenPointers.contains(ptr))
             return span->length;
         m_seenPointers.add(ptr);
 
-        // Mark the memory used for the Span itself as an administrative region
-        vm_range_t ptrRange = { reinterpret_cast<vm_address_t>(ptr), sizeof(Span) };
-        if (m_typeMask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE))
-            (*m_recorder)(m_task, m_context, MALLOC_ADMIN_REGION_RANGE_TYPE, &ptrRange, 1);
+        if (!m_coalescedSpans.size()) {
+            m_coalescedSpans.append(span);
+            return span->length;
+        }
 
-        ptrRange.address = span->start << kPageShift;
-        ptrRange.size = span->length * kPageSize;
+        Span* previousSpan = m_coalescedSpans[m_coalescedSpans.size() - 1];
+        vm_address_t previousSpanStartAddress = previousSpan->start << kPageShift;
+        vm_size_t previousSpanSizeInBytes = previousSpan->length * kPageSize;
 
-        // Mark the memory region the span represents as candidates for containing pointers
-        if (m_typeMask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE))
-            (*m_recorder)(m_task, m_context, MALLOC_PTR_REGION_RANGE_TYPE, &ptrRange, 1);
+        // If the new span is adjacent to the previous span, do nothing for now.
+        vm_address_t spanStartAddress = span->start << kPageShift;
+        if (spanStartAddress == previousSpanStartAddress + previousSpanSizeInBytes) {
+            m_coalescedSpans.append(span);
+            return span->length;
+        }
 
-        if (!span->free && (m_typeMask & MALLOC_PTR_IN_USE_RANGE_TYPE)) {
-            // If it's an allocated large object span, mark it as in use
-            if (span->sizeclass == 0 && !m_freeObjectFinder.isFreeObject(reinterpret_cast<void*>(ptrRange.address)))
-                (*m_recorder)(m_task, m_context, MALLOC_PTR_IN_USE_RANGE_TYPE, &ptrRange, 1);
-            else if (span->sizeclass) {
-                const size_t byteSize = ByteSizeForClass(span->sizeclass);
-                unsigned totalObjects = (span->length << kPageShift) / byteSize;
-                ASSERT(span->refcount <= totalObjects);
-                char* ptr = reinterpret_cast<char*>(span->start << kPageShift);
+        // New span is not adjacent to previous span, so record the spans coalesced so far.
+        recordPendingRegions();
+        m_coalescedSpans.append(span);
 
-                // Mark each allocated small object within the span as in use
-                for (unsigned i = 0; i < totalObjects; i++) {
-                    char* thisObject = ptr + (i * byteSize);
-                    if (m_freeObjectFinder.isFreeObject(thisObject))
-                        continue;
+        return span->length;
+    }
+};
 
-                    vm_range_t objectRange = { reinterpret_cast<vm_address_t>(thisObject), byteSize };
-                    (*m_recorder)(m_task, m_context, MALLOC_PTR_IN_USE_RANGE_TYPE, &objectRange, 1);
-                }
-            }
+class AdminRegionRecorder {
+    task_t m_task;
+    void* m_context;
+    unsigned m_typeMask;
+    vm_range_recorder_t* m_recorder;
+    const RemoteMemoryReader& m_reader;
+
+    Vector<vm_range_t, 1024> m_pendingRegions;
+
+public:
+    AdminRegionRecorder(task_t task, void* context, unsigned typeMask, vm_range_recorder_t* recorder, const RemoteMemoryReader& reader)
+        : m_task(task)
+        , m_context(context)
+        , m_typeMask(typeMask)
+        , m_recorder(recorder)
+        , m_reader(reader)
+    { }
+
+    void recordRegion(vm_address_t ptr, size_t size)
+    {
+        if (m_typeMask & MALLOC_ADMIN_REGION_RANGE_TYPE)
+            m_pendingRegions.append((vm_range_t){ ptr, size });
+    }
+
+    void visit(void *ptr, size_t size)
+    {
+        recordRegion(reinterpret_cast<vm_address_t>(ptr), size);
+    }
+
+    void recordPendingRegions()
+    {
+        if (m_pendingRegions.size()) {
+            (*m_recorder)(m_task, m_context, MALLOC_ADMIN_REGION_RANGE_TYPE, m_pendingRegions.data(), m_pendingRegions.size());
+            m_pendingRegions.clear();
         }
+    }
 
-        return span->length;
+    ~AdminRegionRecorder()
+    {
+        ASSERT(!m_pendingRegions.size());
     }
 };
 
@@ -3764,10 +4229,22 @@ kern_return_t FastMallocZone::enumerate(task_t task, void* context, unsigned typ
 
     TCMalloc_PageHeap::PageMap* pageMap = &pageHeap->pagemap_;
     PageMapFreeObjectFinder pageMapFinder(memoryReader, finder);
-    pageMap->visit(pageMapFinder, memoryReader);
+    pageMap->visitValues(pageMapFinder, memoryReader);
 
     PageMapMemoryUsageRecorder usageRecorder(task, context, typeMask, recorder, memoryReader, finder);
-    pageMap->visit(usageRecorder, memoryReader);
+    pageMap->visitValues(usageRecorder, memoryReader);
+    usageRecorder.recordPendingRegions();
+
+    AdminRegionRecorder adminRegionRecorder(task, context, typeMask, recorder, memoryReader);
+    pageMap->visitAllocations(adminRegionRecorder, memoryReader);
+
+    PageHeapAllocator<Span>* spanAllocator = memoryReader(mzone->m_spanAllocator);
+    PageHeapAllocator<TCMalloc_ThreadCache>* pageHeapAllocator = memoryReader(mzone->m_pageHeapAllocator);
+
+    spanAllocator->recordAdministrativeRegions(adminRegionRecorder, memoryReader);
+    pageHeapAllocator->recordAdministrativeRegions(adminRegionRecorder, memoryReader);
+
+    adminRegionRecorder.recordPendingRegions();
 
     return 0;
 }
@@ -3809,13 +4286,20 @@ void* FastMallocZone::zoneRealloc(malloc_zone_t*, void*, size_t)
 extern "C" {
 malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enumerate, &FastMallocZone::goodSize, &FastMallocZone::check, &FastMallocZone::print,
     &FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics
+
+#if !PLATFORM(IPHONE_SIMULATOR)
+    , 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher.
+#endif
+
     };
 }
 
-FastMallocZone::FastMallocZone(TCMalloc_PageHeap* pageHeap, TCMalloc_ThreadCache** threadHeaps, TCMalloc_Central_FreeListPadded* centralCaches)
+FastMallocZone::FastMallocZone(TCMalloc_PageHeap* pageHeap, TCMalloc_ThreadCache** threadHeaps, TCMalloc_Central_FreeListPadded* centralCaches, PageHeapAllocator<Span>* spanAllocator, PageHeapAllocator<TCMalloc_ThreadCache>* pageHeapAllocator)
     : m_pageHeap(pageHeap)
     , m_threadHeaps(threadHeaps)
     , m_centralCaches(centralCaches)
+    , m_spanAllocator(spanAllocator)
+    , m_pageHeapAllocator(pageHeapAllocator)
 {
     memset(&m_zone, 0, sizeof(m_zone));
     m_zone.version = 4;
@@ -3834,7 +4318,7 @@ FastMallocZone::FastMallocZone(TCMalloc_PageHeap* pageHeap, TCMalloc_ThreadCache
 
 void FastMallocZone::init()
 {
-    static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Central_FreeListPadded*>(central_cache));
+    static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Central_FreeListPadded*>(central_cache), &span_allocator, &threadheap_allocator);
 }
 
 #endif
index f1264ac92f5844c8f17b6f601a4db77a8eda9c2a..61ebe327e433758555a1c331fbf8f726a9cc3d67 100644 (file)
@@ -56,6 +56,95 @@ namespace WTF {
     };
     FastMallocStatistics fastMallocStatistics();
 
+    // This defines a type which holds an unsigned integer and is the same
+    // size as the minimally aligned memory allocation.
+    typedef unsigned long long AllocAlignmentInteger;
+
+    namespace Internal {
+        enum AllocType {                    // Start with an unusual number instead of zero, because zero is common.
+            AllocTypeMalloc = 0x375d6750,   // Encompasses fastMalloc, fastZeroedMalloc, fastCalloc, fastRealloc.
+            AllocTypeClassNew,              // Encompasses class operator new from FastAllocBase.
+            AllocTypeClassNewArray,         // Encompasses class operator new[] from FastAllocBase.
+            AllocTypeFastNew,               // Encompasses fastNew.
+            AllocTypeFastNewArray,          // Encompasses fastNewArray.
+            AllocTypeNew,                   // Encompasses global operator new.
+            AllocTypeNewArray               // Encompasses global operator new[].
+        };
+    }
+
+#if ENABLE(FAST_MALLOC_MATCH_VALIDATION)
+
+    // Malloc validation is a scheme whereby a tag is attached to an
+    // allocation which identifies how it was originally allocated.
+    // This allows us to verify that the freeing operation matches the
+    // allocation operation. If memory is allocated with operator new[]
+    // but freed with free or delete, this system would detect that.
+    // In the implementation here, the tag is an integer prepended to
+    // the allocation memory which is assigned one of the AllocType
+    // enumeration values. An alternative implementation of this
+    // scheme could store the tag somewhere else or ignore it.
+    // Users of FastMalloc don't need to know or care how this tagging
+    // is implemented.
+
+    namespace Internal {
+
+        // Return the AllocType tag associated with the allocated block p.
+        inline AllocType fastMallocMatchValidationType(const void* p)
+        {
+            const AllocAlignmentInteger* type = static_cast<const AllocAlignmentInteger*>(p) - 1;
+            return static_cast<AllocType>(*type);
+        }
+
+        // Return the address of the AllocType tag associated with the allocated block p.
+        inline AllocAlignmentInteger* fastMallocMatchValidationValue(void* p)
+        {
+            return reinterpret_cast<AllocAlignmentInteger*>(static_cast<char*>(p) - sizeof(AllocAlignmentInteger));
+        }
+
+        // Set the AllocType tag to be associaged with the allocated block p.
+        inline void setFastMallocMatchValidationType(void* p, AllocType allocType)
+        {
+            AllocAlignmentInteger* type = static_cast<AllocAlignmentInteger*>(p) - 1;
+            *type = static_cast<AllocAlignmentInteger>(allocType);
+        }
+
+        // Handle a detected alloc/free mismatch. By default this calls CRASH().
+        void fastMallocMatchFailed(void* p);
+
+    } // namespace Internal
+
+    // This is a higher level function which is used by FastMalloc-using code.
+    inline void fastMallocMatchValidateMalloc(void* p, Internal::AllocType allocType)
+    {
+        if (!p)
+            return;
+
+        Internal::setFastMallocMatchValidationType(p, allocType);
+    }
+
+    // This is a higher level function which is used by FastMalloc-using code.
+    inline void fastMallocMatchValidateFree(void* p, Internal::AllocType allocType)
+    {
+        if (!p)
+            return;
+
+        if (Internal::fastMallocMatchValidationType(p) != allocType)
+            Internal::fastMallocMatchFailed(p);
+        Internal::setFastMallocMatchValidationType(p, Internal::AllocTypeMalloc);  // Set it to this so that fastFree thinks it's OK.
+    }
+
+#else
+
+    inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType)
+    {
+    }
+
+    inline void fastMallocMatchValidateFree(void*, Internal::AllocType)
+    {
+    }
+
+#endif
+
 } // namespace WTF
 
 using WTF::fastMalloc;
@@ -90,6 +179,13 @@ WTF_PRIVATE_INLINE void* operator new(size_t s) { return fastMalloc(s); }
 WTF_PRIVATE_INLINE void operator delete(void* p) { fastFree(p); }
 WTF_PRIVATE_INLINE void* operator new[](size_t s) { return fastMalloc(s); }
 WTF_PRIVATE_INLINE void operator delete[](void* p) { fastFree(p); }
+
+#if PLATFORM(WINCE)
+WTF_PRIVATE_INLINE void* operator new(size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); }
+WTF_PRIVATE_INLINE void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); }
+WTF_PRIVATE_INLINE void* operator new[](size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); }
+WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); }
+#endif
 #endif
 
 #endif // _CRTDBG_MAP_ALLOC
index 58869f4b67eda86b9a75fa3ec67e202301451d9a..432885f1c9f74b98e6237d8be51c27d6bb9d0c87 100644 (file)
@@ -56,4 +56,10 @@ template <> void freeOwnedGPtr<GDir>(GDir* ptr)
         g_dir_close(ptr);
 }
 
+template <> void freeOwnedGPtr<GHashTable>(GHashTable* ptr)
+{
+    if (ptr)
+        g_hash_table_unref(ptr);
+}
+
 } // namespace WTF
index bbb793abc7825c818585f9b309625d0b0ae78021..8d03ff2246266123b494105019ceb826ad1455ee 100644 (file)
@@ -35,6 +35,7 @@ namespace WTF {
     template<> void freeOwnedGPtr<GMutex>(GMutex*);
     template<> void freeOwnedGPtr<GPatternSpec>(GPatternSpec*);
     template<> void freeOwnedGPtr<GDir>(GDir*);
+    template<> void freeOwnedGPtr<GHashTable>(GHashTable*);
 
     template <typename T> class GOwnPtr : Noncopyable {
     public:
index 6fc02344eccc6343a3496b07032357e24dfbc2b6..1a422d8170ca982ca90836cf06bdf304c047f955 100644 (file)
 #define WTF_HashCountedSet_h
 
 #include "Assertions.h"
+#include "FastAllocBase.h"
 #include "HashMap.h"
 #include "Vector.h"
 
 namespace WTF {
 
     template<typename Value, typename HashFunctions = typename DefaultHash<Value>::Hash,
-        typename Traits = HashTraits<Value> > class HashCountedSet {
+        typename Traits = HashTraits<Value> > class HashCountedSet : public FastAllocBase {
     private:
         typedef HashMap<Value, unsigned, HashFunctions, Traits> ImplType;
     public:
index c5b75ffae8f7ab93bac60ed62544732d29d14d3e..3de5ee6e0cb02017a0f146a14ba9bf8f30075c16 100644 (file)
@@ -29,7 +29,7 @@ namespace WTF {
 
     template<typename KeyArg, typename MappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash,
         typename KeyTraitsArg = HashTraits<KeyArg>, typename MappedTraitsArg = HashTraits<MappedArg> >
-    class HashMap {
+    class HashMap : public FastAllocBase {
     private:
         typedef KeyTraitsArg KeyTraits;
         typedef MappedTraitsArg MappedTraits;
index da99f2cebebf24007f4f8e6ecdae406df55f8309..d664c67cf0ccaeb39f0e128e5be13f8e699f4b48 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef WTF_HashSet_h
 #define WTF_HashSet_h
 
+#include "FastAllocBase.h"
 #include "HashTable.h"
 
 namespace WTF {
@@ -32,7 +33,7 @@ namespace WTF {
     template<typename T> struct IdentityExtractor;
 
     template<typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash,
-        typename TraitsArg = HashTraits<ValueArg> > class HashSet {
+        typename TraitsArg = HashTraits<ValueArg> > class HashSet : public FastAllocBase {
     private:
         typedef HashArg HashFunctions;
         typedef TraitsArg ValueTraits;
index b3c0b7a7dc0aaeb2d386cc17cb6e9d27fc4d053e..c8d40f7d54e0f5d0ff82b082c6a607998ba26aa6 100644 (file)
@@ -21,8 +21,8 @@
 #ifndef WTF_HashTraits_h
 #define WTF_HashTraits_h
 
-#include "Assertions.h"
 #include "HashFunctions.h"
+#include "TypeTraits.h"
 #include <utility>
 #include <limits>
 
@@ -31,47 +31,6 @@ namespace WTF {
     using std::pair;
     using std::make_pair;
 
-    template<typename T> struct IsInteger           { static const bool value = false; };
-    template<> struct IsInteger<bool>               { static const bool value = true; };
-    template<> struct IsInteger<char>               { static const bool value = true; };
-    template<> struct IsInteger<signed char>        { static const bool value = true; };
-    template<> struct IsInteger<unsigned char>      { static const bool value = true; };
-    template<> struct IsInteger<short>              { static const bool value = true; };
-    template<> struct IsInteger<unsigned short>     { static const bool value = true; };
-    template<> struct IsInteger<int>                { static const bool value = true; };
-    template<> struct IsInteger<unsigned int>       { static const bool value = true; };
-    template<> struct IsInteger<long>               { static const bool value = true; };
-    template<> struct IsInteger<unsigned long>      { static const bool value = true; };
-    template<> struct IsInteger<long long>          { static const bool value = true; };
-    template<> struct IsInteger<unsigned long long> { static const bool value = true; };
-
-#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
-    template<> struct IsInteger<wchar_t>            { static const bool value = true; };
-#endif
-
-    COMPILE_ASSERT(IsInteger<bool>::value, WTF_IsInteger_bool_true);
-    COMPILE_ASSERT(IsInteger<char>::value, WTF_IsInteger_char_true);
-    COMPILE_ASSERT(IsInteger<signed char>::value, WTF_IsInteger_signed_char_true);
-    COMPILE_ASSERT(IsInteger<unsigned char>::value, WTF_IsInteger_unsigned_char_true);
-    COMPILE_ASSERT(IsInteger<short>::value, WTF_IsInteger_short_true);
-    COMPILE_ASSERT(IsInteger<unsigned short>::value, WTF_IsInteger_unsigned_short_true);
-    COMPILE_ASSERT(IsInteger<int>::value, WTF_IsInteger_int_true);
-    COMPILE_ASSERT(IsInteger<unsigned int>::value, WTF_IsInteger_unsigned_int_true);
-    COMPILE_ASSERT(IsInteger<long>::value, WTF_IsInteger_long_true);
-    COMPILE_ASSERT(IsInteger<unsigned long>::value, WTF_IsInteger_unsigned_long_true);
-    COMPILE_ASSERT(IsInteger<long long>::value, WTF_IsInteger_long_long_true);
-    COMPILE_ASSERT(IsInteger<unsigned long long>::value, WTF_IsInteger_unsigned_long_long_true);
-
-#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
-    COMPILE_ASSERT(IsInteger<wchar_t>::value, WTF_IsInteger_wchar_t_true);
-#endif
-
-    COMPILE_ASSERT(!IsInteger<char*>::value, WTF_IsInteger_char_pointer_false);
-    COMPILE_ASSERT(!IsInteger<const char* >::value, WTF_IsInteger_const_char_pointer_false);
-    COMPILE_ASSERT(!IsInteger<volatile char* >::value, WTF_IsInteger_volatile_char_pointer__false);
-    COMPILE_ASSERT(!IsInteger<double>::value, WTF_IsInteger_double_false);
-    COMPILE_ASSERT(!IsInteger<float>::value, WTF_IsInteger_float_false);
-
     template<typename T> struct HashTraits;
 
     template<bool isInteger, typename T> struct GenericHashTraitsBase;
index c7a6caa34451e3ef0aa314d76fea066acc9e1a49..e999094df21daba1b533d3c161edbef61ccc95c0 100644 (file)
 #include "MainThread.h"
 
 #include "StdLibExtras.h"
+#include "CurrentTime.h"
+#include "Deque.h"
 #include "Threading.h"
-#include "Vector.h"
 
 namespace WTF {
 
 struct FunctionWithContext {
     MainThreadFunction* function;
     void* context;
-    ThreadCondition* syncFlag;
 
-    FunctionWithContext(MainThreadFunction* function = 0, void* context = 0, ThreadCondition* syncFlag = 0)
+    FunctionWithContext(MainThreadFunction* function = 0, void* context = 0)
         : function(function)
         , context(context)
-        , syncFlag(syncFlag)
     { 
     }
 };
 
-typedef Vector<FunctionWithContext> FunctionQueue;
+typedef Deque<FunctionWithContext> FunctionQueue;
 
 static bool callbacksPaused; // This global variable is only accessed from main thread.
 
@@ -64,12 +63,14 @@ static FunctionQueue& functionQueue()
     return staticFunctionQueue;
 }
 
-#if !PLATFORM(WIN)
 void initializeMainThread()
 {
     mainThreadFunctionQueueMutex();
+    initializeMainThreadPlatform();
 }
-#endif
+
+// 0.1 sec delays in UI is approximate threshold when they become noticeable. Have a limit that's half of that.
+static const double maxRunLoopSuspensionTime = 0.05;
 
 void dispatchFunctionsFromMainThread()
 {
@@ -78,52 +79,42 @@ void dispatchFunctionsFromMainThread()
     if (callbacksPaused)
         return;
 
-    FunctionQueue queueCopy;
-    {
-        MutexLocker locker(mainThreadFunctionQueueMutex());
-        queueCopy.swap(functionQueue());
-    }
+    double startTime = currentTime();
+
+    FunctionWithContext invocation;
+    while (true) {
+        {
+            MutexLocker locker(mainThreadFunctionQueueMutex());
+            if (!functionQueue().size())
+                break;
+            invocation = functionQueue().first();
+            functionQueue().removeFirst();
+        }
 
-    for (unsigned i = 0; i < queueCopy.size(); ++i) {
-        FunctionWithContext& invocation = queueCopy[i];
         invocation.function(invocation.context);
-        if (invocation.syncFlag)
-            invocation.syncFlag->signal();
+
+        // If we are running accumulated functions for too long so UI may become unresponsive, we need to
+        // yield so the user input can be processed. Otherwise user may not be able to even close the window.
+        // This code has effect only in case the scheduleDispatchFunctionsOnMainThread() is implemented in a way that
+        // allows input events to be processed before we are back here.
+        if (currentTime() - startTime > maxRunLoopSuspensionTime) {
+            scheduleDispatchFunctionsOnMainThread();
+            break;
+        }
     }
 }
 
 void callOnMainThread(MainThreadFunction* function, void* context)
 {
     ASSERT(function);
-
+    bool needToSchedule = false;
     {
         MutexLocker locker(mainThreadFunctionQueueMutex());
+        needToSchedule = functionQueue().size() == 0;
         functionQueue().append(FunctionWithContext(function, context));
     }
-
-    scheduleDispatchFunctionsOnMainThread();
-}
-
-void callOnMainThreadAndWait(MainThreadFunction* function, void* context)
-{
-    ASSERT(function);
-
-    if (isMainThread()) {
-        function(context);
-        return;
-    }
-
-    ThreadCondition syncFlag;
-    Mutex conditionMutex;
-
-    {
-        MutexLocker locker(mainThreadFunctionQueueMutex());
-        functionQueue().append(FunctionWithContext(function, context, &syncFlag));
-        conditionMutex.lock();
-    }
-
-    scheduleDispatchFunctionsOnMainThread();
-    syncFlag.wait(conditionMutex);
+    if (needToSchedule)
+        scheduleDispatchFunctionsOnMainThread();
 }
 
 void setMainThreadCallbacksPaused(bool paused)
index 953b9867c7c38b79c4ab7bf95c6db161bfd881fd..01ce80476fde8e6816e54878b262407341fe4c96 100644 (file)
@@ -37,7 +37,6 @@ class Mutex;
 typedef void MainThreadFunction(void*);
 
 void callOnMainThread(MainThreadFunction*, void* context);
-void callOnMainThreadAndWait(MainThreadFunction*, void* context);
 
 void setMainThreadCallbacksPaused(bool paused);
 
@@ -45,9 +44,10 @@ void setMainThreadCallbacksPaused(bool paused);
 void initializeMainThread();
 
 // These functions are internal to the callOnMainThread implementation.
-void dispatchFunctionsFromMainThread();
+void initializeMainThreadPlatform();
 void scheduleDispatchFunctionsOnMainThread();
 Mutex& mainThreadFunctionQueueMutex();
+void dispatchFunctionsFromMainThread();
 
 } // namespace WTF
 
index 76488b472901407c08d897473493f7fe93f9f0fb..324300d3a14176a55f0eeac1cd3dba94dff039ce 100644 (file)
 #endif
 
 #if COMPILER(MSVC)
-#if PLATFORM(WIN_CE)
+#if PLATFORM(WINCE)
 #include <stdlib.h>
-#else
-#include <xmath.h>
 #endif
 #include <limits>
 
index 19c5c10fede9649a519bb480ba00b2212a0bc85f..7721dba512187e7c05a2ba18aa3e57e2f32cdfb8 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +30,7 @@
 #ifndef MessageQueue_h
 #define MessageQueue_h
 
+#include <limits>
 #include <wtf/Assertions.h>
 #include <wtf/Deque.h>
 #include <wtf/Noncopyable.h>
@@ -45,12 +47,14 @@ namespace WTF {
     template<typename DataType>
     class MessageQueue : Noncopyable {
     public:
-        MessageQueue() : m_killed(false) {}
+        MessageQueue() : m_killed(false) { }
         
         void append(const DataType&);
+        bool appendAndCheckEmpty(const DataType&);
         void prepend(const DataType&);
         bool waitForMessage(DataType&);
-        MessageQueueWaitResult waitForMessageTimed(DataType&, double absoluteTime);
+        template<typename Predicate>
+        MessageQueueWaitResult waitForMessageFilteredWithTimeout(DataType&, Predicate&, double absoluteTime);
         void kill();
 
         bool tryGetMessage(DataType&);
@@ -59,7 +63,11 @@ namespace WTF {
         // The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time.
         bool isEmpty();
 
+        static double infiniteTime() { return std::numeric_limits<double>::max(); }
+
     private:
+        static bool alwaysTruePredicate(DataType&) { return true; }
+
         mutable Mutex m_mutex;
         ThreadCondition m_condition;
         Deque<DataType> m_queue;
@@ -74,6 +82,17 @@ namespace WTF {
         m_condition.signal();
     }
 
+    // Returns true if the queue was empty before the item was added.
+    template<typename DataType>
+    inline bool MessageQueue<DataType>::appendAndCheckEmpty(const DataType& message)
+    {
+        MutexLocker lock(m_mutex);
+        bool wasEmpty = m_queue.isEmpty();
+        m_queue.append(message);
+        m_condition.signal();
+        return wasEmpty;
+    }
+
     template<typename DataType>
     inline void MessageQueue<DataType>::prepend(const DataType& message)
     {
@@ -85,38 +104,33 @@ namespace WTF {
     template<typename DataType>
     inline bool MessageQueue<DataType>::waitForMessage(DataType& result)
     {
-        MutexLocker lock(m_mutex);
-
-        while (!m_killed && m_queue.isEmpty())
-            m_condition.wait(m_mutex);
-
-        if (m_killed)
-            return false;
-
-        ASSERT(!m_queue.isEmpty());
-        result = m_queue.first();
-        m_queue.removeFirst();
-        return true;
+        MessageQueueWaitResult exitReason = waitForMessageFilteredWithTimeout(result, MessageQueue<DataType>::alwaysTruePredicate, infiniteTime());
+        ASSERT(exitReason == MessageQueueTerminated || exitReason == MessageQueueMessageReceived);
+        return exitReason == MessageQueueMessageReceived;
     }
 
     template<typename DataType>
-    inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageTimed(DataType& result, double absoluteTime)
+    template<typename Predicate>
+    inline MessageQueueWaitResult MessageQueue<DataType>::waitForMessageFilteredWithTimeout(DataType& result, Predicate& predicate, double absoluteTime)
     {
         MutexLocker lock(m_mutex);
         bool timedOut = false;
 
-        while (!m_killed && !timedOut && m_queue.isEmpty())
+        DequeConstIterator<DataType> found = m_queue.end();
+        while (!m_killed && !timedOut && (found = m_queue.findIf(predicate)) == m_queue.end())
             timedOut = !m_condition.timedWait(m_mutex, absoluteTime);
 
+        ASSERT(!timedOut || absoluteTime != infiniteTime());
+
         if (m_killed)
             return MessageQueueTerminated;
 
         if (timedOut)
             return MessageQueueTimeout;
 
-        ASSERT(!m_queue.isEmpty());
-        result = m_queue.first();
-        m_queue.removeFirst();
+        ASSERT(found != m_queue.end());
+        result = *found;
+        m_queue.remove(found);
         return MessageQueueMessageReceived;
     }
 
@@ -157,7 +171,7 @@ namespace WTF {
         MutexLocker lock(m_mutex);
         return m_killed;
     }
-}
+} // namespace WTF
 
 using WTF::MessageQueue;
 // MessageQueueWaitResult enum and all its values.
index f0bb8665457e9759eef920e73bc4a72964e65c8a..4263bcecabed4fff4dc6b4987425dd34e4d9285f 100644 (file)
@@ -32,4 +32,6 @@ namespace WTF {
 
 } // namespace WTF
 
+using WTF::notFound;
+
 #endif // NotFound_h
diff --git a/wtf/OwnFastMallocPtr.h b/wtf/OwnFastMallocPtr.h
new file mode 100644 (file)
index 0000000..5c0d064
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *  Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef OwnFastMallocPtr_h
+#define OwnFastMallocPtr_h
+
+#include "FastMalloc.h"
+#include "Noncopyable.h"
+
+namespace WTF {
+
+    template<class T> class OwnFastMallocPtr : Noncopyable {
+    public:
+        explicit OwnFastMallocPtr(T* ptr) : m_ptr(ptr)
+        {
+        }
+
+        ~OwnFastMallocPtr()
+        {
+            fastFree(m_ptr);
+        }
+
+        T* get() const { return m_ptr; }
+        T* release() { T* ptr = m_ptr; m_ptr = 0; return ptr; }
+
+    private:
+        T* m_ptr;
+    };
+
+} // namespace WTF
+
+using WTF::OwnFastMallocPtr;
+
+#endif // OwnFastMallocPtr_h
index 256b55c5a64af3936331d66cfd5a97a5544b8d28..9e4bd32ae82a47e79a81724207a15af7891ddcfd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *  Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 #ifndef WTF_OwnPtr_h
 #define WTF_OwnPtr_h
 
+#include "Assertions.h"
+#include "Noncopyable.h"
+#include "OwnPtrCommon.h"
+#include "TypeTraits.h"
 #include <algorithm>
 #include <memory>
-#include <wtf/Assertions.h>
-#include <wtf/Noncopyable.h>
-
-#if PLATFORM(WIN)
-
-typedef struct HBITMAP__* HBITMAP;
-typedef struct HBRUSH__* HBRUSH;
-typedef struct HFONT__* HFONT;
-typedef struct HPALETTE__* HPALETTE;
-typedef struct HPEN__* HPEN;
-typedef struct HRGN__* HRGN;
-
-#endif
 
 namespace WTF {
 
     // Unlike most of our smart pointers, OwnPtr can take either the pointer type or the pointed-to type.
 
-    // FIXME: Share a single RemovePointer class template with RetainPtr.
-    template <typename T> struct OwnPtrRemovePointer { typedef T type; };
-    template <typename T> struct OwnPtrRemovePointer<T*> { typedef T type; };
-
-    template <typename T> inline void deleteOwnedPtr(T* ptr)
-    {
-        typedef char known[sizeof(T) ? 1 : -1];
-        if (sizeof(known))
-            delete ptr;
-    }
-
-#if PLATFORM(WIN)
-    void deleteOwnedPtr(HBITMAP);
-    void deleteOwnedPtr(HBRUSH);
-    void deleteOwnedPtr(HFONT);
-    void deleteOwnedPtr(HPALETTE);
-    void deleteOwnedPtr(HPEN);
-    void deleteOwnedPtr(HRGN);
-#endif
+    template <typename T> class PassOwnPtr;
 
     template <typename T> class OwnPtr : Noncopyable {
     public:
-        typedef typename OwnPtrRemovePointer<T>::type ValueType;
+        typedef typename RemovePointer<T>::Type ValueType;
         typedef ValueType* PtrType;
 
         explicit OwnPtr(PtrType ptr = 0) : m_ptr(ptr) { }
         OwnPtr(std::auto_ptr<ValueType> autoPtr) : m_ptr(autoPtr.release()) { }
+        // See comment in PassOwnPtr.h for why this takes a const reference.
+        template <typename U> OwnPtr(const PassOwnPtr<U>& o);
+
+        // This copy constructor is used implicitly by gcc when it generates
+        // transients for assigning a PassOwnPtr<T> object to a stack-allocated
+        // OwnPtr<T> object.  It should never be called explicitly and gcc
+        // should optimize away the constructor when generating code.
+        OwnPtr(const OwnPtr<ValueType>& o);
+
         ~OwnPtr() { deleteOwnedPtr(m_ptr); }
 
         PtrType get() const { return m_ptr; }
@@ -89,19 +71,50 @@ namespace WTF {
         typedef PtrType OwnPtr::*UnspecifiedBoolType;
         operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; }
 
+        OwnPtr& operator=(const PassOwnPtr<T>&);
+        template <typename U> OwnPtr& operator=(const PassOwnPtr<U>&);
+
         void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
 
     private:
         PtrType m_ptr;
     };
-    
-    template <typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b) { a.swap(b); }
+
+    template <typename T> template <typename U> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o)
+        : m_ptr(o.release())
+    {
+    }
+
+    template <typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o)
+    {
+        T* ptr = m_ptr;
+        m_ptr = o.release();
+        ASSERT(!ptr || m_ptr != ptr);
+        if (ptr)
+            deleteOwnedPtr(ptr);
+        return *this;
+    }
+
+    template <typename T> template <typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>& o)
+    {
+        T* ptr = m_ptr;
+        m_ptr = o.release();
+        ASSERT(!ptr || m_ptr != ptr);
+        if (ptr)
+            deleteOwnedPtr(ptr);
+        return *this;
+    }
+
+    template <typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b)
+    {
+        a.swap(b);
+    }
 
     template <typename T, typename U> inline bool operator==(const OwnPtr<T>& a, U* b)
-    { 
+    {
         return a.get() == b; 
     }
-    
+
     template <typename T, typename U> inline bool operator==(T* a, const OwnPtr<U>& b) 
     {
         return a == b.get(); 
@@ -113,10 +126,10 @@ namespace WTF {
     }
 
     template <typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U>& b)
-    { 
+    {
         return a != b.get(); 
     }
-    
+
     template <typename T> inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<T>& p)
     {
         return p.get();
diff --git a/wtf/OwnPtrCommon.h b/wtf/OwnPtrCommon.h
new file mode 100644 (file)
index 0000000..6d91a54
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef WTF_OwnPtrCommon_h
+#define WTF_OwnPtrCommon_h
+
+#if PLATFORM(WIN)
+typedef struct HBITMAP__* HBITMAP;
+typedef struct HBRUSH__* HBRUSH;
+typedef struct HDC__* HDC;
+typedef struct HFONT__* HFONT;
+typedef struct HPALETTE__* HPALETTE;
+typedef struct HPEN__* HPEN;
+typedef struct HRGN__* HRGN;
+#endif
+
+namespace WTF {
+
+    template <typename T> inline void deleteOwnedPtr(T* ptr)
+    {
+        typedef char known[sizeof(T) ? 1 : -1];
+        if (sizeof(known))
+            delete ptr;
+    }
+
+#if PLATFORM(WIN)
+    void deleteOwnedPtr(HBITMAP);
+    void deleteOwnedPtr(HBRUSH);
+    void deleteOwnedPtr(HDC);
+    void deleteOwnedPtr(HFONT);
+    void deleteOwnedPtr(HPALETTE);
+    void deleteOwnedPtr(HPEN);
+    void deleteOwnedPtr(HRGN);
+#endif
+
+} // namespace WTF
+
+#endif // WTF_OwnPtrCommon_h
index b08d7dc292b226a6fb6d462c6aef0899bb9fc509..67a32ff77f5640375bf3ee916dcd9faefdb5fa80 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Torch Mobile, Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,6 +43,12 @@ void deleteOwnedPtr(HBRUSH ptr)
         DeleteObject(ptr);
 }
 
+void deleteOwnedPtr(HDC ptr)
+{
+    if (ptr)
+        DeleteDC(ptr);
+}
+
 void deleteOwnedPtr(HFONT ptr)
 {
     if (ptr)
diff --git a/wtf/PassOwnPtr.h b/wtf/PassOwnPtr.h
new file mode 100644 (file)
index 0000000..ae70457
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef WTF_PassOwnPtr_h
+#define WTF_PassOwnPtr_h
+
+#include "Assertions.h"
+#include "OwnPtrCommon.h"
+#include "TypeTraits.h"
+
+namespace WTF {
+
+    // Unlike most of our smart pointers, PassOwnPtr can take either the pointer type or the pointed-to type.
+
+    template <typename T> class OwnPtr;
+
+    template <typename T> class PassOwnPtr {
+    public:
+        typedef typename RemovePointer<T>::Type ValueType;
+        typedef ValueType* PtrType;
+
+        PassOwnPtr(PtrType ptr = 0) : m_ptr(ptr) { }
+        // It somewhat breaks the type system to allow transfer of ownership out of
+        // a const PassOwnPtr. However, it makes it much easier to work with PassOwnPtr
+        // temporaries, and we don't really have a need to use real const PassOwnPtrs 
+        // anyway.
+        PassOwnPtr(const PassOwnPtr& o) : m_ptr(o.release()) { }
+        template <typename U> PassOwnPtr(const PassOwnPtr<U>& o) : m_ptr(o.release()) { }
+
+        ~PassOwnPtr() { deleteOwnedPtr(m_ptr); }
+
+        PtrType get() const { return m_ptr; }
+
+        void clear() { m_ptr = 0; }
+        PtrType release() const { PtrType ptr = m_ptr; m_ptr = 0; return ptr; }
+
+        ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
+        PtrType operator->() const { ASSERT(m_ptr); return m_ptr; }
+
+        bool operator!() const { return !m_ptr; }
+
+        // This conversion operator allows implicit conversion to bool but not to other integer types.
+        typedef PtrType PassOwnPtr::*UnspecifiedBoolType;
+        operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnPtr::m_ptr : 0; }
+
+        PassOwnPtr& operator=(T*);
+        PassOwnPtr& operator=(const PassOwnPtr<T>&);
+        template <typename U> PassOwnPtr& operator=(const PassOwnPtr<U>&);
+
+    private:
+        mutable PtrType m_ptr;
+    };
+
+    template <typename T> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(T* optr)
+    {
+        T* ptr = m_ptr;
+        m_ptr = optr;
+        ASSERT(!ptr || m_ptr != ptr);
+        if (ptr)
+            deleteOwnedPtr(ptr);
+        return *this;
+    }
+
+    template <typename T> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(const PassOwnPtr<T>& optr)
+    {
+        T* ptr = m_ptr;
+        m_ptr = optr.release();
+        ASSERT(!ptr || m_ptr != ptr);
+        if (ptr)
+            deleteOwnedPtr(ptr);
+        return *this;
+    }
+
+    template <typename T> template <typename U> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(const PassOwnPtr<U>& optr)
+    {
+        T* ptr = m_ptr;
+        m_ptr = optr.release();
+        ASSERT(!ptr || m_ptr != ptr);
+        if (ptr)
+            deleteOwnedPtr(ptr);
+        return *this;
+    }
+
+    template <typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, const PassOwnPtr<U>& b) 
+    {
+        return a.get() == b.get(); 
+    }
+
+    template <typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, const OwnPtr<U>& b) 
+    {
+        return a.get() == b.get(); 
+    }
+    
+    template <typename T, typename U> inline bool operator==(const OwnPtr<T>& a, const PassOwnPtr<U>& b) 
+    {
+        return a.get() == b.get(); 
+    }
+    
+    template <typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, U* b) 
+    {
+        return a.get() == b; 
+    }
+    
+    template <typename T, typename U> inline bool operator==(T* a, const PassOwnPtr<U>& b) 
+    {
+        return a == b.get(); 
+    }
+    
+    template <typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, const PassOwnPtr<U>& b) 
+    {
+        return a.get() != b.get(); 
+    }
+    
+    template <typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, const OwnPtr<U>& b) 
+    {
+        return a.get() != b.get(); 
+    }
+    
+    template <typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, const PassOwnPtr<U>& b) 
+    {
+        return a.get() != b.get(); 
+    }
+    
+    template <typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, U* b)
+    {
+        return a.get() != b; 
+    }
+    
+    template <typename T, typename U> inline bool operator!=(T* a, const PassOwnPtr<U>& b) 
+    {
+        return a != b.get(); 
+    }
+
+    template <typename T, typename U> inline PassOwnPtr<T> static_pointer_cast(const PassOwnPtr<U>& p) 
+    {
+        return PassOwnPtr<T>(static_cast<T*>(p.release())); 
+    }
+
+    template <typename T, typename U> inline PassOwnPtr<T> const_pointer_cast(const PassOwnPtr<U>& p) 
+    {
+        return PassOwnPtr<T>(const_cast<T*>(p.release())); 
+    }
+
+    template <typename T> inline T* getPtr(const PassOwnPtr<T>& p)
+    {
+        return p.get();
+    }
+
+} // namespace WTF
+
+using WTF::PassOwnPtr;
+using WTF::const_pointer_cast;
+using WTF::static_pointer_cast;
+
+#endif // WTF_PassOwnPtr_h
index c1dc309f4d79c436042817c928ff09c15e834943..d80ed629133320a6576fa05b15e916cce189acf2 100644 (file)
@@ -40,7 +40,7 @@ namespace WTF {
         PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {}
         template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { }
 
-        ALWAYS_INLINE ~PassRefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
+        ALWAYS_INLINE ~PassRefPtr() { if (UNLIKELY(m_ptr != 0)) m_ptr->deref(); }
         
         template <class U> 
         PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
index 12f4ec0f2842a44769b19cffb9d12dd13fb36ce3..e4d41fe8c4688408004b1756257cab169544b439 100644 (file)
 /* be used regardless of operating environment */
 #ifdef __APPLE__
 #define WTF_PLATFORM_DARWIN 1
+#include <AvailabilityMacros.h>
+#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+#define BUILDING_ON_TIGER 1
+#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
+#define BUILDING_ON_LEOPARD 1
+#endif
+#include <Availability.h>
 #include <TargetConditionals.h>
 #endif
 
 #define WTF_PLATFORM_WIN_OS 1
 #endif
 
-/* PLATFORM(WIN_CE) */
+/* PLATFORM(WINCE) */
 /* Operating system level dependencies for Windows CE that should be used */
 /* regardless of operating environment */
 /* Note that for this platform PLATFORM(WIN_OS) is also defined. */
 #if defined(_WIN32_WCE)
-#define WTF_PLATFORM_WIN_CE 1
+#define WTF_PLATFORM_WINCE 1
+#endif
+
+/* PLATFORM(LINUX) */
+/* Operating system level dependencies for Linux-like systems that */
+/* should be used regardless of operating environment */
+#ifdef __linux__
+#define WTF_PLATFORM_LINUX 1
 #endif
 
 /* PLATFORM(FREEBSD) */
 #endif
 
 /* PLATFORM(IPHONE) */
-#if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+#if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
 #define WTF_PLATFORM_IPHONE 1
 #endif
 
 /* PLATFORM(IPHONE_SIMULATOR) */
-#if TARGET_IPHONE_SIMULATOR
+#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
 #define WTF_PLATFORM_IPHONE 1
 #define WTF_PLATFORM_IPHONE_SIMULATOR 1
 #else
 #if !defined(__ARM_EABI__)
 #define WTF_PLATFORM_FORCE_PACK 1
 #endif
+#define ARM_ARCH_VERSION 3
+#if defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
+#undef ARM_ARCH_VERSION
+#define ARM_ARCH_VERSION 4
+#endif
+#if defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
+        || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
+        || defined(__ARM_ARCH_5TEJ__)
+#undef ARM_ARCH_VERSION
+#define ARM_ARCH_VERSION 5
 #endif
+#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+     || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
+     || defined(__ARM_ARCH_6ZK__)
+#undef ARM_ARCH_VERSION
+#define ARM_ARCH_VERSION 6
+#endif
+#if defined(__ARM_ARCH_7A__)
+#undef ARM_ARCH_VERSION
+#define ARM_ARCH_VERSION 7
+#endif
+#endif /* ARM */
+#define PLATFORM_ARM_ARCH(N) (PLATFORM(ARM) && ARM_ARCH_VERSION >= N)
 
 /* PLATFORM(X86) */
 #if   defined(__i386__) \
 
 /* PLATFORM(X86_64) */
 #if   defined(__x86_64__) \
-   || defined(__ia64__) \
    || defined(_M_X64)
 #define WTF_PLATFORM_X86_64 1
 #endif
 
+/* PLATFORM(SH4) */
+#if defined(__SH4__)
+#define WTF_PLATFORM_SH4 1
+#endif
+
 /* PLATFORM(SPARC64) */
 #if defined(__sparc64__)
 #define WTF_PLATFORM_SPARC64 1
 #define WTF_PLATFORM_BIG_ENDIAN 1
 #endif
 
-/* PLATFORM(WIN_CE) && PLATFORM(QT)
+/* PLATFORM(WINCE) && PLATFORM(QT)
    We can not determine the endianess at compile time. For
    Qt for Windows CE the endianess is specified in the
    device specific makespec
 */
-#if PLATFORM(WIN_CE) && PLATFORM(QT)
+#if PLATFORM(WINCE) && PLATFORM(QT)
 #   include <QtGlobal>
 #   undef WTF_PLATFORM_BIG_ENDIAN
 #   undef WTF_PLATFORM_MIDDLE_ENDIAN
 #endif
 #endif
 
+/* COMPILER(RVCT) */
+#if defined(__CC_ARM) || defined(__ARMCC__)
+#define WTF_COMPILER_RVCT 1
+#endif
+
 /* COMPILER(GCC) */
-#if defined(__GNUC__)
+/* --gnu option of the RVCT compiler also defines __GNUC__ */
+#if defined(__GNUC__) && !COMPILER(RVCT)
 #define WTF_COMPILER_GCC 1
 #endif
 
 #define WTF_COMPILER_CYGWIN 1
 #endif
 
-/* COMPILER(RVCT) */
-#if defined(__CC_ARM) || defined(__ARMCC__)
-#define WTF_COMPILER_RVCT 1
-#endif
-
 /* COMPILER(WINSCW) */
 #if defined(__WINSCW__)
 #define WTF_COMPILER_WINSCW 1
 #define WTF_USE_PTHREADS 1
 #endif
 
-#define WTF_PLATFORM_CF 1
-#define WTF_USE_PTHREADS 1
+#define DONT_FINALIZE_ON_MAIN_THREAD 1
+#define ENABLE_CONTEXT_MENUS 0
+#define ENABLE_DRAG_SUPPORT 0
 #define ENABLE_FTPDIR 1
+#define ENABLE_GEOLOCATION 1
+#define ENABLE_ICONDATABASE 0
+#define ENABLE_INSPECTOR 0
 #define ENABLE_JIT 0
 #define ENABLE_MAC_JAVA_BRIDGE 0
-#define ENABLE_ICONDATABASE 0
-#define ENABLE_TOUCH_EVENTS 1
-#define ENABLE_IPHONE_PPT 1
-#define ENABLE_GEOLOCATION 1
 #define ENABLE_NETSCAPE_PLUGIN_API 0
-#define HAVE_READLINE 1
-#define DONT_FINALIZE_ON_MAIN_THREAD 1
-#define HAVE_MADV_FREE 1
+#define ENABLE_ORIENTATION_EVENTS 1
 #define ENABLE_REPAINT_THROTTLING 1
 #define ENABLE_RESPECT_EXIF_ORIENTATION 1
+#define HAVE_READLINE 1
+#define HAVE_RUNLOOP_TIMER 0
+#define WTF_PLATFORM_CF 1
+#define WTF_USE_PTHREADS 1
 
 #if PLATFORM(WIN)
 #define WTF_USE_WININET 1
 #endif
 
 #if PLATFORM(WX)
+#define ENABLE_ASSEMBLER 1
 #define WTF_USE_CURL 1
 #define WTF_USE_PTHREADS 1
 #endif
 #define HAVE_ACCESSIBILITY 1
 #endif /* !defined(HAVE_ACCESSIBILITY) */
 
-#if COMPILER(GCC)
-#define HAVE_COMPUTED_GOTO 1
+#if PLATFORM(UNIX) && !PLATFORM(SYMBIAN)
+#define HAVE_SIGNAL_H 1
 #endif
 
 #if PLATFORM(DARWIN)
 
 #define HAVE_ERRNO_H 1
+#define HAVE_LANGINFO_H 1
 #define HAVE_MMAP 1
 #define HAVE_MERGESORT 1
 #define HAVE_SBRK 1
 #define HAVE_SYS_TIME_H 1
 #define HAVE_SYS_TIMEB_H 1
 
+
+#define HAVE_MADV_FREE 1
+
 #elif PLATFORM(WIN_OS)
 
 #define HAVE_FLOAT_H 1
-#if PLATFORM(WIN_CE)
+#if PLATFORM(WINCE)
 #define HAVE_ERRNO_H 0
 #else
 #define HAVE_SYS_TIMEB_H 1
 /* FIXME: is this actually used or do other platforms generate their own config.h? */
 
 #define HAVE_ERRNO_H 1
+#define HAVE_LANGINFO_H 1
 #define HAVE_MMAP 1
 #define HAVE_SBRK 1
 #define HAVE_STRINGS_H 1
 
 /* ENABLE macro defaults */
 
+/* fastMalloc match validation allows for runtime verification that
+   new is matched by delete, fastMalloc is matched by fastFree, etc. */
+#if !defined(ENABLE_FAST_MALLOC_MATCH_VALIDATION)
+#define ENABLE_FAST_MALLOC_MATCH_VALIDATION 0
+#endif
+
 #if !defined(ENABLE_ICONDATABASE)
 #define ENABLE_ICONDATABASE 1
 #endif
 #define ENABLE_DASHBOARD_SUPPORT 0
 #endif
 
+#if !defined(ENABLE_CONTEXT_MENUS)
+#define ENABLE_CONTEXT_MENUS 1
+#endif
+
+#if !defined(ENABLE_DRAG_SUPPORT)
+#define ENABLE_DRAG_SUPPORT 1
+#endif
+
+#if !defined(ENABLE_INSPECTOR)
+#define ENABLE_INSPECTOR 1
+#endif
+
 #if !defined(ENABLE_MAC_JAVA_BRIDGE)
 #define ENABLE_MAC_JAVA_BRIDGE 0
 #endif
 #define ENABLE_NETSCAPE_PLUGIN_API 1
 #endif
 
-#if !defined(ENABLE_RESPECT_EXIF_ORIENTATION)
-#define ENABLE_RESPECT_EXIF_ORIENTATION 0
+#if !defined(WTF_USE_PLUGIN_HOST_PROCESS)
+#define WTF_USE_PLUGIN_HOST_PROCESS 0
 #endif
 
-#if !defined(ENABLE_TOUCH_EVENTS)
-#define ENABLE_TOUCH_EVENTS 0
+#if !defined(ENABLE_ORIENTATION_EVENTS)
+#define ENABLE_ORIENTATION_EVENTS 0
 #endif
 
-#if !defined(ENABLE_IPHONE_PPT)
-#define ENABLE_IPHONE_PPT 0
+#if !defined(ENABLE_RESPECT_EXIF_ORIENTATION)
+#define ENABLE_RESPECT_EXIF_ORIENTATION 0
 #endif
 
 #if !defined(ENABLE_OPCODE_STATS)
 #define ENABLE_OPCODE_STATS 0
 #endif
 
-#if !defined(ENABLE_CODEBLOCK_SAMPLING)
+#define ENABLE_SAMPLING_COUNTERS 0
+#define ENABLE_SAMPLING_FLAGS 0
+#define ENABLE_OPCODE_SAMPLING 0
 #define ENABLE_CODEBLOCK_SAMPLING 0
+#if ENABLE(CODEBLOCK_SAMPLING) && !ENABLE(OPCODE_SAMPLING)
+#error "CODEBLOCK_SAMPLING requires OPCODE_SAMPLING"
 #endif
-
-#if ENABLE(CODEBLOCK_SAMPLING) && !defined(ENABLE_OPCODE_SAMPLING)
-#define ENABLE_OPCODE_SAMPLING 1
-#endif
-
-#if !defined(ENABLE_OPCODE_SAMPLING)
-#define ENABLE_OPCODE_SAMPLING 0
+#if ENABLE(OPCODE_SAMPLING) || ENABLE(SAMPLING_FLAGS)
+#define ENABLE_SAMPLING_THREAD 1
 #endif
 
 #if !defined(ENABLE_GEOLOCATION)
 #define ENABLE_TEXT_CARET 1
 #endif
 
-#if !defined(WTF_USE_ALTERNATE_JSIMMEDIATE) && PLATFORM(X86_64) && PLATFORM(MAC)
-#define WTF_USE_ALTERNATE_JSIMMEDIATE 1
+#if !defined(ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL)
+#define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0
+#endif
+
+#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64)
+#if PLATFORM(X86_64) && PLATFORM(MAC)
+#define WTF_USE_JSVALUE64 1
+#elif PLATFORM(PPC64) || PLATFORM(QT) || (PLATFORM(IPHONE) && PLATFORM_ARM_ARCH(6) && !defined(__llvm__))
+// FIXME: <rdar://problem/7478149> gcc-4.2 compiler bug with USE(JSVALUE32_64) and armv6 target
+#define WTF_USE_JSVALUE32 1
+#else
+#define WTF_USE_JSVALUE32_64 1
 #endif
+#endif // !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64)
 
 #if !defined(ENABLE_REPAINT_THROTTLING)
 #define ENABLE_REPAINT_THROTTLING 0
 #endif
 
 #if !defined(ENABLE_JIT)
-/* x86-64 support is under development. */
+/* The JIT is tested & working on x86_64 Mac */
 #if PLATFORM(X86_64) && PLATFORM(MAC)
-    #define ENABLE_JIT 0
-    #define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
+    #define ENABLE_JIT 1
 /* The JIT is tested & working on x86 Mac */
 #elif PLATFORM(X86) && PLATFORM(MAC)
     #define ENABLE_JIT 1
     #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
+#elif PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE)
+    /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */
+    #define ENABLE_JIT 0
+    #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0
 /* The JIT is tested & working on x86 Windows */
 #elif PLATFORM(X86) && PLATFORM(WIN)
     #define ENABLE_JIT 1
-    #define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
 #endif
-    #define ENABLE_JIT_OPTIMIZE_CALL 1
-    #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1
-    #define ENABLE_JIT_OPTIMIZE_ARITHMETIC 1
 #endif
 
 #if ENABLE(JIT)
-#if !(USE(JIT_STUB_ARGUMENT_VA_LIST) || USE(JIT_STUB_ARGUMENT_REGISTER) || USE(JIT_STUB_ARGUMENT_STACK))
-#error Please define one of the JIT_STUB_ARGUMENT settings.
-#elif (USE(JIT_STUB_ARGUMENT_VA_LIST) && USE(JIT_STUB_ARGUMENT_REGISTER)) \
-   || (USE(JIT_STUB_ARGUMENT_VA_LIST) && USE(JIT_STUB_ARGUMENT_STACK)) \
-   || (USE(JIT_STUB_ARGUMENT_REGISTER) && USE(JIT_STUB_ARGUMENT_STACK))
-#error Please do not define more than one of the JIT_STUB_ARGUMENT settings.
+#ifndef ENABLE_JIT_OPTIMIZE_CALL
+#define ENABLE_JIT_OPTIMIZE_CALL 1
+#endif
+#ifndef ENABLE_JIT_OPTIMIZE_NATIVE_CALL
+#define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 1
+#endif
+#ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS
+#define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1
+#endif
+#ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS
+#define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1
+#endif
+#endif
+
+#if PLATFORM(X86) && COMPILER(MSVC)
+#define JSC_HOST_CALL __fastcall
+#elif PLATFORM(X86) && COMPILER(GCC)
+#define JSC_HOST_CALL __attribute__ ((fastcall))
+#else
+#define JSC_HOST_CALL
+#endif
+
+#if COMPILER(GCC) && !ENABLE(JIT)
+#define HAVE_COMPUTED_GOTO 1
 #endif
+
+#if ENABLE(JIT) && defined(COVERAGE)
+    #define WTF_USE_INTERPRETER 0
+#else
+    #define WTF_USE_INTERPRETER 1
 #endif
 
-/* WREC supports x86 & x86-64, and has been tested on Mac and Windows ('cept on 64-bit on Mac). */
-#if (!defined(ENABLE_WREC) && PLATFORM(X86) && PLATFORM(MAC)) \
- || (!defined(ENABLE_WREC) && PLATFORM(X86_64) && PLATFORM(MAC)) \
- || (!defined(ENABLE_WREC) && PLATFORM(X86) && PLATFORM(WIN))
-#define ENABLE_WREC 1
+/* Yet Another Regex Runtime. */
+/* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */
+#if (!defined(ENABLE_YARR_JIT) && PLATFORM(X86) && PLATFORM(MAC)) \
+ || (!defined(ENABLE_YARR_JIT) && PLATFORM(X86_64) && PLATFORM(MAC)) \
+ /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */ \
+ || (!defined(ENABLE_YARR_JIT) && PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE) && 0) \
+ || (!defined(ENABLE_YARR_JIT) && PLATFORM(X86) && PLATFORM(WIN))
+#define ENABLE_YARR 1
+#define ENABLE_YARR_JIT 1
+#endif
+/* Sanity Check */
+#if ENABLE(YARR_JIT) && !ENABLE(YARR)
+#error "YARR_JIT requires YARR"
 #endif
 
-#if ENABLE(JIT) || ENABLE(WREC)
+#if ENABLE(JIT) || ENABLE(YARR_JIT)
 #define ENABLE_ASSEMBLER 1
 #endif
+/* Setting this flag prevents the assembler from using RWX memory; this may improve
+   security but currectly comes at a significant performance cost. */
+#if PLATFORM_ARM_ARCH(7) && PLATFORM(IPHONE)
+#define ENABLE_ASSEMBLER_WX_EXCLUSIVE 1
+#else
+#define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0
+#endif
 
 #if !defined(ENABLE_PAN_SCROLLING) && PLATFORM(WIN_OS)
 #define ENABLE_PAN_SCROLLING 1
 #define WTF_USE_FONT_FAST_PATH 1
 #endif
 
+/* Accelerated compositing */
+#if PLATFORM(MAC)
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+#define WTF_USE_ACCELERATED_COMPOSITING 1
+#endif
+#endif
+
+#define WTF_USE_ACCELERATED_COMPOSITING 1
+
 #endif /* WTF_Platform_h */
index 477e893d60eeba3736308999e1de17ad33a1a3f2..f4527df7411bf09fd2a80046a506cfa6d80a66f8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Google Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -42,9 +42,20 @@ namespace WTF {
         void setFlag(FlagEnum flagNumber) { ASSERT(flagNumber < 2); m_ptrAndFlags |= (1 << flagNumber);}
         void clearFlag(FlagEnum flagNumber) { ASSERT(flagNumber < 2); m_ptrAndFlags &= ~(1 << flagNumber);}
         T* get() const { return reinterpret_cast<T*>(m_ptrAndFlags & ~3); }
-        void set(T* ptr) { ASSERT(!(reinterpret_cast<intptr_t>(ptr) & 3)); m_ptrAndFlags = reinterpret_cast<intptr_t>(ptr) | (m_ptrAndFlags & 3);}
+        void set(T* ptr)
+        {
+            ASSERT(!(reinterpret_cast<intptr_t>(ptr) & 3));
+            m_ptrAndFlags = reinterpret_cast<intptr_t>(ptr) | (m_ptrAndFlags & 3);
+#ifndef NDEBUG
+            m_leaksPtr = ptr;
+#endif
+        }
+
     private:
         intptr_t m_ptrAndFlags;
+#ifndef NDEBUG
+        void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced.
+#endif
     };
 } // namespace WTF
 
index ac8e167bf7488b808e6a06b0de6337ad4d9dd37e..c174145dceebff3cc11bc91bb8096abc6cebb803 100644 (file)
@@ -49,15 +49,17 @@ public:
     }
 
 protected:
-    RefCountedBase(int initialRefCount)
-        : m_refCount(initialRefCount)
+    RefCountedBase()
+        : m_refCount(1)
 #ifndef NDEBUG
         , m_deletionHasBegun(false)
 #endif
     {
     }
 
-    ~RefCountedBase() {}
+    ~RefCountedBase()
+    {
+    }
 
     // Returns whether the pointer should be freed or not.
     bool derefBase()
@@ -75,7 +77,23 @@ protected:
         return false;
     }
 
-protected:
+    // Helper for generating JIT code. Please do not use for non-JIT purposes.
+    int* addressOfCount()
+    {
+        return &m_refCount;
+    }
+
+#ifndef NDEBUG
+    bool deletionHasBegun() const
+    {
+        return m_deletionHasBegun;
+    }
+#endif
+
+private:
+    template<class T>
+    friend class CrossThreadRefCounted;
+
     int m_refCount;
 #ifndef NDEBUG
     bool m_deletionHasBegun;
@@ -85,11 +103,6 @@ protected:
 
 template<class T> class RefCounted : public RefCountedBase {
 public:
-    RefCounted(int initialRefCount = 1)
-        : RefCountedBase(initialRefCount)
-    {
-    }
-
     void deref()
     {
         if (derefBase())
@@ -97,7 +110,9 @@ public:
     }
 
 protected:
-    ~RefCounted() {}
+    ~RefCounted()
+    {
+    }
 };
 
 } // namespace WTF
index 929e745b51c5254233fd1fef5a97800f047108ab..74cd0ead4b6d6966e71c0de7402fdb73e6041319 100644 (file)
@@ -23,6 +23,7 @@
 
 #include <algorithm>
 #include "AlwaysInline.h"
+#include "FastAllocBase.h"
 
 namespace WTF {
 
@@ -32,7 +33,7 @@ namespace WTF {
 
     enum HashTableDeletedValueType { HashTableDeletedValue };
 
-    template <typename T> class RefPtr {
+    template <typename T> class RefPtr : public FastAllocBase {
     public:
         RefPtr() : m_ptr(0) { }
         RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
index a66a12748a03b87ef6bb22807258dce2819c34f1..77f25e05f921556bea30f180a9eb5b6eccaa7a4c 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef RetainPtr_h
 #define RetainPtr_h
 
+#include "TypeTraits.h"
 #include <algorithm>
 #include <CoreFoundation/CoreFoundation.h>
 
 
 namespace WTF {
 
-    template <typename T> struct RemovePointer {
-        typedef T type;
-    };
-
-    template <typename T> struct RemovePointer<T*> {
-        typedef T type;
-    };
-
     // Unlike most most of our smart pointers, RetainPtr can take either the pointer type or the pointed-to type,
     // so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work.
 
@@ -56,7 +49,7 @@ namespace WTF {
 
     template <typename T> class RetainPtr {
     public:
-        typedef typename RemovePointer<T>::type ValueType;
+        typedef typename RemovePointer<T>::Type ValueType;
         typedef ValueType* PtrType;
 
         RetainPtr() : m_ptr(0) {}
diff --git a/wtf/SegmentedVector.h b/wtf/SegmentedVector.h
new file mode 100644 (file)
index 0000000..065c19c
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SegmentedVector_h
+#define SegmentedVector_h
+
+#include <wtf/Vector.h>
+
+namespace WTF {
+
+    // An iterator for SegmentedVector. It supports only the pre ++ operator
+    template <typename T, size_t SegmentSize> class SegmentedVector;
+    template <typename T, size_t SegmentSize> class SegmentedVectorIterator {
+    private:
+        friend class SegmentedVector<T, SegmentSize>;
+    public:
+        typedef SegmentedVectorIterator<T, SegmentSize> Iterator;
+
+        ~SegmentedVectorIterator() { }
+
+        T& operator*() const { return m_vector.m_segments.at(m_segment)->at(m_index); }
+        T* operator->() const { return &m_vector.m_segments.at(m_segment)->at(m_index); }
+
+        // Only prefix ++ operator supported
+        Iterator& operator++()
+        {
+            ASSERT(m_index != SegmentSize);
+            ++m_index;
+            if (m_index >= m_vector.m_segments.at(m_segment)->size())  {
+                if (m_segment + 1 < m_vector.m_segments.size()) {
+                    ASSERT(m_vector.m_segments.at(m_segment)->size() > 0);
+                    ++m_segment;
+                    m_index = 0;
+                } else {
+                    // Points to the "end" symbol
+                    m_segment = 0;
+                    m_index = SegmentSize;
+                }
+            }
+            return *this;
+        }
+
+        bool operator==(const Iterator& other) const
+        {
+            return (m_index == other.m_index && m_segment = other.m_segment && &m_vector == &other.m_vector);
+        }
+
+        bool operator!=(const Iterator& other) const
+        {
+            return (m_index != other.m_index || m_segment != other.m_segment || &m_vector != &other.m_vector);
+        }
+
+        SegmentedVectorIterator& operator=(const SegmentedVectorIterator<T, SegmentSize>& other)
+        {
+            m_vector = other.m_vector;
+            m_segment = other.m_segment;
+            m_index = other.m_index;
+            return *this;
+        }
+
+    private:
+        SegmentedVectorIterator(SegmentedVector<T, SegmentSize>& vector, size_t segment, size_t index)
+            : m_vector(vector)
+            , m_segment(segment)
+            , m_index(index)
+        {
+        }
+
+        SegmentedVector<T, SegmentSize>& m_vector;
+        size_t m_segment;
+        size_t m_index;
+    };
+
+    // SegmentedVector is just like Vector, but it doesn't move the values
+    // stored in its buffer when it grows. Therefore, it is safe to keep
+    // pointers into a SegmentedVector.
+    template <typename T, size_t SegmentSize> class SegmentedVector {
+        friend class SegmentedVectorIterator<T, SegmentSize>;
+    public:
+        typedef SegmentedVectorIterator<T, SegmentSize> Iterator;
+
+        SegmentedVector()
+            : m_size(0)
+        {
+            m_segments.append(&m_inlineSegment);
+        }
+
+        ~SegmentedVector()
+        {
+            deleteAllSegments();
+        }
+
+        size_t size() const { return m_size; }
+
+        T& at(size_t index)
+        {
+            if (index < SegmentSize)
+                return m_inlineSegment[index];
+            return segmentFor(index)->at(subscriptFor(index));
+        }
+
+        T& operator[](size_t index)
+        {
+            return at(index);
+        }
+
+        T& last()
+        {
+            return at(size() - 1);
+        }
+
+        template <typename U> void append(const U& value)
+        {
+            ++m_size;
+
+            if (m_size <= SegmentSize) {
+                m_inlineSegment.uncheckedAppend(value);
+                return;
+            }
+
+            if (!segmentExistsFor(m_size - 1))
+                m_segments.append(new Segment);
+            segmentFor(m_size - 1)->uncheckedAppend(value);
+        }
+
+        T& alloc()
+        {
+            append<T>(T());
+            return last();
+        }
+
+        void removeLast()
+        {
+            if (m_size <= SegmentSize)
+                m_inlineSegment.removeLast();
+            else
+                segmentFor(m_size - 1)->removeLast();
+            --m_size;
+        }
+
+        void grow(size_t size)
+        {
+            ASSERT(size > m_size);
+            ensureSegmentsFor(size);
+            m_size = size;
+        }
+
+        void clear()
+        {
+            deleteAllSegments();
+            m_segments.resize(1);
+            m_inlineSegment.clear();
+            m_size = 0;
+        }
+
+        Iterator begin()
+        {
+            return Iterator(*this, 0, m_size ? 0 : SegmentSize);
+        }
+
+        Iterator end()
+        {
+            return Iterator(*this, 0, SegmentSize);
+        }
+
+    private:
+        typedef Vector<T, SegmentSize> Segment;
+
+        void deleteAllSegments()
+        {
+            // Skip the first segment, because it's our inline segment, which was
+            // not created by new.
+            for (size_t i = 1; i < m_segments.size(); i++)
+                delete m_segments[i];
+        }
+
+        bool segmentExistsFor(size_t index)
+        {
+            return index / SegmentSize < m_segments.size();
+        }
+
+        Segment* segmentFor(size_t index)
+        {
+            return m_segments[index / SegmentSize];
+        }
+
+        size_t subscriptFor(size_t index)
+        {
+            return index % SegmentSize;
+        }
+
+        void ensureSegmentsFor(size_t size)
+        {
+            size_t segmentCount = m_size / SegmentSize;
+            if (m_size % SegmentSize)
+                ++segmentCount;
+            segmentCount = std::max<size_t>(segmentCount, 1); // We always have at least our inline segment.
+
+            size_t neededSegmentCount = size / SegmentSize;
+            if (size % SegmentSize)
+                ++neededSegmentCount;
+
+            // Fill up to N - 1 segments.
+            size_t end = neededSegmentCount - 1;
+            for (size_t i = segmentCount - 1; i < end; ++i)
+                ensureSegment(i, SegmentSize);
+
+            // Grow segment N to accomodate the remainder.
+            ensureSegment(end, subscriptFor(size - 1) + 1);
+        }
+
+        void ensureSegment(size_t segmentIndex, size_t size)
+        {
+            ASSERT(segmentIndex <= m_segments.size());
+            if (segmentIndex == m_segments.size())
+                m_segments.append(new Segment);
+            m_segments[segmentIndex]->grow(size);
+        }
+
+        size_t m_size;
+        Segment m_inlineSegment;
+        Vector<Segment*, 32> m_segments;
+    };
+
+} // namespace WTF
+
+#endif // SegmentedVector_h
index 14227abb30b2e0c1d198f0a5da0ceafecb44757b..d21d1ffccf8b61a5c8da7f77f4f81346ed1d530b 100644 (file)
     static type& name = *new type arguments
 #endif
 
+// OBJECT_OFFSETOF: Like the C++ offsetof macro, but you can use it with classes.
+// The magic number 0x4000 is insignificant. We use it to avoid using NULL, since
+// NULL can cause compiler problems, especially in cases of multiple inheritance.
+#define OBJECT_OFFSETOF(class, field) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->field)) - 0x4000)
+
 namespace WTF {
 
     /*
      * C++'s idea of a reinterpret_cast lacks sufficient cojones.
      */
     template<typename TO, typename FROM>
-    TO bitwise_cast(FROM in)
+    TO bitwise_cast(FROM from)
     {
-        COMPILE_ASSERT(sizeof(TO) == sizeof(FROM), WTF_wtf_reinterpret_cast_sizeof_types_is_equal);
+        COMPILE_ASSERT(sizeof(TO) == sizeof(FROM), WTF_bitwise_cast_sizeof_casted_types_is_equal);
         union {
             FROM from;
             TO to;
         } u;
-        u.from = in;
+        u.from = from;
         return u.to;
     }
 
index 881b0667bcbdee7364a967414419861f0248df15..1c23390d55617b1fa8da7d6870b52c673f8d43e6 100644 (file)
 #include <stdarg.h>
 #include <stdio.h>
 
+#if HAVE(STRINGS_H) 
+#include <strings.h> 
+#endif 
+
 #if COMPILER(MSVC)
 
 inline int snprintf(char* buffer, size_t count, const char* format, ...) 
@@ -41,7 +45,7 @@ inline int snprintf(char* buffer, size_t count, const char* format, ...)
     return result;
 }
 
-#if COMPILER(MSVC7) || PLATFORM(WIN_CE)
+#if COMPILER(MSVC7) || PLATFORM(WINCE)
 
 inline int vsnprintf(char* buffer, size_t count, const char* format, va_list args)
 {
@@ -50,7 +54,7 @@ inline int vsnprintf(char* buffer, size_t count, const char* format, va_list arg
 
 #endif
 
-#if PLATFORM(WIN_CE)
+#if PLATFORM(WINCE)
 
 inline int strnicmp(const char* string1, const char* string2, size_t count)
 {
index 21a87e4195c3b55aa39c4303aefdd59668fe98dc..3f56c24bbe1038a5e54abbebc9f174a8be323a1e 100644 (file)
@@ -54,7 +54,6 @@
 #endif
 
 #include <string.h>
-
 #include "Assertions.h"
 
 // Single-level array
@@ -164,7 +163,7 @@ class TCMalloc_PageMap2 {
 
 #ifdef WTF_CHANGES
   template<class Visitor, class MemoryReader>
-  void visit(const Visitor& visitor, const MemoryReader& reader)
+  void visitValues(Visitor& visitor, const MemoryReader& reader)
   {
     for (int i = 0; i < ROOT_LENGTH; i++) {
       if (!root_[i])
@@ -175,6 +174,14 @@ class TCMalloc_PageMap2 {
         ;
     }
   }
+
+  template<class Visitor, class MemoryReader>
+  void visitAllocations(Visitor& visitor, const MemoryReader&) {
+    for (int i = 0; i < ROOT_LENGTH; i++) {
+      if (root_[i])
+        visitor.visit(root_[i], sizeof(Leaf));
+    }
+  }
 #endif
 };
 
@@ -266,7 +273,7 @@ class TCMalloc_PageMap3 {
 
 #ifdef WTF_CHANGES
   template<class Visitor, class MemoryReader>
-  void visit(const Visitor& visitor, const MemoryReader& reader) {
+  void visitValues(Visitor& visitor, const MemoryReader& reader) {
     Node* root = reader(root_);
     for (int i = 0; i < INTERIOR_LENGTH; i++) {
       if (!root->ptrs[i])
@@ -283,6 +290,26 @@ class TCMalloc_PageMap3 {
       }
     }
   }
+
+  template<class Visitor, class MemoryReader>
+  void visitAllocations(Visitor& visitor, const MemoryReader& reader) {
+    visitor.visit(root_, sizeof(Node));
+
+    Node* root = reader(root_);
+    for (int i = 0; i < INTERIOR_LENGTH; i++) {
+      if (!root->ptrs[i])
+        continue;
+
+      visitor.visit(root->ptrs[i], sizeof(Node));
+      Node* n = reader(root->ptrs[i]);
+      for (int j = 0; j < INTERIOR_LENGTH; j++) {
+        if (!n->ptrs[j])
+          continue;
+
+        visitor.visit(n->ptrs[j], sizeof(Leaf));
+      }
+    }
+  }
 #endif
 };
 
index df1aa3333b18807d377c850e65e6e8354ee1a531..659bb0e64d9f47c4ff108919b994e110fdfe34e4 100644 (file)
 // Author: Sanjay Ghemawat
 
 #include "config.h"
+#include "TCSystemAlloc.h"
+
+#include <algorithm>
+#include <fcntl.h>
+#include "Assertions.h"
+#include "TCSpinLock.h"
+#include "UnusedParam.h"
+
 #if HAVE(STDINT_H)
 #include <stdint.h>
 #elif HAVE(INTTYPES_H)
@@ -38,6 +46,7 @@
 #else
 #include <sys/types.h>
 #endif
+
 #if PLATFORM(WIN_OS)
 #include "windows.h"
 #else
 #include <unistd.h>
 #include <sys/mman.h>
 #endif
-#include <fcntl.h>
-#include "Assertions.h"
-#include "TCSystemAlloc.h"
-#include "TCSpinLock.h"
-#include "UnusedParam.h"
 
 #ifndef MAP_ANONYMOUS
 #define MAP_ANONYMOUS MAP_ANON
 #endif
 
+using namespace std;
+
 // Structure for discovering alignment
 union MemoryAligner {
   void*  p;
@@ -381,13 +387,23 @@ void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size, size_t alignment) {
   return NULL;
 }
 
+#if HAVE(MADV_FREE_REUSE)
+
+void TCMalloc_SystemRelease(void* start, size_t length)
+{
+    while (madvise(start, length, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
+}
+
+#elif HAVE(MADV_FREE) || HAVE(MADV_DONTNEED)
+
 void TCMalloc_SystemRelease(void* start, size_t length)
 {
-#if HAVE(MADV_FREE) || HAVE(MADV_DONTNEED)
+    // MADV_FREE clears the modified bit on pages, which allows
+    // them to be discarded immediately.
 #if HAVE(MADV_FREE)
-  const int advice = MADV_FREE;
+    const int advice = MADV_FREE;
 #else
-  const int advice = MADV_DONTNEED;
+    const int advice = MADV_DONTNEED;
 #endif
   if (FLAGS_malloc_devmem_start) {
     // It's not safe to use MADV_DONTNEED if we've been mapping
@@ -419,25 +435,87 @@ void TCMalloc_SystemRelease(void* start, size_t length)
            errno == EAGAIN) {
       // NOP
     }
-    return;
   }
-#endif
+}
 
-#if HAVE(MMAP)
+#elif HAVE(MMAP)
+
+void TCMalloc_SystemRelease(void* start, size_t length)
+{
   void* newAddress = mmap(start, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
   // If the mmap failed then that's ok, we just won't return the memory to the system.
   ASSERT_UNUSED(newAddress, newAddress == start || newAddress == reinterpret_cast<void*>(MAP_FAILED));
-  return;
-#endif
+}
+
+#elif HAVE(VIRTUALALLOC)
+
+void TCMalloc_SystemRelease(void* start, size_t length)
+{
+    if (VirtualFree(start, length, MEM_DECOMMIT))
+        return;
+
+    // The decommit may fail if the memory region consists of allocations
+    // from more than one call to VirtualAlloc.  In this case, fall back to
+    // using VirtualQuery to retrieve the allocation boundaries and decommit
+    // them each individually.
+
+    char* ptr = static_cast<char*>(start);
+    char* end = ptr + length;
+    MEMORY_BASIC_INFORMATION info;
+    while (ptr < end) {
+        size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
+        ASSERT_UNUSED(resultSize, resultSize == sizeof(info));
+
+        size_t decommitSize = min<size_t>(info.RegionSize, end - ptr);
+        BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT);
+        ASSERT_UNUSED(success, success);
+        ptr += decommitSize;
+    }
+}
+
+#else
+
+// Platforms that don't support returning memory use an empty inline version of TCMalloc_SystemRelease
+// declared in TCSystemAlloc.h
 
-#if !HAVE(MADV_DONTNEED) && !HAVE(MMAP)
-  UNUSED_PARAM(start);
-  UNUSED_PARAM(length);
 #endif
+
+#if HAVE(MADV_FREE_REUSE)
+
+void TCMalloc_SystemCommit(void* start, size_t length)
+{
+    while (madvise(start, length, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
 }
 
-#if HAVE(VIRTUALALLOC)
-void TCMalloc_SystemCommit(void*, size_t)
+#elif HAVE(VIRTUALALLOC)
+
+void TCMalloc_SystemCommit(void* start, size_t length)
 {
+    if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start)
+        return;
+
+    // The commit may fail if the memory region consists of allocations
+    // from more than one call to VirtualAlloc.  In this case, fall back to
+    // using VirtualQuery to retrieve the allocation boundaries and commit them
+    // each individually.
+
+    char* ptr = static_cast<char*>(start);
+    char* end = ptr + length;
+    MEMORY_BASIC_INFORMATION info;
+    while (ptr < end) {
+        size_t resultSize = VirtualQuery(ptr, &info, sizeof(info));
+        ASSERT_UNUSED(resultSize, resultSize == sizeof(info));
+
+        size_t commitSize = min<size_t>(info.RegionSize, end - ptr);
+        void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT, PAGE_READWRITE);
+        ASSERT_UNUSED(newAddress, newAddress == ptr);
+        ptr += commitSize;
+    }
 }
+
+#else
+
+// Platforms that don't need to explicitly commit memory use an empty inline version of TCMalloc_SystemCommit
+// declared in TCSystemAlloc.h
+
 #endif
index 0caf718b5ec7087c65d5970f64f07c8187eaa60c..1c677889c25b95eb8127104d6bf6078bf37ae319 100644 (file)
@@ -62,9 +62,13 @@ extern void* TCMalloc_SystemAlloc(size_t bytes, size_t *actual_bytes,
 // be released, partial pages will not.)
 extern void TCMalloc_SystemRelease(void* start, size_t length);
 
-#if HAVE(VIRTUALALLOC)
 extern void TCMalloc_SystemCommit(void* start, size_t length);
-#else
+
+#if !HAVE(MADV_FREE_REUSE) && !HAVE(MADV_DONTNEED) && !HAVE(MMAP) && !HAVE(VIRTUALALLOC)
+inline void TCMalloc_SystemRelease(void*, size_t) { }
+#endif
+
+#if !HAVE(VIRTUALALLOC) && !HAVE(MADV_FREE_REUSE)
 inline void TCMalloc_SystemCommit(void*, size_t) { }
 #endif
 
index 76038025d9340fd68c88350ed47b362979371851..b07a9a21e40851c037f2b8199ee94283079dc63c 100644 (file)
 
 #if USE(PTHREADS)
 #include <pthread.h>
+#elif PLATFORM(QT)
+#include <QThreadStorage>
 #elif PLATFORM(WIN_OS)
 #include <windows.h>
 #endif
 
 namespace WTF {
 
-#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+#if !USE(PTHREADS) && !PLATFORM(QT) && PLATFORM(WIN_OS)
 // ThreadSpecificThreadExit should be called each time when a thread is detached.
 // This is done automatically for threads created with WTF::createThread.
 void ThreadSpecificThreadExit();
@@ -66,7 +68,7 @@ public:
     ~ThreadSpecific();
 
 private:
-#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+#if !USE(PTHREADS) && !PLATFORM(QT) && PLATFORM(WIN_OS)
     friend void ThreadSpecificThreadExit();
 #endif
     
@@ -74,7 +76,7 @@ private:
     void set(T*);
     void static destroy(void* ptr);
 
-#if USE(PTHREADS) || PLATFORM(WIN_OS)
+#if USE(PTHREADS) || PLATFORM(QT) || PLATFORM(WIN_OS)
     struct Data : Noncopyable {
         Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {}
 
@@ -88,6 +90,8 @@ private:
 
 #if USE(PTHREADS)
     pthread_key_t m_key;
+#elif PLATFORM(QT)
+    QThreadStorage<Data*> m_key;
 #elif PLATFORM(WIN_OS)
     int m_index;
 #endif
@@ -122,6 +126,37 @@ inline void ThreadSpecific<T>::set(T* ptr)
     pthread_setspecific(m_key, new Data(ptr, this));
 }
 
+#elif PLATFORM(QT)
+
+template<typename T>
+inline ThreadSpecific<T>::ThreadSpecific()
+{
+}
+
+template<typename T>
+inline ThreadSpecific<T>::~ThreadSpecific()
+{
+    Data* data = static_cast<Data*>(m_key.localData());
+    if (data)
+        data->destructor(data);
+}
+
+template<typename T>
+inline T* ThreadSpecific<T>::get()
+{
+    Data* data = static_cast<Data*>(m_key.localData());
+    return data ? data->value : 0;
+}
+
+template<typename T>
+inline void ThreadSpecific<T>::set(T* ptr)
+{
+    ASSERT(!get());
+    Data* data = new Data(ptr, this);
+    data->destructor = &ThreadSpecific<T>::destroy;
+    m_key.setLocalData(data);
+}
+
 #elif PLATFORM(WIN_OS)
 
 // The maximum number of TLS keys that can be created. For simplification, we assume that:
@@ -129,8 +164,8 @@ inline void ThreadSpecific<T>::set(T* ptr)
 // 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough.
 const int kMaxTlsKeySize = 256;
 
-extern long g_tls_key_count;
-extern DWORD g_tls_keys[kMaxTlsKeySize];
+long& tlsKeyCount();
+DWORD* tlsKeys();
 
 template<typename T>
 inline ThreadSpecific<T>::ThreadSpecific()
@@ -140,23 +175,23 @@ inline ThreadSpecific<T>::ThreadSpecific()
     if (tls_key == TLS_OUT_OF_INDEXES)
         CRASH();
 
-    m_index = InterlockedIncrement(&g_tls_key_count) - 1;
+    m_index = InterlockedIncrement(&tlsKeyCount()) - 1;
     if (m_index >= kMaxTlsKeySize)
         CRASH();
-    g_tls_keys[m_index] = tls_key;
+    tlsKeys()[m_index] = tls_key;
 }
 
 template<typename T>
 inline ThreadSpecific<T>::~ThreadSpecific()
 {
     // Does not invoke destructor functions. They will be called from ThreadSpecificThreadExit when the thread is detached.
-    TlsFree(g_tls_keys[m_index]);
+    TlsFree(tlsKeys()[m_index]);
 }
 
 template<typename T>
 inline T* ThreadSpecific<T>::get()
 {
-    Data* data = static_cast<Data*>(TlsGetValue(g_tls_keys[m_index]));
+    Data* data = static_cast<Data*>(TlsGetValue(tlsKeys()[m_index]));
     return data ? data->value : 0;
 }
 
@@ -166,7 +201,7 @@ inline void ThreadSpecific<T>::set(T* ptr)
     ASSERT(!get());
     Data* data = new Data(ptr, this);
     data->destructor = &ThreadSpecific<T>::destroy;
-    TlsSetValue(g_tls_keys[m_index], data);
+    TlsSetValue(tlsKeys()[m_index], data);
 }
 
 #else
@@ -189,8 +224,10 @@ inline void ThreadSpecific<T>::destroy(void* ptr)
 
 #if USE(PTHREADS)
     pthread_setspecific(data->owner->m_key, 0);
+#elif PLATFORM(QT)
+    data->owner->m_key.setLocalData(0);
 #elif PLATFORM(WIN_OS)
-    TlsSetValue(g_tls_keys[data->owner->m_index], 0);
+    TlsSetValue(tlsKeys()[data->owner->m_index], 0);
 #else
 #error ThreadSpecific is not implemented for this platform.
 #endif
index 1a3febbf62d76fe95b54368730821cb3de457532..f2c0cad95766558f0f69e2457490fea8bf558e45 100644 (file)
 
 namespace WTF {
 
-long g_tls_key_count = 0;
-DWORD g_tls_keys[kMaxTlsKeySize];
+long& tlsKeyCount()
+{
+    static long count;
+    return count;
+}
+
+DWORD* tlsKeys()
+{
+    static DWORD keys[kMaxTlsKeySize];
+    return keys;
+}
 
 void ThreadSpecificThreadExit()
 {
-    for (long i = 0; i < g_tls_key_count; i++) {
+    for (long i = 0; i < tlsKeyCount(); i++) {
         // The layout of ThreadSpecific<T>::Data does not depend on T. So we are safe to do the static cast to ThreadSpecific<int> in order to access its data member.
-        ThreadSpecific<int>::Data* data = static_cast<ThreadSpecific<int>::Data*>(TlsGetValue(g_tls_keys[i]));
+        ThreadSpecific<int>::Data* data = static_cast<ThreadSpecific<int>::Data*>(TlsGetValue(tlsKeys()[i]));
         if (data)
             data->destructor(data);
     }
index 41c913589dca963c274b5cb273ccec76e92a329c..bd25ee749869d2b1aac78aa25aff882df80d23c6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "Threading.h"
 
+#include <string.h>
+
 namespace WTF {
 
 struct NewThreadContext {
-    NewThreadContext(ThreadFunction entryPoint, void* data)
+    NewThreadContext(ThreadFunction entryPoint, void* data, const char* name)
         : entryPoint(entryPoint)
         , data(data)
-    { }
+        , name(name)
+    {
+    }
 
     ThreadFunction entryPoint;
     void* data;
+    const char* name;
 
     Mutex creationMutex;
 };
@@ -44,6 +49,8 @@ static void* threadEntryPoint(void* contextData)
 {
     NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData);
 
+    setThreadNameInternal(context->name);
+
     // Block until our creating thread has completed any extra setup work
     {
         MutexLocker locker(context->creationMutex);
@@ -59,7 +66,14 @@ static void* threadEntryPoint(void* contextData)
 
 ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
 {
-    NewThreadContext* context = new NewThreadContext(entryPoint, data);
+    // Visual Studio has a 31-character limit on thread names. Longer names will
+    // be truncated silently, but we'd like callers to know about the limit.
+#if !LOG_DISABLED
+    if (strlen(name) > 31)
+        LOG_ERROR("Thread name \"%s\" is longer than 31 characters and will be truncated by Visual Studio", name);
+#endif
+
+    NewThreadContext* context = new NewThreadContext(entryPoint, data, name);
 
     // Prevent the thread body from executing until we've established the thread identifier
     MutexLocker locker(context->creationMutex);
index 5e5f020b81293c6fcc6fd0385fb1027a5133fcb0..b12f41fa771c92f98f6ef141698098f894d8272a 100644 (file)
@@ -59,9 +59,7 @@
 #ifndef Threading_h
 #define Threading_h
 
-#include <wtf/Platform.h>
-
-#if PLATFORM(WIN_CE)
+#if PLATFORM(WINCE)
 #include <windows.h>
 #endif
 
@@ -69,7 +67,7 @@
 #include <wtf/Locker.h>
 #include <wtf/Noncopyable.h>
 
-#if PLATFORM(WIN_OS) && !PLATFORM(WIN_CE)
+#if PLATFORM(WIN_OS) && !PLATFORM(WINCE)
 #include <windows.h>
 #elif PLATFORM(DARWIN)
 #include <libkern/OSAtomic.h>
@@ -89,14 +87,6 @@ typedef struct _GMutex GMutex;
 typedef struct _GCond GCond;
 #endif
 
-#if USE(PTHREADS) && (PLATFORM(MAC) || PLATFORM(IPHONE))
-#ifdef __OBJC__
-@class NSThread;
-#else
-class NSThread;
-#endif
-#endif
-
 #if PLATFORM(QT)
 #include <qglobal.h>
 QT_BEGIN_NAMESPACE
@@ -118,10 +108,17 @@ namespace WTF {
 typedef uint32_t ThreadIdentifier;
 typedef void* (*ThreadFunction)(void* argument);
 
-// Returns 0 if thread creation failed
+// Returns 0 if thread creation failed.
+// The thread name must be a literal since on some platforms it's passed in to the thread.
 ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);
+
+// Internal platform-specific createThread implementation.
 ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);
 
+// Called in the thread during initialization.
+// Helpful for platforms where the thread name must be set from within the thread.
+void setThreadNameInternal(const char* threadName);
+
 ThreadIdentifier currentThread();
 bool isMainThread();
 int waitForThreadCompletion(ThreadIdentifier, void**);
@@ -129,18 +126,22 @@ void detachThread(ThreadIdentifier);
 
 #if USE(PTHREADS)
 typedef pthread_mutex_t PlatformMutex;
+typedef pthread_rwlock_t PlatformReadWriteLock;
 typedef pthread_cond_t PlatformCondition;
 #elif PLATFORM(GTK)
 typedef GOwnPtr<GMutex> PlatformMutex;
+typedef void* PlatformReadWriteLock; // FIXME: Implement.
 typedef GOwnPtr<GCond> PlatformCondition;
 #elif PLATFORM(QT)
 typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex;
+typedef void* PlatformReadWriteLock; // FIXME: Implement.
 typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition;
 #elif PLATFORM(WIN_OS)
 struct PlatformMutex {
     CRITICAL_SECTION m_internalMutex;
     size_t m_recursionCount;
 };
+typedef void* PlatformReadWriteLock; // FIXME: Implement.
 struct PlatformCondition {
     size_t m_waitersGone;
     size_t m_waitersBlocked;
@@ -154,6 +155,7 @@ struct PlatformCondition {
 };
 #else
 typedef void* PlatformMutex;
+typedef void* PlatformReadWriteLock;
 typedef void* PlatformCondition;
 #endif
     
@@ -174,6 +176,23 @@ private:
 
 typedef Locker<Mutex> MutexLocker;
 
+class ReadWriteLock : Noncopyable {
+public:
+    ReadWriteLock();
+    ~ReadWriteLock();
+
+    void readLock();
+    bool tryReadLock();
+
+    void writeLock();
+    bool tryWriteLock();
+    
+    void unlock();
+
+private:
+    PlatformReadWriteLock m_readWriteLock;
+};
+
 class ThreadCondition : Noncopyable {
 public:
     ThreadCondition();
@@ -193,7 +212,7 @@ private:
 #if PLATFORM(WIN_OS)
 #define WTF_USE_LOCKFREE_THREADSAFESHARED 1
 
-#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WIN_CE)
+#if COMPILER(MINGW) || COMPILER(MSVC7) || PLATFORM(WINCE)
 inline void atomicIncrement(int* addend) { InterlockedIncrement(reinterpret_cast<long*>(addend)); }
 inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
 #else
@@ -215,9 +234,9 @@ inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_
 
 #endif
 
-template<class T> class ThreadSafeShared : Noncopyable {
+class ThreadSafeSharedBase : Noncopyable {
 public:
-    ThreadSafeShared(int initialRefCount = 1)
+    ThreadSafeSharedBase(int initialRefCount = 1)
         : m_refCount(initialRefCount)
     {
     }
@@ -232,20 +251,6 @@ public:
 #endif
     }
 
-    void deref()
-    {
-#if USE(LOCKFREE_THREADSAFESHARED)
-        if (atomicDecrement(&m_refCount) <= 0)
-#else
-        {
-            MutexLocker locker(m_mutex);
-            --m_refCount;
-        }
-        if (m_refCount <= 0)
-#endif
-            delete static_cast<T*>(this);
-    }
-
     bool hasOneRef()
     {
         return refCount() == 1;
@@ -259,22 +264,54 @@ public:
         return static_cast<int const volatile &>(m_refCount);
     }
 
+protected:
+    // Returns whether the pointer should be freed or not.
+    bool derefBase()
+    {
+#if USE(LOCKFREE_THREADSAFESHARED)
+        if (atomicDecrement(&m_refCount) <= 0)
+            return true;
+#else
+        int refCount;
+        {
+            MutexLocker locker(m_mutex);
+            --m_refCount;
+            refCount = m_refCount;
+        }
+        if (refCount <= 0)
+            return true;
+#endif
+        return false;
+    }
+
 private:
+    template<class T>
+    friend class CrossThreadRefCounted;
+
     int m_refCount;
 #if !USE(LOCKFREE_THREADSAFESHARED)
     mutable Mutex m_mutex;
 #endif
 };
 
+template<class T> class ThreadSafeShared : public ThreadSafeSharedBase {
+public:
+    ThreadSafeShared(int initialRefCount = 1)
+        : ThreadSafeSharedBase(initialRefCount)
+    {
+    }
+
+    void deref()
+    {
+        if (derefBase())
+            delete static_cast<T*>(this);
+    }
+};
+
 // This function must be called from the main thread. It is safe to call it repeatedly.
 // Darwin is an exception to this rule: it is OK to call it from any thread, the only requirement is that the calls are not reentrant.
 void initializeThreading();
 
-#if USE(PTHREADS) && (PLATFORM(MAC) || PLATFORM(IPHONE))
-void initializeMainNSThread();
-NSThread *mainNSThread();
-#endif
-    
 void lockAtomicallyInitializedStaticMutex();
 void unlockAtomicallyInitializedStaticMutex();
 
diff --git a/wtf/ThreadingGtk.cpp b/wtf/ThreadingGtk.cpp
deleted file mode 100644 (file)
index 24c34ca..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "Threading.h"
-
-#if !USE(PTHREADS)
-
-#include "CurrentTime.h"
-#include "HashMap.h"
-#include "MainThread.h"
-#include "RandomNumberSeed.h"
-
-#include <glib.h>
-#include <limits.h>
-
-namespace WTF {
-
-static Mutex* atomicallyInitializedStaticMutex;
-
-static ThreadIdentifier mainThreadIdentifier;
-
-static Mutex& threadMapMutex()
-{
-    static Mutex mutex;
-    return mutex;
-}
-
-void initializeThreading()
-{
-    if (!g_thread_supported())
-        g_thread_init(NULL);
-    ASSERT(g_thread_supported());
-
-    if (!atomicallyInitializedStaticMutex) {
-        atomicallyInitializedStaticMutex = new Mutex;
-        threadMapMutex();
-        initializeRandomNumberGenerator();
-        mainThreadIdentifier = currentThread();
-        initializeMainThread();
-    }
-}
-
-void lockAtomicallyInitializedStaticMutex()
-{
-    ASSERT(atomicallyInitializedStaticMutex);
-    atomicallyInitializedStaticMutex->lock();
-}
-
-void unlockAtomicallyInitializedStaticMutex()
-{
-    atomicallyInitializedStaticMutex->unlock();
-}
-
-static HashMap<ThreadIdentifier, GThread*>& threadMap()
-{
-    static HashMap<ThreadIdentifier, GThread*> map;
-    return map;
-}
-
-static ThreadIdentifier identifierByGthreadHandle(GThread*& thread)
-{
-    MutexLocker locker(threadMapMutex());
-
-    HashMap<ThreadIdentifier, GThread*>::iterator i = threadMap().begin();
-    for (; i != threadMap().end(); ++i) {
-        if (i->second == thread)
-            return i->first;
-    }
-
-    return 0;
-}
-
-static ThreadIdentifier establishIdentifierForThread(GThread*& thread)
-{
-    ASSERT(!identifierByGthreadHandle(thread));
-
-    MutexLocker locker(threadMapMutex());
-
-    static ThreadIdentifier identifierCount = 1;
-
-    threadMap().add(identifierCount, thread);
-
-    return identifierCount++;
-}
-
-static GThread* threadForIdentifier(ThreadIdentifier id)
-{
-    MutexLocker locker(threadMapMutex());
-
-    return threadMap().get(id);
-}
-
-static void clearThreadForIdentifier(ThreadIdentifier id)
-{
-    MutexLocker locker(threadMapMutex());
-
-    ASSERT(threadMap().contains(id));
-
-    threadMap().remove(id);
-}
-
-ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
-{
-    GThread* thread;
-    if (!(thread = g_thread_create(entryPoint, data, TRUE, 0))) {
-        LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
-        return 0;
-    }
-
-    ThreadIdentifier threadID = establishIdentifierForThread(thread);
-    return threadID;
-}
-
-int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
-{
-    ASSERT(threadID);
-
-    GThread* thread = threadForIdentifier(threadID);
-
-    void* joinResult = g_thread_join(thread);
-    if (result)
-        *result = joinResult;
-
-    clearThreadForIdentifier(threadID);
-    return 0;
-}
-
-void detachThread(ThreadIdentifier)
-{
-}
-
-ThreadIdentifier currentThread()
-{
-    GThread* currentThread = g_thread_self();
-    if (ThreadIdentifier id = identifierByGthreadHandle(currentThread))
-        return id;
-    return establishIdentifierForThread(currentThread);
-}
-
-bool isMainThread()
-{
-    return currentThread() == mainThreadIdentifier;
-}
-
-Mutex::Mutex()
-    : m_mutex(g_mutex_new())
-{
-}
-
-Mutex::~Mutex()
-{
-}
-
-void Mutex::lock()
-{
-    g_mutex_lock(m_mutex.get());
-}
-
-bool Mutex::tryLock()
-{
-    return g_mutex_trylock(m_mutex.get());
-}
-
-void Mutex::unlock()
-{
-    g_mutex_unlock(m_mutex.get());
-}
-
-ThreadCondition::ThreadCondition()
-    : m_condition(g_cond_new())
-{
-}
-
-ThreadCondition::~ThreadCondition()
-{
-}
-
-void ThreadCondition::wait(Mutex& mutex)
-{
-    g_cond_wait(m_condition.get(), mutex.impl().get());
-}
-
-bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
-{
-    // Time is in the past - return right away.
-    if (absoluteTime < currentTime())
-        return false;
-    
-    // Time is too far in the future for g_cond_timed_wait - wait forever.
-    if (absoluteTime > INT_MAX) {
-        wait(mutex);
-        return true;
-    }
-
-    int timeSeconds = static_cast<int>(absoluteTime);
-    int timeMicroseconds = static_cast<int>((absoluteTime - timeSeconds) * 1000000.0);
-    
-    GTimeVal targetTime;
-    targetTime.tv_sec = timeSeconds;
-    targetTime.tv_usec = timeMicroseconds;
-
-    return g_cond_timed_wait(m_condition.get(), mutex.impl().get(), &targetTime);
-}
-
-void ThreadCondition::signal()
-{
-    g_cond_signal(m_condition.get());
-}
-
-void ThreadCondition::broadcast()
-{
-    g_cond_broadcast(m_condition.get());
-}
-
-
-}
-
-#endif // !USE(PTHREADS)
index 0be2a4be41e66f2073d3436de7643989991be70f..46f23d211f1518b273c76de385870968205b2ed7 100644 (file)
 namespace WTF {
 
 void initializeThreading() { }
-ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char*) { return 0; }
+ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char*) { return ThreadIdentifier(); }
+void setThreadNameInternal(const char*) { }
 int waitForThreadCompletion(ThreadIdentifier, void**) { return 0; }
 void detachThread(ThreadIdentifier) { }
-ThreadIdentifier currentThread() { return 0; }
+ThreadIdentifier currentThread() { return ThreadIdentifier(); }
 bool isMainThread() { return true; }
 
 Mutex::Mutex() { }
@@ -47,8 +48,8 @@ void Mutex::unlock() { }
 
 ThreadCondition::ThreadCondition() { }
 ThreadCondition::~ThreadCondition() { }
-void ThreadCondition::wait(Mutex& mutex) { }
-bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) { return false; }
+void ThreadCondition::wait(Mutex&) { }
+bool ThreadCondition::timedWait(Mutex&, double) { return false; }
 void ThreadCondition::signal() { }
 void ThreadCondition::broadcast() { }
 
index 3cc2f8a73ff2cf52f81016246718fad5c7b55742..0c6db2d1ec60c794b4f6a5264a55c9b612d30187 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
  * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
  *
  * Redistribution and use in source and binary forms, with or without
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 #include "config.h"
 #include "Threading.h"
 
-#include "StdLibExtras.h"
-
 #if USE(PTHREADS)
 
 #include "CurrentTime.h"
 #include "HashMap.h"
 #include "MainThread.h"
 #include "RandomNumberSeed.h"
-
+#include "StdLibExtras.h"
+#include "UnusedParam.h"
 #include <errno.h>
 #include <limits.h>
 #include <sys/time.h>
 
+#if PLATFORM(ANDROID)
+#include "jni_utility.h"
+#endif
+
 namespace WTF {
 
 typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap;
@@ -63,7 +67,6 @@ void initializeThreading()
         threadMapMutex();
         initializeRandomNumberGenerator();
         mainThreadIdentifier = currentThread();
-        initializeMainNSThread();
         initializeMainThread();
     }
 }
@@ -107,14 +110,14 @@ static ThreadIdentifier establishIdentifierForPthreadHandle(pthread_t& pthreadHa
     static ThreadIdentifier identifierCount = 1;
 
     threadMap().add(identifierCount, pthreadHandle);
-    
+
     return identifierCount++;
 }
 
 static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id)
 {
     MutexLocker locker(threadMapMutex());
-    
+
     return threadMap().get(id);
 }
 
@@ -123,31 +126,76 @@ static void clearPthreadHandleForIdentifier(ThreadIdentifier id)
     MutexLocker locker(threadMapMutex());
 
     ASSERT(threadMap().contains(id));
-    
+
     threadMap().remove(id);
 }
 
+#if PLATFORM(ANDROID)
+// On the Android platform, threads must be registered with the VM before they run.
+struct ThreadData {
+    ThreadFunction entryPoint;
+    void* arg;
+};
+
+static void* runThreadWithRegistration(void* arg)
+{
+    ThreadData* data = static_cast<ThreadData*>(arg);
+    JavaVM* vm = JSC::Bindings::getJavaVM();
+    JNIEnv* env;
+    void* ret = 0;
+    if (vm->AttachCurrentThread(&env, 0) == JNI_OK) {
+        ret = data->entryPoint(data->arg);
+        vm->DetachCurrentThread();
+    }
+    delete data;
+    return ret;
+}
+
+ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
+{
+    pthread_t threadHandle;
+    ThreadData* threadData = new ThreadData();
+    threadData->entryPoint = entryPoint;
+    threadData->arg = data;
+
+    if (pthread_create(&threadHandle, 0, runThreadWithRegistration, static_cast<void*>(threadData))) {
+        LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
+        return 0;
+    }
+    return establishIdentifierForPthreadHandle(threadHandle);
+}
+#else
 ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
 {
     pthread_t threadHandle;
-    if (pthread_create(&threadHandle, NULL, entryPoint, data)) {
+    if (pthread_create(&threadHandle, 0, entryPoint, data)) {
         LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data);
         return 0;
     }
 
     return establishIdentifierForPthreadHandle(threadHandle);
 }
+#endif
+
+void setThreadNameInternal(const char* threadName)
+{
+#if HAVE(PTHREAD_SETNAME_NP)
+    pthread_setname_np(threadName);
+#else
+    UNUSED_PARAM(threadName);
+#endif
+}
 
 int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
 {
     ASSERT(threadID);
-    
+
     pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
+
     int joinResult = pthread_join(pthreadHandle, result);
     if (joinResult == EDEADLK)
         LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID);
-        
+
     clearPthreadHandleForIdentifier(threadID);
     return joinResult;
 }
@@ -155,11 +203,11 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
 void detachThread(ThreadIdentifier threadID)
 {
     ASSERT(threadID);
-    
+
     pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID);
-    
+
     pthread_detach(pthreadHandle);
-    
+
     clearPthreadHandleForIdentifier(threadID);
 }
 
@@ -188,27 +236,82 @@ Mutex::~Mutex()
 
 void Mutex::lock()
 {
-    if (pthread_mutex_lock(&m_mutex) != 0)
-        ASSERT(false);
+    int result = pthread_mutex_lock(&m_mutex);
+    ASSERT_UNUSED(result, !result);
 }
-    
+
 bool Mutex::tryLock()
 {
     int result = pthread_mutex_trylock(&m_mutex);
-    
+
     if (result == 0)
         return true;
-    else if (result == EBUSY)
+    if (result == EBUSY)
         return false;
 
-    ASSERT(false);
+    ASSERT_NOT_REACHED();
     return false;
 }
 
 void Mutex::unlock()
 {
-    if (pthread_mutex_unlock(&m_mutex) != 0)
-        ASSERT(false);
+    int result = pthread_mutex_unlock(&m_mutex);
+    ASSERT_UNUSED(result, !result);
+}
+
+
+ReadWriteLock::ReadWriteLock()
+{
+    pthread_rwlock_init(&m_readWriteLock, NULL);
+}
+
+ReadWriteLock::~ReadWriteLock()
+{
+    pthread_rwlock_destroy(&m_readWriteLock);
+}
+
+void ReadWriteLock::readLock()
+{
+    int result = pthread_rwlock_rdlock(&m_readWriteLock);
+    ASSERT_UNUSED(result, !result);
+}
+
+bool ReadWriteLock::tryReadLock()
+{
+    int result = pthread_rwlock_tryrdlock(&m_readWriteLock);
+
+    if (result == 0)
+        return true;
+    if (result == EBUSY || result == EAGAIN)
+        return false;
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+void ReadWriteLock::writeLock()
+{
+    int result = pthread_rwlock_wrlock(&m_readWriteLock);
+    ASSERT_UNUSED(result, !result);
+}
+
+bool ReadWriteLock::tryWriteLock()
+{
+    int result = pthread_rwlock_trywrlock(&m_readWriteLock);
+
+    if (result == 0)
+        return true;
+    if (result == EBUSY || result == EAGAIN)
+        return false;
+
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
+void ReadWriteLock::unlock()
+{
+    int result = pthread_rwlock_unlock(&m_readWriteLock);
+    ASSERT_UNUSED(result, !result);
 }
 
 ThreadCondition::ThreadCondition()
@@ -223,8 +326,8 @@ ThreadCondition::~ThreadCondition()
     
 void ThreadCondition::wait(Mutex& mutex)
 {
-    if (pthread_cond_wait(&m_condition, &mutex.impl()) != 0)
-        ASSERT(false);
+    int result = pthread_cond_wait(&m_condition, &mutex.impl());
+    ASSERT_UNUSED(result, !result);
 }
 
 bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
@@ -249,16 +352,16 @@ bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
 
 void ThreadCondition::signal()
 {
-    if (pthread_cond_signal(&m_condition) != 0)
-        ASSERT(false);
+    int result = pthread_cond_signal(&m_condition);
+    ASSERT_UNUSED(result, !result);
 }
 
 void ThreadCondition::broadcast()
 {
-    if (pthread_cond_broadcast(&m_condition) != 0)
-        ASSERT(false);
+    int result = pthread_cond_broadcast(&m_condition);
+    ASSERT_UNUSED(result, !result);
 }
-    
+
 } // namespace WTF
 
 #endif // USE(PTHREADS)
diff --git a/wtf/ThreadingQt.cpp b/wtf/ThreadingQt.cpp
deleted file mode 100644 (file)
index 55a479b..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer. 
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution. 
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-#include "config.h"
-#include "Threading.h"
-
-#include "CurrentTime.h"
-#include "HashMap.h"
-#include "MainThread.h"
-#include "RandomNumberSeed.h"
-
-#include <QCoreApplication>
-#include <QMutex>
-#include <QThread>
-#include <QWaitCondition>
-
-namespace WTF {
-
-class ThreadPrivate : public QThread {
-public:
-    ThreadPrivate(ThreadFunction entryPoint, void* data);
-    void run();
-    void* getReturnValue() { return m_returnValue; }
-private:
-    void* m_data;
-    ThreadFunction m_entryPoint;
-    void* m_returnValue;
-};
-
-ThreadPrivate::ThreadPrivate(ThreadFunction entryPoint, void* data) 
-    : m_data(data)
-    , m_entryPoint(entryPoint)
-    , m_returnValue(0)
-{
-}
-
-void ThreadPrivate::run()
-{
-    m_returnValue = m_entryPoint(m_data);
-}
-
-
-static Mutex* atomicallyInitializedStaticMutex;
-
-static ThreadIdentifier mainThreadIdentifier;
-
-static Mutex& threadMapMutex()
-{
-    static Mutex mutex;
-    return mutex;
-}
-
-static HashMap<ThreadIdentifier, QThread*>& threadMap()
-{
-    static HashMap<ThreadIdentifier, QThread*> map;
-    return map;
-}
-
-static ThreadIdentifier identifierByQthreadHandle(QThread*& thread)
-{
-    MutexLocker locker(threadMapMutex());
-
-    HashMap<ThreadIdentifier, QThread*>::iterator i = threadMap().begin();
-    for (; i != threadMap().end(); ++i) {
-        if (i->second == thread)
-            return i->first;
-    }
-
-    return 0;
-}
-
-static ThreadIdentifier establishIdentifierForThread(QThread*& thread)
-{
-    ASSERT(!identifierByQthreadHandle(thread));
-
-    MutexLocker locker(threadMapMutex());
-
-    static ThreadIdentifier identifierCount = 1;
-
-    threadMap().add(identifierCount, thread);
-
-    return identifierCount++;
-}
-
-static void clearThreadForIdentifier(ThreadIdentifier id)
-{
-    MutexLocker locker(threadMapMutex());
-
-    ASSERT(threadMap().contains(id));
-
-    threadMap().remove(id);
-}
-
-static QThread* threadForIdentifier(ThreadIdentifier id)
-{
-    MutexLocker locker(threadMapMutex());
-
-    return threadMap().get(id);
-}
-
-void initializeThreading()
-{
-    if (!atomicallyInitializedStaticMutex) {
-        atomicallyInitializedStaticMutex = new Mutex;
-        threadMapMutex();
-        initializeRandomNumberGenerator();
-        QThread* mainThread = QCoreApplication::instance()->thread();
-        mainThreadIdentifier = identifierByQthreadHandle(mainThread);
-        if (!mainThreadIdentifier)
-            mainThreadIdentifier = establishIdentifierForThread(mainThread);
-        initializeMainThread();
-    }
-}
-
-void lockAtomicallyInitializedStaticMutex()
-{
-    ASSERT(atomicallyInitializedStaticMutex);
-    atomicallyInitializedStaticMutex->lock();
-}
-
-void unlockAtomicallyInitializedStaticMutex()
-{
-    atomicallyInitializedStaticMutex->unlock();
-}
-
-ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
-{
-    ThreadPrivate* thread = new ThreadPrivate(entryPoint, data);
-    if (!thread) {
-        LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
-        return 0;
-    }
-    thread->start();
-
-    QThread* threadRef = static_cast<QThread*>(thread);
-
-    return establishIdentifierForThread(threadRef);
-}
-
-int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
-{
-    ASSERT(threadID);
-
-    QThread* thread = threadForIdentifier(threadID);
-
-    bool res = thread->wait();
-
-    clearThreadForIdentifier(threadID);
-    if (result)
-        *result = static_cast<ThreadPrivate*>(thread)->getReturnValue();
-
-    return !res;
-}
-
-void detachThread(ThreadIdentifier)
-{
-}
-
-ThreadIdentifier currentThread()
-{
-    QThread* currentThread = QThread::currentThread();
-    if (ThreadIdentifier id = identifierByQthreadHandle(currentThread))
-        return id;
-    return establishIdentifierForThread(currentThread);
-}
-
-bool isMainThread()
-{
-    return currentThread() == mainThreadIdentifier;
-}
-
-Mutex::Mutex()
-    : m_mutex(new QMutex())
-{
-}
-
-Mutex::~Mutex()
-{
-    delete m_mutex;
-}
-
-void Mutex::lock()
-{
-    m_mutex->lock();
-}
-
-bool Mutex::tryLock()
-{
-    return m_mutex->tryLock();
-}
-
-void Mutex::unlock()
-{
-    m_mutex->unlock();
-}
-
-ThreadCondition::ThreadCondition()
-    : m_condition(new QWaitCondition())
-{
-}
-
-ThreadCondition::~ThreadCondition()
-{
-    delete m_condition;
-}
-
-void ThreadCondition::wait(Mutex& mutex)
-{
-    m_condition->wait(mutex.impl());
-}
-
-bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
-{
-    double currentTime = WTF::currentTime();
-
-    // Time is in the past - return immediately.
-    if (absoluteTime < currentTime)
-        return false;
-
-    double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
-    // Qt defines wait for up to ULONG_MAX milliseconds.
-    if (intervalMilliseconds >= ULONG_MAX)
-        intervalMilliseconds = ULONG_MAX;
-
-    return m_condition->wait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds));
-}
-
-void ThreadCondition::signal()
-{
-    m_condition->wakeOne();
-}
-
-void ThreadCondition::broadcast()
-{
-    m_condition->wakeAll();
-}
-
-} // namespace WebCore
index 399fb385beed7e986746d1ec3ce1f4f66a003ca8..ea186564b0009f5259805eadb3f6fff88ea96d0b 100644 (file)
@@ -98,7 +98,7 @@
 
 namespace WTF {
 
-// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadName all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>.
+// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>.
 static const DWORD MS_VC_EXCEPTION = 0x406D1388;
 
 #pragma pack(push, 8)
@@ -110,16 +110,12 @@ typedef struct tagTHREADNAME_INFO {
 } THREADNAME_INFO;
 #pragma pack(pop)
 
-static void setThreadName(DWORD dwThreadID, LPCSTR szThreadName)
+void setThreadNameInternal(const char* szThreadName)
 {
-    // Visual Studio has a 31-character limit on thread names. Longer names will
-    // be truncated silently, but we'd like callers to know about the limit.
-    ASSERT_ARG(szThreadName, strlen(szThreadName) <= 31);
-
     THREADNAME_INFO info;
     info.dwType = 0x1000;
     info.szName = szThreadName;
-    info.dwThreadID = dwThreadID;
+    info.dwThreadID = GetCurrentThreadId();
     info.dwFlags = 0;
 
     __try {
@@ -157,7 +153,7 @@ void initializeThreading()
         initializeRandomNumberGenerator();
         initializeMainThread();
         mainThreadIdentifier = currentThread();
-        setThreadName(mainThreadIdentifier, "Main Thread");
+        setThreadNameInternal("Main Thread");
     }
 }
 
@@ -220,9 +216,6 @@ ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, con
         return 0;
     }
 
-    if (threadName)
-        setThreadName(threadIdentifier, threadName);
-
     threadID = static_cast<ThreadIdentifier>(threadIdentifier);
     storeThreadHandleByIdentifier(threadIdentifier, threadHandle);
 
@@ -250,7 +243,7 @@ int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
 void detachThread(ThreadIdentifier threadID)
 {
     ASSERT(threadID);
-    
+
     HANDLE threadHandle = threadHandleForIdentifier(threadID);
     if (threadHandle)
         CloseHandle(threadHandle);
@@ -457,10 +450,13 @@ bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
     if (absoluteTime < currentTime)
         return false;
 
-    double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
-    if (intervalMilliseconds >= INT_MAX)
-        intervalMilliseconds = INT_MAX;
+    // Time is too far in the future (and would overflow unsigned long) - wait forever.
+    if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) {
+        wait(mutex);
+        return true;
+    }
 
+    double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
     return m_condition.timedWait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds));
 }
 
diff --git a/wtf/TypeTraits.cpp b/wtf/TypeTraits.cpp
new file mode 100644 (file)
index 0000000..36fc6c6
--- /dev/null
@@ -0,0 +1,120 @@
+ /*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+#include "TypeTraits.h"
+
+#include "Assertions.h"
+
+namespace WTF {
+
+COMPILE_ASSERT(IsInteger<bool>::value, WTF_IsInteger_bool_true);
+COMPILE_ASSERT(IsInteger<char>::value, WTF_IsInteger_char_true);
+COMPILE_ASSERT(IsInteger<signed char>::value, WTF_IsInteger_signed_char_true);
+COMPILE_ASSERT(IsInteger<unsigned char>::value, WTF_IsInteger_unsigned_char_true);
+COMPILE_ASSERT(IsInteger<short>::value, WTF_IsInteger_short_true);
+COMPILE_ASSERT(IsInteger<unsigned short>::value, WTF_IsInteger_unsigned_short_true);
+COMPILE_ASSERT(IsInteger<int>::value, WTF_IsInteger_int_true);
+COMPILE_ASSERT(IsInteger<unsigned int>::value, WTF_IsInteger_unsigned_int_true);
+COMPILE_ASSERT(IsInteger<long>::value, WTF_IsInteger_long_true);
+COMPILE_ASSERT(IsInteger<unsigned long>::value, WTF_IsInteger_unsigned_long_true);
+COMPILE_ASSERT(IsInteger<long long>::value, WTF_IsInteger_long_long_true);
+COMPILE_ASSERT(IsInteger<unsigned long long>::value, WTF_IsInteger_unsigned_long_long_true);
+#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+COMPILE_ASSERT(IsInteger<wchar_t>::value, WTF_IsInteger_wchar_t_true);
+#endif
+COMPILE_ASSERT(!IsInteger<char*>::value, WTF_IsInteger_char_pointer_false);
+COMPILE_ASSERT(!IsInteger<const char*>::value, WTF_IsInteger_const_char_pointer_false);
+COMPILE_ASSERT(!IsInteger<volatile char*>::value, WTF_IsInteger_volatile_char_pointer_false);
+COMPILE_ASSERT(!IsInteger<double>::value, WTF_IsInteger_double_false);
+COMPILE_ASSERT(!IsInteger<float>::value, WTF_IsInteger_float_false);
+
+COMPILE_ASSERT(IsPod<bool>::value, WTF_IsPod_bool_true);
+COMPILE_ASSERT(IsPod<char>::value, WTF_IsPod_char_true);
+COMPILE_ASSERT(IsPod<signed char>::value, WTF_IsPod_signed_char_true);
+COMPILE_ASSERT(IsPod<unsigned char>::value, WTF_IsPod_unsigned_char_true);
+COMPILE_ASSERT(IsPod<short>::value, WTF_IsPod_short_true);
+COMPILE_ASSERT(IsPod<unsigned short>::value, WTF_IsPod_unsigned_short_true);
+COMPILE_ASSERT(IsPod<int>::value, WTF_IsPod_int_true);
+COMPILE_ASSERT(IsPod<unsigned int>::value, WTF_IsPod_unsigned_int_true);
+COMPILE_ASSERT(IsPod<long>::value, WTF_IsPod_long_true);
+COMPILE_ASSERT(IsPod<unsigned long>::value, WTF_IsPod_unsigned_long_true);
+COMPILE_ASSERT(IsPod<long long>::value, WTF_IsPod_long_long_true);
+COMPILE_ASSERT(IsPod<unsigned long long>::value, WTF_IsPod_unsigned_long_long_true);
+#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+COMPILE_ASSERT(IsPod<wchar_t>::value, WTF_IsPod_wchar_t_true);
+#endif
+COMPILE_ASSERT(IsPod<char*>::value, WTF_IsPod_char_pointer_true);
+COMPILE_ASSERT(IsPod<const char*>::value, WTF_IsPod_const_char_pointer_true);
+COMPILE_ASSERT(IsPod<volatile char*>::value, WTF_IsPod_volatile_char_pointer_true);
+COMPILE_ASSERT(IsPod<double>::value, WTF_IsPod_double_true);
+COMPILE_ASSERT(IsPod<long double>::value, WTF_IsPod_long_double_true);
+COMPILE_ASSERT(IsPod<float>::value, WTF_IsPod_float_true);
+COMPILE_ASSERT(!IsPod<IsPod<bool> >::value, WTF_IsPod_struct_false);
+
+enum IsConvertibleToIntegerCheck { };
+COMPILE_ASSERT(IsConvertibleToInteger<IsConvertibleToIntegerCheck>::value, WTF_IsConvertibleToInteger_enum_true);
+COMPILE_ASSERT(IsConvertibleToInteger<bool>::value, WTF_IsConvertibleToInteger_bool_true);
+COMPILE_ASSERT(IsConvertibleToInteger<char>::value, WTF_IsConvertibleToInteger_char_true);
+COMPILE_ASSERT(IsConvertibleToInteger<signed char>::value, WTF_IsConvertibleToInteger_signed_char_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned char>::value, WTF_IsConvertibleToInteger_unsigned_char_true);
+COMPILE_ASSERT(IsConvertibleToInteger<short>::value, WTF_IsConvertibleToInteger_short_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned short>::value, WTF_IsConvertibleToInteger_unsigned_short_true);
+COMPILE_ASSERT(IsConvertibleToInteger<int>::value, WTF_IsConvertibleToInteger_int_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned int>::value, WTF_IsConvertibleToInteger_unsigned_int_true);
+COMPILE_ASSERT(IsConvertibleToInteger<long>::value, WTF_IsConvertibleToInteger_long_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned long>::value, WTF_IsConvertibleToInteger_unsigned_long_true);
+COMPILE_ASSERT(IsConvertibleToInteger<long long>::value, WTF_IsConvertibleToInteger_long_long_true);
+COMPILE_ASSERT(IsConvertibleToInteger<unsigned long long>::value, WTF_IsConvertibleToInteger_unsigned_long_long_true);
+#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+COMPILE_ASSERT(IsConvertibleToInteger<wchar_t>::value, WTF_IsConvertibleToInteger_wchar_t_true);
+#endif
+COMPILE_ASSERT(IsConvertibleToInteger<double>::value, WTF_IsConvertibleToInteger_double_true);
+COMPILE_ASSERT(IsConvertibleToInteger<long double>::value, WTF_IsConvertibleToInteger_long_double_true);
+COMPILE_ASSERT(IsConvertibleToInteger<float>::value, WTF_IsConvertibleToInteger_float_true);
+COMPILE_ASSERT(!IsConvertibleToInteger<char*>::value, WTF_IsConvertibleToInteger_char_pointer_false);
+COMPILE_ASSERT(!IsConvertibleToInteger<const char*>::value, WTF_IsConvertibleToInteger_const_char_pointer_false);
+COMPILE_ASSERT(!IsConvertibleToInteger<volatile char*>::value, WTF_IsConvertibleToInteger_volatile_char_pointer_false);
+COMPILE_ASSERT(!IsConvertibleToInteger<IsConvertibleToInteger<bool> >::value, WTF_IsConvertibleToInteger_struct_false);
+
+COMPILE_ASSERT((IsSameType<bool, bool>::value), WTF_IsSameType_bool_true);
+COMPILE_ASSERT((IsSameType<int*, int*>::value), WTF_IsSameType_int_pointer_true);
+COMPILE_ASSERT((!IsSameType<int, int*>::value), WTF_IsSameType_int_int_pointer_false);
+COMPILE_ASSERT((!IsSameType<bool, const bool>::value), WTF_IsSameType_const_change_false);
+COMPILE_ASSERT((!IsSameType<bool, volatile bool>::value), WTF_IsSameType_volatile_change_false);
+
+COMPILE_ASSERT((IsSameType<bool, RemoveConst<const bool>::Type>::value), WTF_test_RemoveConst_const_bool);
+COMPILE_ASSERT((!IsSameType<bool, RemoveConst<volatile bool>::Type>::value), WTF_test_RemoveConst_volatile_bool);
+
+COMPILE_ASSERT((IsSameType<bool, RemoveVolatile<bool>::Type>::value), WTF_test_RemoveVolatile_bool);
+COMPILE_ASSERT((!IsSameType<bool, RemoveVolatile<const bool>::Type>::value), WTF_test_RemoveVolatile_const_bool);
+COMPILE_ASSERT((IsSameType<bool, RemoveVolatile<volatile bool>::Type>::value), WTF_test_RemoveVolatile_volatile_bool);
+
+COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<bool>::Type>::value), WTF_test_RemoveConstVolatile_bool);
+COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<const bool>::Type>::value), WTF_test_RemoveConstVolatile_const_bool);
+COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<volatile bool>::Type>::value), WTF_test_RemoveConstVolatile_volatile_bool);
+COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<const volatile bool>::Type>::value), WTF_test_RemoveConstVolatile_const_volatile_bool);
+
+COMPILE_ASSERT((IsSameType<int, RemovePointer<int>::Type>::value), WTF_Test_RemovePointer_int);
+COMPILE_ASSERT((IsSameType<int, RemovePointer<int*>::Type>::value), WTF_Test_RemovePointer_int_pointer);
+COMPILE_ASSERT((!IsSameType<int, RemovePointer<int**>::Type>::value), WTF_Test_RemovePointer_int_pointer_pointer);
+
+} // namespace WTF
diff --git a/wtf/TypeTraits.h b/wtf/TypeTraits.h
new file mode 100644 (file)
index 0000000..6ce6a3e
--- /dev/null
@@ -0,0 +1,339 @@
+ /*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef TypeTraits_h
+#define TypeTraits_h
+
+#include "Platform.h"
+
+#if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
+#include <type_traits>
+#endif
+
+namespace WTF {
+
+    // The following are provided in this file:
+    //
+    //   IsInteger<T>::value
+    //   IsPod<T>::value, see the definition for a note about its limitations
+    //   IsConvertibleToInteger<T>::value
+    //
+    //   IsSameType<T, U>::value
+    //
+    //   RemovePointer<T>::Type
+    //   RemoveConst<T>::Type
+    //   RemoveVolatile<T>::Type
+    //   RemoveConstVolatile<T>::Type
+    //
+    //   COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do.
+
+    template<typename T> struct IsInteger           { static const bool value = false; };
+    template<> struct IsInteger<bool>               { static const bool value = true; };
+    template<> struct IsInteger<char>               { static const bool value = true; };
+    template<> struct IsInteger<signed char>        { static const bool value = true; };
+    template<> struct IsInteger<unsigned char>      { static const bool value = true; };
+    template<> struct IsInteger<short>              { static const bool value = true; };
+    template<> struct IsInteger<unsigned short>     { static const bool value = true; };
+    template<> struct IsInteger<int>                { static const bool value = true; };
+    template<> struct IsInteger<unsigned int>       { static const bool value = true; };
+    template<> struct IsInteger<long>               { static const bool value = true; };
+    template<> struct IsInteger<unsigned long>      { static const bool value = true; };
+    template<> struct IsInteger<long long>          { static const bool value = true; };
+    template<> struct IsInteger<unsigned long long> { static const bool value = true; };
+#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED)
+    template<> struct IsInteger<wchar_t>            { static const bool value = true; };
+#endif
+
+    // IsPod is misnamed as it doesn't cover all plain old data (pod) types.
+    // Specifically, it doesn't allow for enums or for structs.
+    template <typename T> struct IsPod           { static const bool value = IsInteger<T>::value; };
+    template <> struct IsPod<float>              { static const bool value = true; };
+    template <> struct IsPod<double>             { static const bool value = true; };
+    template <> struct IsPod<long double>        { static const bool value = true; };
+    template <typename P> struct IsPod<P*>       { static const bool value = true; };
+
+    template<typename T> class IsConvertibleToInteger {
+        // Avoid "possible loss of data" warning when using Microsoft's C++ compiler
+        // by not converting int's to doubles.
+        template<bool performCheck, typename U> class IsConvertibleToDouble;
+        template<typename U> class IsConvertibleToDouble<false, U> {
+        public:
+            static const bool value = false;
+        };
+
+        template<typename U> class IsConvertibleToDouble<true, U> {
+            typedef char YesType;
+            struct NoType {
+                char padding[8];
+            };
+
+            static YesType floatCheck(long double);
+            static NoType floatCheck(...);
+            static T& t;
+        public:
+            static const bool value = sizeof(floatCheck(t)) == sizeof(YesType);
+        };
+
+    public:
+        static const bool value = IsInteger<T>::value || IsConvertibleToDouble<!IsInteger<T>::value, T>::value;
+    };
+
+    template <typename T, typename U> struct IsSameType {
+        static const bool value = false;
+    };
+
+    template <typename T> struct IsSameType<T, T> {
+        static const bool value = true;
+    };
+
+    template <typename T> struct RemoveConst {
+        typedef T Type;
+    };
+
+    template <typename T> struct RemoveConst<const T> {
+        typedef T Type;
+    };
+
+    template <typename T> struct RemoveVolatile {
+        typedef T Type;
+    };
+
+    template <typename T> struct RemoveVolatile<volatile T> {
+        typedef T Type;
+    };
+
+    template <typename T> struct RemoveConstVolatile {
+        typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type;
+    };
+
+    template <typename T> struct RemovePointer {
+        typedef T Type;
+    };
+
+    template <typename T> struct RemovePointer<T*> {
+        typedef T Type;
+    };
+
+#if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
+
+    // GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace.
+    // VC10 (VS2010) and later support C++ TR1 type_traits in the std::tr1 namespace.
+    template<typename T> struct HasTrivialConstructor : public std::tr1::has_trivial_constructor<T> { };
+    template<typename T> struct HasTrivialDestructor : public std::tr1::has_trivial_destructor<T> { };
+
+#else
+
+    // This compiler doesn't provide type traits, so we provide basic HasTrivialConstructor
+    // and HasTrivialDestructor definitions. The definitions here include most built-in
+    // scalar types but do not include POD structs and classes. For the intended purposes of
+    // type_traits this results correct but potentially less efficient code.
+    template <typename T, T v>
+    struct IntegralConstant {
+        static const T value = v;
+        typedef T value_type;
+        typedef IntegralConstant<T, v> type;
+    };
+
+    typedef IntegralConstant<bool, true>  true_type;
+    typedef IntegralConstant<bool, false> false_type;
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+    // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor,
+    // but for some unexplained reason it doesn't work on built-in types.
+    template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ };
+    template <typename T> struct HasTrivialDestructor : public IntegralConstant<bool, __has_trivial_destructor(T)>{ };
+#else
+    template <typename T> struct HasTrivialConstructor : public false_type{ };
+    template <typename T> struct HasTrivialDestructor : public false_type{ };
+#endif
+
+    template <typename T> struct HasTrivialConstructor<T*> : public true_type{ };
+    template <typename T> struct HasTrivialDestructor<T*> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<float> : public true_type{ };
+    template <> struct HasTrivialConstructor<const float> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile float> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile float> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<double> : public true_type{ };
+    template <> struct HasTrivialConstructor<const double> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile double> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile double> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<long double> : public true_type{ };
+    template <> struct HasTrivialConstructor<const long double> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile long double> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile long double> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<unsigned char> : public true_type{ };
+    template <> struct HasTrivialConstructor<const unsigned char> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile unsigned char> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile unsigned char> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<unsigned short> : public true_type{ };
+    template <> struct HasTrivialConstructor<const unsigned short> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile unsigned short> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile unsigned short> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<unsigned int> : public true_type{ };
+    template <> struct HasTrivialConstructor<const unsigned int> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile unsigned int> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile unsigned int> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<unsigned long> : public true_type{ };
+    template <> struct HasTrivialConstructor<const unsigned long> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile unsigned long> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile unsigned long> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<unsigned long long> : public true_type{ };
+    template <> struct HasTrivialConstructor<const unsigned long long> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile unsigned long long> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile unsigned long long> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<signed char> : public true_type{ };
+    template <> struct HasTrivialConstructor<const signed char> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile signed char> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile signed char> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<signed short> : public true_type{ };
+    template <> struct HasTrivialConstructor<const signed short> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile signed short> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile signed short> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<signed int> : public true_type{ };
+    template <> struct HasTrivialConstructor<const signed int> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile signed int> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile signed int> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<signed long> : public true_type{ };
+    template <> struct HasTrivialConstructor<const signed long> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile signed long> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile signed long> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<signed long long> : public true_type{ };
+    template <> struct HasTrivialConstructor<const signed long long> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile signed long long> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile signed long long> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<bool> : public true_type{ };
+    template <> struct HasTrivialConstructor<const bool> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile bool> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile bool> : public true_type{ };
+
+    template <> struct HasTrivialConstructor<char> : public true_type{ };
+    template <> struct HasTrivialConstructor<const char> : public true_type{ };
+    template <> struct HasTrivialConstructor<volatile char> : public true_type{ };
+    template <> struct HasTrivialConstructor<const volatile char> : public true_type{ };
+
+    #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
+        template <> struct HasTrivialConstructor<wchar_t> : public true_type{ };
+        template <> struct HasTrivialConstructor<const wchar_t> : public true_type{ };
+        template <> struct HasTrivialConstructor<volatile wchar_t> : public true_type{ };
+        template <> struct HasTrivialConstructor<const volatile wchar_t> : public true_type{ };
+    #endif
+
+    template <> struct HasTrivialDestructor<float> : public true_type{ };
+    template <> struct HasTrivialDestructor<const float> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile float> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile float> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<double> : public true_type{ };
+    template <> struct HasTrivialDestructor<const double> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile double> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile double> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<long double> : public true_type{ };
+    template <> struct HasTrivialDestructor<const long double> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile long double> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile long double> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<unsigned char> : public true_type{ };
+    template <> struct HasTrivialDestructor<const unsigned char> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile unsigned char> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile unsigned char> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<unsigned short> : public true_type{ };
+    template <> struct HasTrivialDestructor<const unsigned short> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile unsigned short> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile unsigned short> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<unsigned int> : public true_type{ };
+    template <> struct HasTrivialDestructor<const unsigned int> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile unsigned int> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile unsigned int> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<unsigned long> : public true_type{ };
+    template <> struct HasTrivialDestructor<const unsigned long> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile unsigned long> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile unsigned long> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<unsigned long long> : public true_type{ };
+    template <> struct HasTrivialDestructor<const unsigned long long> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile unsigned long long> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile unsigned long long> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<signed char> : public true_type{ };
+    template <> struct HasTrivialDestructor<const signed char> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile signed char> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile signed char> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<signed short> : public true_type{ };
+    template <> struct HasTrivialDestructor<const signed short> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile signed short> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile signed short> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<signed int> : public true_type{ };
+    template <> struct HasTrivialDestructor<const signed int> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile signed int> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile signed int> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<signed long> : public true_type{ };
+    template <> struct HasTrivialDestructor<const signed long> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile signed long> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile signed long> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<signed long long> : public true_type{ };
+    template <> struct HasTrivialDestructor<const signed long long> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile signed long long> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile signed long long> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<bool> : public true_type{ };
+    template <> struct HasTrivialDestructor<const bool> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile bool> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile bool> : public true_type{ };
+
+    template <> struct HasTrivialDestructor<char> : public true_type{ };
+    template <> struct HasTrivialDestructor<const char> : public true_type{ };
+    template <> struct HasTrivialDestructor<volatile char> : public true_type{ };
+    template <> struct HasTrivialDestructor<const volatile char> : public true_type{ };
+
+    #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
+        template <> struct HasTrivialDestructor<wchar_t> : public true_type{ };
+        template <> struct HasTrivialDestructor<const wchar_t> : public true_type{ };
+        template <> struct HasTrivialDestructor<volatile wchar_t> : public true_type{ };
+        template <> struct HasTrivialDestructor<const volatile wchar_t> : public true_type{ };
+    #endif
+
+#endif  // __GLIBCXX__, etc.
+
+} // namespace WTF
+
+#endif // TypeTraits_h
diff --git a/wtf/VMTags.h b/wtf/VMTags.h
new file mode 100644 (file)
index 0000000..519f518
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef VMTags_h
+#define VMTags_h
+
+#include <wtf/Platform.h>
+
+// On Mac OS X, the VM subsystem allows tagging memory requested from mmap and vm_map
+// in order to aid tools that inspect system memory use. 
+#if PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER)
+
+#include <mach/vm_statistics.h>
+
+#if defined(VM_MEMORY_JAVASCRIPT_CORE) && defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
+#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_CORE)
+#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE)
+#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
+#else
+#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(63)
+#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY VM_MAKE_TAG(64)
+#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(65)
+#endif // defined(VM_MEMORY_JAVASCRIPT_CORE) && defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
+
+#else // PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER)
+
+#define VM_TAG_FOR_COLLECTOR_MEMORY -1
+#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1
+#define VM_TAG_FOR_REGISTERFILE_MEMORY -1
+
+#endif // PLATFORM(DARWIN) && !defined(BUILDING_ON_TIGER)
+
+#endif // VMTags_h
index 95ff5b37c7c7e83f704884fa5fc89d73ba8e0e0f..f8a5be2798bb4405172eeda933ca282cf45178d4 100644 (file)
 #ifndef WTF_Vector_h
 #define WTF_Vector_h
 
-#include "Assertions.h"
-#include "FastMalloc.h"
+#include "FastAllocBase.h"
 #include "Noncopyable.h"
 #include "NotFound.h"
 #include "VectorTraits.h"
 #include <limits>
-#include <stdlib.h>
-#include <string.h>
 #include <utility>
 
+#if PLATFORM(QT)
+#include <QDataStream>
+#endif
+
 namespace WTF {
 
     using std::min;
@@ -377,7 +378,8 @@ namespace WTF {
         VectorBuffer(size_t capacity)
             : Base(inlineBuffer(), inlineCapacity)
         {
-            allocateBuffer(capacity);
+            if (capacity > inlineCapacity)
+                Base::allocateBuffer(capacity);
         }
 
         ~VectorBuffer()
@@ -389,6 +391,10 @@ namespace WTF {
         {
             if (newCapacity > inlineCapacity)
                 Base::allocateBuffer(newCapacity);
+            else {
+                m_buffer = inlineBuffer();
+                m_capacity = inlineCapacity;
+            }
         }
 
         void deallocateBuffer(T* bufferToDeallocate)
@@ -433,7 +439,7 @@ namespace WTF {
     };
 
     template<typename T, size_t inlineCapacity = 0>
-    class Vector {
+    class Vector : public FastAllocBase {
     private:
         typedef VectorBuffer<T, inlineCapacity> Buffer;
         typedef VectorTypeOperations<T> TypeOperations;
@@ -566,6 +572,32 @@ namespace WTF {
         Buffer m_buffer;
     };
 
+#if PLATFORM(QT)
+    template<typename T>
+    QDataStream& operator<<(QDataStream& stream, const Vector<T>& data)
+    {
+        stream << qint64(data.size());
+        foreach (const T& i, data)
+            stream << i;
+        return stream;
+    }
+
+    template<typename T>
+    QDataStream& operator>>(QDataStream& stream, Vector<T>& data)
+    {
+        data.clear();
+        qint64 count;
+        T item;
+        stream >> count;
+        data.reserveCapacity(count);
+        for (qint64 i = 0; i < count; ++i) {
+            stream >> item;
+            data.append(item);
+        }
+        return stream;
+    }
+#endif
+
     template<typename T, size_t inlineCapacity>
     Vector<T, inlineCapacity>::Vector(const Vector& other)
         : m_size(other.size())
@@ -692,7 +724,7 @@ namespace WTF {
     }
 
     template<typename T, size_t inlineCapacity>
-    void Vector<T, inlineCapacity>::resize(size_t size)
+    inline void Vector<T, inlineCapacity>::resize(size_t size)
     {
         if (size <= m_size)
             TypeOperations::destruct(begin() + size, end());
@@ -790,7 +822,7 @@ namespace WTF {
     }
 
     template<typename T, size_t inlineCapacity> template<typename U>
-    inline void Vector<T, inlineCapacity>::append(const U& val)
+    ALWAYS_INLINE void Vector<T, inlineCapacity>::append(const U& val)
     {
         const U* ptr = &val;
         if (size() == capacity()) {
index 6efe36c58e29b3dcffef3dfda98327683c7f8759..7974b9a77e7544d9dacc8ff6b1fd8d211fb49035 100644 (file)
@@ -22,6 +22,7 @@
 #define WTF_VectorTraits_h
 
 #include "RefPtr.h"
+#include "TypeTraits.h"
 #include <utility>
 #include <memory>
 
@@ -29,24 +30,6 @@ using std::pair;
 
 namespace WTF {
 
-    template <typename T> struct IsPod           { static const bool value = false; };
-    template <> struct IsPod<bool>               { static const bool value = true; };
-    template <> struct IsPod<char>               { static const bool value = true; };
-    template <> struct IsPod<signed char>        { static const bool value = true; };
-    template <> struct IsPod<unsigned char>      { static const bool value = true; };
-    template <> struct IsPod<short>              { static const bool value = true; };
-    template <> struct IsPod<unsigned short>     { static const bool value = true; };
-    template <> struct IsPod<int>                { static const bool value = true; };
-    template <> struct IsPod<unsigned int>       { static const bool value = true; };
-    template <> struct IsPod<long>               { static const bool value = true; };
-    template <> struct IsPod<unsigned long>      { static const bool value = true; };
-    template <> struct IsPod<long long>          { static const bool value = true; };
-    template <> struct IsPod<unsigned long long> { static const bool value = true; };
-    template <> struct IsPod<float>              { static const bool value = true; };
-    template <> struct IsPod<double>             { static const bool value = true; };
-    template <> struct IsPod<long double>        { static const bool value = true; };
-    template <typename P> struct IsPod<P *>      { static const bool value = true; };
-
     template<bool isPod, typename T>
     class VectorTraitsBase;
 
diff --git a/wtf/chromium/ChromiumThreading.h b/wtf/chromium/ChromiumThreading.h
new file mode 100644 (file)
index 0000000..e9b1f39
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+* Copyright (C) 2009 Google Inc. All rights reserved.
+* 
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* 
+*     * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+*     * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+* 
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef ChromiumThreading_h
+#define ChromiumThreading_h
+
+namespace WTF {
+
+    // An interface to the embedding layer, which provides threading support.
+    class ChromiumThreading {
+    public:
+        static void initializeMainThread();
+        static void scheduleDispatchFunctionsOnMainThread();
+    };
+
+} // namespace WTF
+
+#endif // ChromiumThreading_h
diff --git a/wtf/chromium/MainThreadChromium.cpp b/wtf/chromium/MainThreadChromium.cpp
new file mode 100644 (file)
index 0000000..394370f
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+* Copyright (C) 2009 Google Inc. All rights reserved.
+* 
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+* 
+*     * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*     * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+*     * Neither the name of Google Inc. nor the names of its
+* contributors may be used to endorse or promote products derived from
+* this software without specific prior written permission.
+* 
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "config.h"
+#include "MainThread.h"
+
+#include "ChromiumThreading.h"
+
+namespace WTF {
+
+void initializeMainThreadPlatform()
+{
+    ChromiumThreading::initializeMainThread();
+}
+
+void scheduleDispatchFunctionsOnMainThread()
+{
+    ChromiumThreading::scheduleDispatchFunctionsOnMainThread();
+}
+
+} // namespace WTF
+
index c9e8d301357238e2173743e03b3a814c7a080b1a..d75c17a9338daad47395023a10ebaa6eb2a62444 100644 (file)
 #include <wtf/AlwaysInline.h>
 #include <wtf/Assertions.h>
 #include <wtf/FastMalloc.h>
+#include <wtf/Vector.h>
 #include <wtf/Threading.h>
 
+#include <stdio.h>
+
 #if COMPILER(MSVC)
 #pragma warning(disable: 4244)
 #pragma warning(disable: 4245)
@@ -189,13 +192,13 @@ typedef union { double d; uint32_t L[2]; } U;
 #endif
 #else
 #ifdef IEEE_8087
-#define word0(x) ((U*)&x)->L[1]
-#define word1(x) ((U*)&x)->L[0]
+#define word0(x) (x)->L[1]
+#define word1(x) (x)->L[0]
 #else
-#define word0(x) ((U*)&x)->L[0]
-#define word1(x) ((U*)&x)->L[1]
+#define word0(x) (x)->L[0]
+#define word1(x) (x)->L[1]
 #endif
-#define dval(x) ((U*)&x)->d
+#define dval(x) (x)->d
 #endif
 
 /* The following definition of Storeinc is appropriate for MIPS processors.
@@ -253,6 +256,8 @@ typedef union { double d; uint32_t L[2]; } U;
 #define Big0 (Frac_mask1 | Exp_msk1 * (DBL_MAX_EXP + Bias - 1))
 #define Big1 0xffffffff
 
+
+// FIXME: we should remove non-Pack_32 mode since it is unused and unmaintained
 #ifndef Pack_32
 #define Pack_32
 #endif
@@ -275,32 +280,45 @@ typedef union { double d; uint32_t L[2]; } U;
 
 #define Kmax 15
 
-struct Bigint {
-    struct Bigint* next;
-    int k, maxwds, sign, wds;
-    uint32_t x[1];
-};
+struct BigInt {
+    BigInt() : sign(0) { }
+    int sign;
 
-static Bigint* Balloc(int k)
-{
-    int x = 1 << k;
-    Bigint* rv = (Bigint*)fastMalloc(sizeof(Bigint) + (x - 1)*sizeof(uint32_t));
-    rv->k = k;
-    rv->maxwds = x;
-    rv->next = 0;
-    rv->sign = rv->wds = 0;
-
-    return rv;
-}
+    void clear()
+    {
+        sign = 0;
+        m_words.clear();
+    }
+    
+    size_t size() const
+    {
+        return m_words.size();
+    }
 
-static void Bfree(Bigint* v)
-{
-    fastFree(v);
-}
+    void resize(size_t s)
+    {
+        m_words.resize(s);
+    }
+            
+    uint32_t* words()
+    {
+        return m_words.data();
+    }
 
-#define Bcopy(x, y) memcpy((char*)&x->sign, (char*)&y->sign, y->wds * sizeof(int32_t) + 2 * sizeof(int))
+    const uint32_t* words() const
+    {
+        return m_words.data();
+    }
+    
+    void append(uint32_t w)
+    {
+        m_words.append(w);
+    }
+    
+    Vector<uint32_t, 16> m_words;
+};
 
-static Bigint* multadd(Bigint* b, int m, int a)    /* multiply by m and add a */
+static void multadd(BigInt& b, int m, int a)    /* multiply by m and add a */
 {
 #ifdef USE_LONG_LONG
     unsigned long long carry;
@@ -308,8 +326,8 @@ static Bigint* multadd(Bigint* b, int m, int a)    /* multiply by m and add a */
     uint32_t carry;
 #endif
 
-    int wds = b->wds;
-    uint32_t* x = b->x;
+    int wds = b.size();
+    uint32_t* x = b.words();
     int i = 0;
     carry = a;
     do {
@@ -332,20 +350,11 @@ static Bigint* multadd(Bigint* b, int m, int a)    /* multiply by m and add a */
 #endif
     } while (++i < wds);
 
-    if (carry) {
-        if (wds >= b->maxwds) {
-            Bigint* b1 = Balloc(b->k + 1);
-            Bcopy(b1, b);
-            Bfree(b);
-            b = b1;
-        }
-        b->x[wds++] = (uint32_t)carry;
-        b->wds = wds;
-    }
-    return b;
+    if (carry)
+        b.append((uint32_t)carry);
 }
 
-static Bigint* s2b(const char* s, int nd0, int nd, uint32_t y9)
+static void s2b(BigInt& b, const char* s, int nd0, int nd, uint32_t y9)
 {
     int k;
     int32_t y;
@@ -353,27 +362,26 @@ static Bigint* s2b(const char* s, int nd0, int nd, uint32_t y9)
 
     for (k = 0, y = 1; x > y; y <<= 1, k++) { }
 #ifdef Pack_32
-    Bigint* b = Balloc(k);
-    b->x[0] = y9;
-    b->wds = 1;
+    b.sign = 0;
+    b.resize(1);
+    b.words()[0] = y9;
 #else
-    Bigint* b = Balloc(k + 1);
-    b->x[0] = y9 & 0xffff;
-    b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+    b.sign = 0;
+    b.resize((b->x[1] = y9 >> 16) ? 2 : 1);
+    b.words()[0] = y9 & 0xffff;
 #endif
 
     int i = 9;
     if (9 < nd0) {
         s += 9;
         do {
-            b = multadd(b, 10, *s++ - '0');
+            multadd(b, 10, *s++ - '0');
         } while (++i < nd0);
         s++;
     } else
         s += 10;
     for (; i < nd; i++)
-        b = multadd(b, 10, *s++ - '0');
-    return b;
+        multadd(b, 10, *s++ - '0');
 }
 
 static int hi0bits(uint32_t x)
@@ -446,21 +454,21 @@ static int lo0bits (uint32_t* y)
     return k;
 }
 
-static Bigint* i2b(int i)
+static void i2b(BigInt& b, int i)
 {
-    Bigint* b;
-
-    b = Balloc(1);
-    b->x[0] = i;
-    b->wds = 1;
-    return b;
+    b.sign = 0;
+    b.resize(1);
+    b.words()[0] = i;
 }
 
-static Bigint* mult(Bigint* a, Bigint* b)
+static void mult(BigInt& aRef, const BigInt& bRef)
 {
-    Bigint* c;
-    int k, wa, wb, wc;
-    uint32_t *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+    const BigInt* a = &aRef;
+    const BigInt* b = &bRef;
+    BigInt c;
+    int wa, wb, wc;
+    const uint32_t *x = 0, *xa, *xb, *xae, *xbe;
+    uint32_t *xc, *xc0;
     uint32_t y;
 #ifdef USE_LONG_LONG
     unsigned long long carry, z;
@@ -468,25 +476,24 @@ static Bigint* mult(Bigint* a, Bigint* b)
     uint32_t carry, z;
 #endif
 
-    if (a->wds < b->wds) {
-        c = a;
+    if (a->size() < b->size()) {
+        const BigInt* tmp = a;
         a = b;
-        b = c;
+        b = tmp;
     }
-    k = a->k;
-    wa = a->wds;
-    wb = b->wds;
+    
+    wa = a->size();
+    wb = b->size();
     wc = wa + wb;
-    if (wc > a->maxwds)
-        k++;
-    c = Balloc(k);
-    for (x = c->x, xa = x + wc; x < xa; x++)
-        *x = 0;
-    xa = a->x;
+    c.resize(wc);
+
+    for (xc = c.words(), xa = xc + wc; xc < xa; xc++)
+        *xc = 0;
+    xa = a->words();
     xae = xa + wa;
-    xb = b->x;
+    xb = b->words();
     xbe = xb + wb;
-    xc0 = c->x;
+    xc0 = c.words();
 #ifdef USE_LONG_LONG
     for (; xb < xbe; xc0++) {
         if ((y = *xb++)) {
@@ -548,33 +555,43 @@ static Bigint* mult(Bigint* a, Bigint* b)
     }
 #endif
 #endif
-    for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) { }
-    c->wds = wc;
-    return c;
+    for (xc0 = c.words(), xc = xc0 + wc; wc > 0 && !*--xc; --wc) { }
+    c.resize(wc);
+    aRef = c;
 }
 
-static Bigint* p5s;
+struct P5Node {
+    BigInt val;
+    P5Node* next;
+};
+    
+static P5Node* p5s;
 static int p5s_count;
 
-static Bigint* pow5mult(Bigint* b, int k)
+static ALWAYS_INLINE void pow5mult(BigInt& b, int k)
 {
     static int p05[3] = { 5, 25, 125 };
 
     if (int i = k & 3)
-        b = multadd(b, p05[i - 1], 0);
+        multadd(b, p05[i - 1], 0);
 
     if (!(k >>= 2))
-        return b;
+        return;
 
 #if ENABLE(JSC_MULTIPLE_THREADS)
     s_dtoaP5Mutex->lock();
 #endif
-    Bigint* p5 = p5s;
+    P5Node* p5 = p5s;
+
     if (!p5) {
         /* first time */
-        p5 = p5s = i2b(625);
+        p5 = new P5Node;
+        i2b(p5->val, 625);
+        p5->next = 0;
+        p5s = p5;
         p5s_count = 1;
     }
+
     int p5s_count_local = p5s_count;
 #if ENABLE(JSC_MULTIPLE_THREADS)
     s_dtoaP5Mutex->unlock();
@@ -582,11 +599,9 @@ static Bigint* pow5mult(Bigint* b, int k)
     int p5s_used = 0;
 
     for (;;) {
-        if (k & 1) {
-            Bigint* b1 = mult(b, p5);
-            Bfree(b);
-            b = b1;
-        }
+        if (k & 1)
+            mult(b, p5->val);
+
         if (!(k >>= 1))
             break;
 
@@ -596,7 +611,10 @@ static Bigint* pow5mult(Bigint* b, int k)
 #endif
             if (p5s_used == p5s_count) {
                 ASSERT(!p5->next);
-                p5->next = mult(p5, p5);
+                p5->next = new P5Node;
+                p5->next->next = 0;
+                p5->next->val = p5->val;
+                mult(p5->next->val, p5->next->val);
                 ++p5s_count;
             }
             
@@ -607,33 +625,30 @@ static Bigint* pow5mult(Bigint* b, int k)
         }
         p5 = p5->next;
     }
-
-    return b;
 }
 
-static Bigint* lshift(Bigint* b, int k)
+static ALWAYS_INLINE void lshift(BigInt& b, int k)
 {
-    Bigint* result = b;
-
 #ifdef Pack_32
     int n = k >> 5;
 #else
     int n = k >> 4;
 #endif
 
-    int k1 = b->k;
-    int n1 = n + b->wds + 1;
-    for (int i = b->maxwds; n1 > i; i <<= 1)
-        k1++;
-    if (b->k < k1)
-        result = Balloc(k1);
+    int origSize = b.size();
+    int n1 = n + origSize + 1;
 
-    const uint32_t* srcStart = b->x;
-    uint32_t* dstStart = result->x;
-    const uint32_t* src = srcStart + b->wds - 1;
+    if (k &= 0x1f)
+        b.resize(b.size() + n + 1);
+    else
+        b.resize(b.size() + n);
+
+    const uint32_t* srcStart = b.words();
+    uint32_t* dstStart = b.words();
+    const uint32_t* src = srcStart + origSize - 1;
     uint32_t* dst = dstStart + n1 - 1;
 #ifdef Pack_32
-    if (k &= 0x1f) {
+    if (k) {
         uint32_t hiSubword = 0;
         int s = 32 - k;
         for (; src >= srcStart; --src) {
@@ -642,7 +657,8 @@ static Bigint* lshift(Bigint* b, int k)
         }
         *dst = hiSubword;
         ASSERT(dst == dstStart + n);
-        result->wds = b->wds + n + (result->x[n1 - 1] != 0);
+
+        b.resize(origSize + n + (b.words()[n1 - 1] != 0));
     }
 #else
     if (k &= 0xf) {
@@ -661,30 +677,27 @@ static Bigint* lshift(Bigint* b, int k)
         do {
             *--dst = *src--;
         } while (src >= srcStart);
-        result->wds = b->wds + n;
     }
     for (dst = dstStart + n; dst != dstStart; )
         *--dst = 0;
 
-    if (result != b)
-        Bfree(b);
-    return result;
+    ASSERT(b.size() <= 1 || b.words()[b.size() - 1]);
 }
 
-static int cmp(Bigint* a, Bigint* b)
+static int cmp(const BigInt& a, const BigInt& b)
 {
-    uint32_t *xa, *xa0, *xb, *xb0;
+    const uint32_t *xa, *xa0, *xb, *xb0;
     int i, j;
 
-    i = a->wds;
-    j = b->wds;
-    ASSERT(i <= 1 || a->x[i - 1]);
-    ASSERT(j <= 1 || b->x[j - 1]);
+    i = a.size();
+    j = b.size();
+    ASSERT(i <= 1 || a.words()[i - 1]);
+    ASSERT(j <= 1 || b.words()[j - 1]);
     if (i -= j)
         return i;
-    xa0 = a->x;
+    xa0 = a.words();
     xa = xa0 + j;
-    xb0 = b->x;
+    xb0 = b.words();
     xb = xb0 + j;
     for (;;) {
         if (*--xa != *--xb)
@@ -695,35 +708,38 @@ static int cmp(Bigint* a, Bigint* b)
     return 0;
 }
 
-static Bigint* diff(Bigint* a, Bigint* b)
+static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef)
 {
-    Bigint* c;
+    const BigInt* a = &aRef;
+    const BigInt* b = &bRef;
     int i, wa, wb;
-    uint32_t *xa, *xae, *xb, *xbe, *xc;
+    uint32_t *xc;
 
-    i = cmp(a,b);
+    i = cmp(*a, *b);
     if (!i) {
-        c = Balloc(0);
-        c->wds = 1;
-        c->x[0] = 0;
-        return c;
+        c.sign = 0;
+        c.resize(1);
+        c.words()[0] = 0;
+        return;
     }
     if (i < 0) {
-        c = a;
+        const BigInt* tmp = a;
         a = b;
-        b = c;
+        b = tmp;
         i = 1;
     } else
         i = 0;
-    c = Balloc(a->k);
-    c->sign = i;
-    wa = a->wds;
-    xa = a->x;
-    xae = xa + wa;
-    wb = b->wds;
-    xb = b->x;
-    xbe = xb + wb;
-    xc = c->x;
+
+    wa = a->size();
+    const uint32_t* xa = a->words();
+    const uint32_t* xae = xa + wa;
+    wb = b->size();
+    const uint32_t* xb = b->words();
+    const uint32_t* xbe = xb + wb;
+
+    c.resize(wa);
+    c.sign = i;
+    xc = c.words();
 #ifdef USE_LONG_LONG
     unsigned long long borrow = 0;
     do {
@@ -768,14 +784,13 @@ static Bigint* diff(Bigint* a, Bigint* b)
 #endif
     while (!*--xc)
         wa--;
-    c->wds = wa;
-    return c;
+    c.resize(wa);
 }
 
-static double ulp(double x)
+static double ulp(U *x)
 {
     register int32_t L;
-    double a;
+    U u;
 
     L = (word0(x) & Exp_mask) - (P - 1) * Exp_msk1;
 #ifndef Avoid_Underflow
@@ -783,57 +798,57 @@ static double ulp(double x)
     if (L > 0) {
 #endif
 #endif
-        word0(a) = L;
-        word1(a) = 0;
+        word0(&u) = L;
+        word1(&u) = 0;
 #ifndef Avoid_Underflow
 #ifndef Sudden_Underflow
     } else {
         L = -L >> Exp_shift;
         if (L < Exp_shift) {
-            word0(a) = 0x80000 >> L;
-            word1(a) = 0;
+            word0(&u) = 0x80000 >> L;
+            word1(&u) = 0;
         } else {
-            word0(a) = 0;
+            word0(&u) = 0;
             L -= Exp_shift;
-            word1(a) = L >= 31 ? 1 : 1 << 31 - L;
+            word1(&u) = L >= 31 ? 1 : 1 << 31 - L;
         }
     }
 #endif
 #endif
-    return dval(a);
+    return dval(&u);
 }
 
-static double b2d(Bigint* a, int* e)
+static double b2d(const BigInt& a, int* e)
 {
-    uint32_t* xa;
-    uint32_t* xa0;
+    const uint32_t* xa;
+    const uint32_t* xa0;
     uint32_t w;
     uint32_t y;
     uint32_t z;
     int k;
-    double d;
+    U d;
 
-#define d0 word0(d)
-#define d1 word1(d)
+#define d0 word0(&d)
+#define d1 word1(&d)
 
-    xa0 = a->x;
-    xa = xa0 + a->wds;
+    xa0 = a.words();
+    xa = xa0 + a.size();
     y = *--xa;
     ASSERT(y);
     k = hi0bits(y);
     *e = 32 - k;
 #ifdef Pack_32
     if (k < Ebits) {
-        d0 = Exp_1 | y >> Ebits - k;
+        d0 = Exp_1 | (y >> (Ebits - k));
         w = xa > xa0 ? *--xa : 0;
-        d1 = y << (32 - Ebits) + k | w >> Ebits - k;
+        d1 = (y << (32 - Ebits + k)) | (w >> (Ebits - k));
         goto ret_d;
     }
     z = xa > xa0 ? *--xa : 0;
     if (k -= Ebits) {
-        d0 = Exp_1 | y << k | z >> 32 - k;
+        d0 = Exp_1 | (y << k) | (z >> (32 - k));
         y = xa > xa0 ? *--xa : 0;
-        d1 = z << k | y >> 32 - k;
+        d1 = (z << k) | (y >> (32 - k));
     } else {
         d0 = Exp_1 | y;
         d1 = z;
@@ -857,12 +872,11 @@ static double b2d(Bigint* a, int* e)
 ret_d:
 #undef d0
 #undef d1
-    return dval(d);
+    return dval(&d);
 }
 
-static Bigint* d2b(double d, int* e, int* bits)
+static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits)
 {
-    Bigint* b;
     int de, k;
     uint32_t *x, y, z;
 #ifndef Sudden_Underflow
@@ -871,12 +885,13 @@ static Bigint* d2b(double d, int* e, int* bits)
 #define d0 word0(d)
 #define d1 word1(d)
 
+    b.sign = 0;
 #ifdef Pack_32
-    b = Balloc(1);
+    b.resize(1);
 #else
-    b = Balloc(2);
+    b.resize(2);
 #endif
-    x = b->x;
+    x = b.words();
 
     z = d0 & Frac_mask;
     d0 &= 0x7fffffff;    /* clear sign bit, which we ignore */
@@ -889,21 +904,25 @@ static Bigint* d2b(double d, int* e, int* bits)
 #ifdef Pack_32
     if ((y = d1)) {
         if ((k = lo0bits(&y))) {
-            x[0] = y | z << 32 - k;
+            x[0] = y | (z << (32 - k));
             z >>= k;
         } else
             x[0] = y;
+            if (z) {
+                b.resize(2);
+                x[1] = z;
+            }
+
 #ifndef Sudden_Underflow
-        i =
+        i = b.size();
 #endif
-            b->wds = (x[1] = z) ? 2 : 1;
     } else {
         k = lo0bits(&z);
         x[0] = z;
 #ifndef Sudden_Underflow
-        i =
+        i = 1;
 #endif
-            b->wds = 1;
+        b.resize(1);
         k += 32;
     }
 #else
@@ -941,7 +960,7 @@ static Bigint* d2b(double d, int* e, int* bits)
         k += 32;
     } while (!x[i])
         --i;
-    b->wds = i + 1;
+    b->resize(i + 1);
 #endif
 #ifndef Sudden_Underflow
     if (de) {
@@ -958,30 +977,29 @@ static Bigint* d2b(double d, int* e, int* bits)
 #endif
     }
 #endif
-    return b;
 }
 #undef d0
 #undef d1
 
-static double ratio(Bigint* a, Bigint* b)
+static double ratio(const BigInt& a, const BigInt& b)
 {
-    double da, db;
+    U da, db;
     int k, ka, kb;
 
-    dval(da) = b2d(a, &ka);
-    dval(db) = b2d(b, &kb);
+    dval(&da) = b2d(a, &ka);
+    dval(&db) = b2d(b, &kb);
 #ifdef Pack_32
-    k = ka - kb + 32 * (a->wds - b->wds);
+    k = ka - kb + 32 * (a.size() - b.size());
 #else
-    k = ka - kb + 16 * (a->wds - b->wds);
+    k = ka - kb + 16 * (a.size() - b.size());
 #endif
     if (k > 0)
-        word0(da) += k * Exp_msk1;
+        word0(&da) += k * Exp_msk1;
     else {
         k = -k;
-        word0(db) += k * Exp_msk1;
+        word0(&db) += k * Exp_msk1;
     }
-    return dval(da) / dval(db);
+    return dval(&da) / dval(&db);
 }
 
 static const double tens[] = {
@@ -1031,7 +1049,7 @@ static int match(const char** sp, const char* t)
 }
 
 #ifndef No_Hex_NaN
-static void hexnan(double* rvp, const char** sp)
+static void hexnan(U* rvp, const char** sp)
 {
     uint32_t c, x[2];
     const char* s;
@@ -1070,8 +1088,8 @@ static void hexnan(double* rvp, const char** sp)
         x[1] = (x[1] << 4) | c;
     }
     if ((x[0] &= 0xfffff) || x[1]) {
-        word0(*rvp) = Exp_mask | x[0];
-        word1(*rvp) = x[1];
+        word0(rvp) = Exp_mask | x[0];
+        word1(rvp) = x[1];
     }
 }
 #endif /*No_Hex_NaN*/
@@ -1085,16 +1103,17 @@ double strtod(const char* s00, char** se)
     int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
          e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
     const char *s, *s0, *s1;
-    double aadj, aadj1, adj, rv, rv0;
+    double aadj, aadj1;
+    U aadj2, adj, rv, rv0;
     int32_t L;
     uint32_t y, z;
-    Bigint *bb = NULL, *bb1 = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL;
+    BigInt bb, bb1, bd, bd0, bs, delta;
 #ifdef SET_INEXACT
     int inexact, oldinexact;
 #endif
 
     sign = nz0 = nz = 0;
-    dval(rv) = 0.;
+    dval(&rv) = 0;
     for (s = s00; ; s++)
         switch (*s) {
             case '-':
@@ -1209,16 +1228,16 @@ dig_done:
                         --s;
                         if (!match(&s,"inity"))
                             ++s;
-                        word0(rv) = 0x7ff00000;
-                        word1(rv) = 0;
+                        word0(&rv) = 0x7ff00000;
+                        word1(&rv) = 0;
                         goto ret;
                     }
                     break;
                 case 'n':
                 case 'N':
                     if (match(&s, "an")) {
-                        word0(rv) = NAN_WORD0;
-                        word1(rv) = NAN_WORD1;
+                        word0(&rv) = NAN_WORD0;
+                        word1(&rv) = NAN_WORD1;
 #ifndef No_Hex_NaN
                         if (*s == '(') /*)*/
                             hexnan(&rv, &s);
@@ -1243,21 +1262,20 @@ ret0:
     if (!nd0)
         nd0 = nd;
     k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
-    dval(rv) = y;
+    dval(&rv) = y;
     if (k > 9) {
 #ifdef SET_INEXACT
         if (k > DBL_DIG)
             oldinexact = get_inexact();
 #endif
-        dval(rv) = tens[k - 9] * dval(rv) + z;
+        dval(&rv) = tens[k - 9] * dval(&rv) + z;
     }
-    bd0 = 0;
     if (nd <= DBL_DIG && Flt_Rounds == 1) {
         if (!e)
             goto ret;
         if (e > 0) {
             if (e <= Ten_pmax) {
-                /* rv = */ rounded_product(dval(rv), tens[e]);
+                /* rv = */ rounded_product(dval(&rv), tens[e]);
                 goto ret;
             }
             i = DBL_DIG - nd;
@@ -1266,14 +1284,14 @@ ret0:
                  * this for larger i values.
                  */
                 e -= i;
-                dval(rv) *= tens[i];
-                /* rv = */ rounded_product(dval(rv), tens[e]);
+                dval(&rv) *= tens[i];
+                /* rv = */ rounded_product(dval(&rv), tens[e]);
                 goto ret;
             }
         }
 #ifndef Inaccurate_Divide
         else if (e >= -Ten_pmax) {
-            /* rv = */ rounded_quotient(dval(rv), tens[-e]);
+            /* rv = */ rounded_quotient(dval(&rv), tens[-e]);
             goto ret;
         }
 #endif
@@ -1293,7 +1311,7 @@ ret0:
 
     if (e1 > 0) {
         if ((i = e1 & 15))
-            dval(rv) *= tens[i];
+            dval(&rv) *= tens[i];
         if (e1 &= ~15) {
             if (e1 > DBL_MAX_10_EXP) {
 ovfl:
@@ -1301,38 +1319,36 @@ ovfl:
                 errno = ERANGE;
 #endif
                 /* Can't trust HUGE_VAL */
-                word0(rv) = Exp_mask;
-                word1(rv) = 0;
+                word0(&rv) = Exp_mask;
+                word1(&rv) = 0;
 #ifdef SET_INEXACT
                 /* set overflow bit */
-                dval(rv0) = 1e300;
-                dval(rv0) *= dval(rv0);
+                dval(&rv0) = 1e300;
+                dval(&rv0) *= dval(&rv0);
 #endif
-                if (bd0)
-                    goto retfree;
                 goto ret;
             }
             e1 >>= 4;
             for (j = 0; e1 > 1; j++, e1 >>= 1)
                 if (e1 & 1)
-                    dval(rv) *= bigtens[j];
+                    dval(&rv) *= bigtens[j];
         /* The last multiplication could overflow. */
-            word0(rv) -= P * Exp_msk1;
-            dval(rv) *= bigtens[j];
-            if ((z = word0(rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - P))
+            word0(&rv) -= P * Exp_msk1;
+            dval(&rv) *= bigtens[j];
+            if ((z = word0(&rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - P))
                 goto ovfl;
             if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) {
                 /* set to largest number */
                 /* (Can't trust DBL_MAX) */
-                word0(rv) = Big0;
-                word1(rv) = Big1;
+                word0(&rv) = Big0;
+                word1(&rv) = Big1;
             } else
-                word0(rv) += P * Exp_msk1;
+                word0(&rv) += P * Exp_msk1;
         }
     } else if (e1 < 0) {
         e1 = -e1;
         if ((i = e1 & 15))
-            dval(rv) /= tens[i];
+            dval(&rv) /= tens[i];
         if (e1 >>= 4) {
             if (e1 >= 1 << n_bigtens)
                 goto undfl;
@@ -1341,42 +1357,40 @@ ovfl:
                 scale = 2 * P;
             for (j = 0; e1 > 0; j++, e1 >>= 1)
                 if (e1 & 1)
-                    dval(rv) *= tinytens[j];
-            if (scale && (j = (2 * P) + 1 - ((word0(rv) & Exp_mask) >> Exp_shift)) > 0) {
+                    dval(&rv) *= tinytens[j];
+            if (scale && (j = (2 * P) + 1 - ((word0(&rv) & Exp_mask) >> Exp_shift)) > 0) {
                 /* scaled rv is denormal; zap j low bits */
                 if (j >= 32) {
-                    word1(rv) = 0;
+                    word1(&rv) = 0;
                     if (j >= 53)
-                       word0(rv) = (P + 2) * Exp_msk1;
+                       word0(&rv) = (P + 2) * Exp_msk1;
                     else
-                       word0(rv) &= 0xffffffff << j - 32;
+                       word0(&rv) &= 0xffffffff << (j - 32);
                 } else
-                    word1(rv) &= 0xffffffff << j;
+                    word1(&rv) &= 0xffffffff << j;
             }
 #else
             for (j = 0; e1 > 1; j++, e1 >>= 1)
                 if (e1 & 1)
-                    dval(rv) *= tinytens[j];
+                    dval(&rv) *= tinytens[j];
             /* The last multiplication could underflow. */
-            dval(rv0) = dval(rv);
-            dval(rv) *= tinytens[j];
-            if (!dval(rv)) {
-                dval(rv) = 2. * dval(rv0);
-                dval(rv) *= tinytens[j];
+            dval(&rv0) = dval(&rv);
+            dval(&rv) *= tinytens[j];
+            if (!dval(&rv)) {
+                dval(&rv) = 2. * dval(&rv0);
+                dval(&rv) *= tinytens[j];
 #endif
-                if (!dval(rv)) {
+                if (!dval(&rv)) {
 undfl:
-                    dval(rv) = 0.;
+                    dval(&rv) = 0.;
 #ifndef NO_ERRNO
                     errno = ERANGE;
 #endif
-                    if (bd0)
-                        goto retfree;
                     goto ret;
                 }
 #ifndef Avoid_Underflow
-                word0(rv) = Tiny0;
-                word1(rv) = Tiny1;
+                word0(&rv) = Tiny0;
+                word1(&rv) = Tiny1;
                 /* The refinement below will clean
                  * this approximation up.
                  */
@@ -1389,13 +1403,12 @@ undfl:
 
     /* Put digits into bd: true value = bd * 10^e */
 
-    bd0 = s2b(s0, nd0, nd, y);
+    s2b(bd0, s0, nd0, nd, y);
 
     for (;;) {
-        bd = Balloc(bd0->k);
-        Bcopy(bd, bd0);
-        bb = d2b(dval(rv), &bbe, &bbbits);    /* rv = bb * 2^bbe */
-        bs = i2b(1);
+        bd = bd0;
+        d2b(bb, &rv, &bbe, &bbbits);    /* rv = bb * 2^bbe */
+        i2b(bs, 1);
 
         if (e >= 0) {
             bb2 = bb5 = 0;
@@ -1442,49 +1455,47 @@ undfl:
             bs2 -= i;
         }
         if (bb5 > 0) {
-            bs = pow5mult(bs, bb5);
-            bb1 = mult(bs, bb);
-            Bfree(bb);
-            bb = bb1;
+            pow5mult(bs, bb5);
+            mult(bb, bs);
         }
         if (bb2 > 0)
-            bb = lshift(bb, bb2);
+            lshift(bb, bb2);
         if (bd5 > 0)
-            bd = pow5mult(bd, bd5);
+            pow5mult(bd, bd5);
         if (bd2 > 0)
-            bd = lshift(bd, bd2);
+            lshift(bd, bd2);
         if (bs2 > 0)
-            bs = lshift(bs, bs2);
-        delta = diff(bb, bd);
-        dsign = delta->sign;
-        delta->sign = 0;
+            lshift(bs, bs2);
+        diff(delta, bb, bd);
+        dsign = delta.sign;
+        delta.sign = 0;
         i = cmp(delta, bs);
 
         if (i < 0) {
             /* Error is less than half an ulp -- check for
              * special case of mantissa a power of two.
              */
-            if (dsign || word1(rv) || word0(rv) & Bndry_mask
+            if (dsign || word1(&rv) || word0(&rv) & Bndry_mask
 #ifdef Avoid_Underflow
-             || (word0(rv) & Exp_mask) <= (2 * P + 1) * Exp_msk1
+             || (word0(&rv) & Exp_mask) <= (2 * P + 1) * Exp_msk1
 #else
-             || (word0(rv) & Exp_mask) <= Exp_msk1
+             || (word0(&rv) & Exp_mask) <= Exp_msk1
 #endif
                 ) {
 #ifdef SET_INEXACT
-                if (!delta->x[0] && delta->wds <= 1)
+                if (!delta->words()[0] && delta->size() <= 1)
                     inexact = 0;
 #endif
                 break;
             }
-            if (!delta->x[0] && delta->wds <= 1) {
+            if (!delta.words()[0] && delta.size() <= 1) {
                 /* exact result */
 #ifdef SET_INEXACT
                 inexact = 0;
 #endif
                 break;
             }
-            delta = lshift(delta,Log2P);
+            lshift(delta, Log2P);
             if (cmp(delta, bs) > 0)
                 goto drop_down;
             break;
@@ -1492,26 +1503,26 @@ undfl:
         if (i == 0) {
             /* exactly half-way between */
             if (dsign) {
-                if ((word0(rv) & Bndry_mask1) == Bndry_mask1
-                 &&  word1(rv) == (
+                if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
+                 &&  word1(&rv) == (
 #ifdef Avoid_Underflow
-            (scale && (y = word0(rv) & Exp_mask) <= 2 * P * Exp_msk1)
+            (scale && (y = word0(&rv) & Exp_mask) <= 2 * P * Exp_msk1)
         ? (0xffffffff & (0xffffffff << (2 * P + 1 - (y >> Exp_shift)))) :
 #endif
                            0xffffffff)) {
                     /*boundary case -- increment exponent*/
-                    word0(rv) = (word0(rv) & Exp_mask) + Exp_msk1;
-                    word1(rv) = 0;
+                    word0(&rv) = (word0(&rv) & Exp_mask) + Exp_msk1;
+                    word1(&rv) = 0;
 #ifdef Avoid_Underflow
                     dsign = 0;
 #endif
                     break;
                 }
-            } else if (!(word0(rv) & Bndry_mask) && !word1(rv)) {
+            } else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
 drop_down:
                 /* boundary case -- decrement exponent */
 #ifdef Sudden_Underflow /*{{*/
-                L = word0(rv) & Exp_mask;
+                L = word0(&rv) & Exp_mask;
 #ifdef Avoid_Underflow
                 if (L <= (scale ? (2 * P + 1) * Exp_msk1 : Exp_msk1))
 #else
@@ -1522,7 +1533,7 @@ drop_down:
 #else /*Sudden_Underflow}{*/
 #ifdef Avoid_Underflow
                 if (scale) {
-                    L = word0(rv) & Exp_mask;
+                    L = word0(&rv) & Exp_mask;
                     if (L <= (2 * P + 1) * Exp_msk1) {
                         if (L > (P + 2) * Exp_msk1)
                             /* round even ==> */
@@ -1533,20 +1544,20 @@ drop_down:
                     }
                 }
 #endif /*Avoid_Underflow*/
-                L = (word0(rv) & Exp_mask) - Exp_msk1;
+                L = (word0(&rv) & Exp_mask) - Exp_msk1;
 #endif /*Sudden_Underflow}}*/
-                word0(rv) = L | Bndry_mask1;
-                word1(rv) = 0xffffffff;
+                word0(&rv) = L | Bndry_mask1;
+                word1(&rv) = 0xffffffff;
                 break;
             }
-            if (!(word1(rv) & LSB))
+            if (!(word1(&rv) & LSB))
                 break;
             if (dsign)
-                dval(rv) += ulp(dval(rv));
+                dval(&rv) += ulp(&rv);
             else {
-                dval(rv) -= ulp(dval(rv));
+                dval(&rv) -= ulp(&rv);
 #ifndef Sudden_Underflow
-                if (!dval(rv))
+                if (!dval(&rv))
                     goto undfl;
 #endif
             }
@@ -1558,9 +1569,9 @@ drop_down:
         if ((aadj = ratio(delta, bs)) <= 2.) {
             if (dsign)
                 aadj = aadj1 = 1.;
-            else if (word1(rv) || word0(rv) & Bndry_mask) {
+            else if (word1(&rv) || word0(&rv) & Bndry_mask) {
 #ifndef Sudden_Underflow
-                if (word1(rv) == Tiny1 && !word0(rv))
+                if (word1(&rv) == Tiny1 && !word0(&rv))
                     goto undfl;
 #endif
                 aadj = 1.;
@@ -1592,23 +1603,23 @@ drop_down:
                 aadj1 += 0.5;
 #endif /*Check_FLT_ROUNDS*/
         }
-        y = word0(rv) & Exp_mask;
+        y = word0(&rv) & Exp_mask;
 
         /* Check for overflow */
 
         if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) {
-            dval(rv0) = dval(rv);
-            word0(rv) -= P * Exp_msk1;
-            adj = aadj1 * ulp(dval(rv));
-            dval(rv) += adj;
-            if ((word0(rv) & Exp_mask) >= Exp_msk1 * (DBL_MAX_EXP + Bias - P)) {
-                if (word0(rv0) == Big0 && word1(rv0) == Big1)
+            dval(&rv0) = dval(&rv);
+            word0(&rv) -= P * Exp_msk1;
+            adj.d = aadj1 * ulp(&rv);
+            dval(&rv) += adj.d;
+            if ((word0(&rv) & Exp_mask) >= Exp_msk1 * (DBL_MAX_EXP + Bias - P)) {
+                if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
                     goto ovfl;
-                word0(rv) = Big0;
-                word1(rv) = Big1;
+                word0(&rv) = Big0;
+                word1(&rv) = Big1;
                 goto cont;
             } else
-                word0(rv) += P * Exp_msk1;
+                word0(&rv) += P * Exp_msk1;
         } else {
 #ifdef Avoid_Underflow
             if (scale && y <= 2 * P * Exp_msk1) {
@@ -1618,30 +1629,32 @@ drop_down:
                     aadj = z;
                     aadj1 = dsign ? aadj : -aadj;
                 }
-                word0(aadj1) += (2 * P + 1) * Exp_msk1 - y;
+                dval(&aadj2) = aadj1;
+                word0(&aadj2) += (2 * P + 1) * Exp_msk1 - y;
+                aadj1 = dval(&aadj2);
             }
-            adj = aadj1 * ulp(dval(rv));
-            dval(rv) += adj;
+            adj.d = aadj1 * ulp(&rv);
+            dval(&rv) += adj.d;
 #else
 #ifdef Sudden_Underflow
-            if ((word0(rv) & Exp_mask) <= P * Exp_msk1) {
-                dval(rv0) = dval(rv);
-                word0(rv) += P * Exp_msk1;
-                adj = aadj1 * ulp(dval(rv));
-                dval(rv) += adj;
-                if ((word0(rv) & Exp_mask) <= P * Exp_msk1)
+            if ((word0(&rv) & Exp_mask) <= P * Exp_msk1) {
+                dval(&rv0) = dval(&rv);
+                word0(&rv) += P * Exp_msk1;
+                adj.d = aadj1 * ulp(&rv);
+                dval(&rv) += adj.d;
+                if ((word0(&rv) & Exp_mask) <= P * Exp_msk1)
                 {
-                    if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1)
+                    if (word0(&rv0) == Tiny0 && word1(&rv0) == Tiny1)
                         goto undfl;
-                    word0(rv) = Tiny0;
-                    word1(rv) = Tiny1;
+                    word0(&rv) = Tiny0;
+                    word1(&rv) = Tiny1;
                     goto cont;
                 }
                 else
-                    word0(rv) -= P * Exp_msk1;
+                    word0(&rv) -= P * Exp_msk1;
             } else {
-                adj = aadj1 * ulp(dval(rv));
-                dval(rv) += adj;
+                adj.d = aadj1 * ulp(&rv);
+                dval(&rv) += adj.d;
             }
 #else /*Sudden_Underflow*/
             /* Compute adj so that the IEEE rounding rules will
@@ -1656,12 +1669,12 @@ drop_down:
                 if (!dsign)
                     aadj1 = -aadj1;
             }
-            adj = aadj1 * ulp(dval(rv));
-            dval(rv) += adj;
+            adj.d = aadj1 * ulp(&rv);
+            dval(&rv) += adj.d;
 #endif /*Sudden_Underflow*/
 #endif /*Avoid_Underflow*/
         }
-        z = word0(rv) & Exp_mask;
+        z = word0(&rv) & Exp_mask;
 #ifndef SET_INEXACT
 #ifdef Avoid_Underflow
         if (!scale)
@@ -1671,7 +1684,7 @@ drop_down:
             L = (int32_t)aadj;
             aadj -= L;
             /* The tolerances below are conservative. */
-            if (dsign || word1(rv) || word0(rv) & Bndry_mask) {
+            if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
                 if (aadj < .4999999 || aadj > .5000001)
                     break;
             } else if (aadj < .4999999 / FLT_RADIX)
@@ -1679,55 +1692,46 @@ drop_down:
         }
 #endif
 cont:
-        Bfree(bb);
-        Bfree(bd);
-        Bfree(bs);
-        Bfree(delta);
+        ;
     }
 #ifdef SET_INEXACT
     if (inexact) {
         if (!oldinexact) {
-            word0(rv0) = Exp_1 + (70 << Exp_shift);
-            word1(rv0) = 0;
-            dval(rv0) += 1.;
+            word0(&rv0) = Exp_1 + (70 << Exp_shift);
+            word1(&rv0) = 0;
+            dval(&rv0) += 1.;
         }
     } else if (!oldinexact)
         clear_inexact();
 #endif
 #ifdef Avoid_Underflow
     if (scale) {
-        word0(rv0) = Exp_1 - 2 * P * Exp_msk1;
-        word1(rv0) = 0;
-        dval(rv) *= dval(rv0);
+        word0(&rv0) = Exp_1 - 2 * P * Exp_msk1;
+        word1(&rv0) = 0;
+        dval(&rv) *= dval(&rv0);
 #ifndef NO_ERRNO
         /* try to avoid the bug of testing an 8087 register value */
-        if (word0(rv) == 0 && word1(rv) == 0)
+        if (word0(&rv) == 0 && word1(&rv) == 0)
             errno = ERANGE;
 #endif
     }
 #endif /* Avoid_Underflow */
 #ifdef SET_INEXACT
-    if (inexact && !(word0(rv) & Exp_mask)) {
+    if (inexact && !(word0(&rv) & Exp_mask)) {
         /* set underflow bit */
-        dval(rv0) = 1e-300;
-        dval(rv0) *= dval(rv0);
+        dval(&rv0) = 1e-300;
+        dval(&rv0) *= dval(&rv0);
     }
 #endif
-retfree:
-    Bfree(bb);
-    Bfree(bd);
-    Bfree(bs);
-    Bfree(bd0);
-    Bfree(delta);
 ret:
     if (se)
         *se = const_cast<char*>(s);
-    return sign ? -dval(rv) : dval(rv);
+    return sign ? -dval(&rv) : dval(&rv);
 }
 
-static int quorem(Bigint* b, Bigint* S)
+static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S)
 {
-    int n;
+    size_t n;
     uint32_t *bx, *bxe, q, *sx, *sxe;
 #ifdef USE_LONG_LONG
     unsigned long long borrow, carry, y, ys;
@@ -1737,14 +1741,16 @@ static int quorem(Bigint* b, Bigint* S)
     uint32_t si, z, zs;
 #endif
 #endif
+    ASSERT(b.size() <= 1 || b.words()[b.size() - 1]);
+    ASSERT(S.size() <= 1 || S.words()[S.size() - 1]);
 
-    n = S->wds;
-    ASSERT_WITH_MESSAGE(b->wds <= n, "oversize b in quorem");
-    if (b->wds < n)
+    n = S.size();
+    ASSERT_WITH_MESSAGE(b.size() <= n, "oversize b in quorem");
+    if (b.size() < n)
         return 0;
-    sx = S->x;
+    sx = S.words();
     sxe = sx + --n;
-    bx = b->x;
+    bx = b.words();
     bxe = bx + n;
     q = *bxe / (*sxe + 1);    /* ensure q <= true quotient */
     ASSERT_WITH_MESSAGE(q <= 9, "oversized quotient in quorem");
@@ -1779,18 +1785,18 @@ static int quorem(Bigint* b, Bigint* S)
 #endif
         } while (sx <= sxe);
         if (!*bxe) {
-            bx = b->x;
+            bx = b.words();
             while (--bxe > bx && !*bxe)
                 --n;
-            b->wds = n;
+            b.resize(n);
         }
     }
     if (cmp(b, S) >= 0) {
         q++;
         borrow = 0;
         carry = 0;
-        bx = b->x;
-        sx = S->x;
+        bx = b.words();
+        sx = S.words();
         do {
 #ifdef USE_LONG_LONG
             ys = *sx++ + carry;
@@ -1818,68 +1824,17 @@ static int quorem(Bigint* b, Bigint* S)
 #endif
 #endif
         } while (sx <= sxe);
-        bx = b->x;
+        bx = b.words();
         bxe = bx + n;
         if (!*bxe) {
             while (--bxe > bx && !*bxe)
                 --n;
-            b->wds = n;
+            b.resize(n);
         }
     }
     return q;
 }
 
-#if !ENABLE(JSC_MULTIPLE_THREADS)
-static char* dtoa_result;
-#endif
-
-static char* rv_alloc(int i)
-{
-    int k;
-
-    int j = sizeof(uint32_t);
-    for (k = 0;
-        sizeof(Bigint) - sizeof(uint32_t) - sizeof(int) + j <= (unsigned)i;
-        j <<= 1)
-            k++;
-    int* r = (int*)Balloc(k);
-    *r = k;
-    return
-#if !ENABLE(JSC_MULTIPLE_THREADS)
-    dtoa_result =
-#endif
-        (char*)(r + 1);
-}
-
-static char* nrv_alloc(const char* s, char** rve, int n)
-{
-    char* rv = rv_alloc(n);
-    char* t = rv;
-
-    while ((*t = *s++))
-        t++;
-    if (rve)
-        *rve = t;
-    return rv;
-}
-
-/* freedtoa(s) must be used to free values s returned by dtoa
- * when MULTIPLE_THREADS is #defined.  It should be used in all cases,
- * but for consistency with earlier versions of dtoa, it is optional
- * when MULTIPLE_THREADS is not defined.
- */
-
-void freedtoa(char* s)
-{
-    Bigint* b = (Bigint*)((int*)s - 1);
-    b->maxwds = 1 << (b->k = *(int*)b);
-    Bfree(b);
-#if !ENABLE(JSC_MULTIPLE_THREADS)
-    if (s == dtoa_result)
-        dtoa_result = 0;
-#endif
-}
-
 /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
  *
  * Inspired by "How to Print Floating-Point Numbers Accurately" by
@@ -1914,7 +1869,7 @@ void freedtoa(char* s)
  *       calculation.
  */
 
-char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
+void dtoa(char* result, double dd, int ndigits, int* decpt, int* sign, char** rve)
 {
     /*
         Arguments ndigits, decpt, sign are similar to those
@@ -1933,38 +1888,37 @@ char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
     int denorm;
     uint32_t x;
 #endif
-    Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S;
-    double d2, ds, eps;
+    BigInt b, b1, delta, mlo, mhi, S;
+    U d2, eps, u;
+    double ds;
     char *s, *s0;
 #ifdef SET_INEXACT
     int inexact, oldinexact;
 #endif
 
-#if !ENABLE(JSC_MULTIPLE_THREADS)
-    if (dtoa_result) {
-        freedtoa(dtoa_result);
-        dtoa_result = 0;
-    }
-#endif
-
-    if (word0(d) & Sign_bit) {
+    u.d = dd;
+    if (word0(&u) & Sign_bit) {
         /* set sign for everything, including 0's and NaNs */
         *sign = 1;
-        word0(d) &= ~Sign_bit;    /* clear sign bit */
+        word0(&u) &= ~Sign_bit;    /* clear sign bit */
     } else
         *sign = 0;
 
-    if ((word0(d) & Exp_mask) == Exp_mask)
+    if ((word0(&u) & Exp_mask) == Exp_mask)
     {
         /* Infinity or NaN */
         *decpt = 9999;
-        if (!word1(d) && !(word0(d) & 0xfffff))
-            return nrv_alloc("Infinity", rve, 8);
-        return nrv_alloc("NaN", rve, 3);
+        if (!word1(&u) && !(word0(&u) & 0xfffff))
+            strcpy(result, "Infinity");
+        else 
+            strcpy(result, "NaN");
+        return;
     }
-    if (!dval(d)) {
+    if (!dval(&u)) {
         *decpt = 1;
-        return nrv_alloc("0", rve, 1);
+        result[0] = '0';
+        result[1] = '\0';
+        return;
     }
 
 #ifdef SET_INEXACT
@@ -1972,15 +1926,15 @@ char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
     inexact = 1;
 #endif
 
-    b = d2b(dval(d), &be, &bbits);
+    d2b(b, &u, &be, &bbits);
 #ifdef Sudden_Underflow
-    i = (int)(word0(d) >> Exp_shift1 & (Exp_mask >> Exp_shift1));
+    i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask >> Exp_shift1));
 #else
-    if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))) {
+    if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))) {
 #endif
-        dval(d2) = dval(d);
-        word0(d2) &= Frac_mask1;
-        word0(d2) |= Exp_11;
+        dval(&d2) = dval(&u);
+        word0(&d2) &= Frac_mask1;
+        word0(&d2) |= Exp_11;
 
         /* log(x)    ~=~ log(1.5) + (x-1.5)/1.5
          * log10(x)     =  log(x) / log(10)
@@ -2011,21 +1965,21 @@ char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
         /* d is denormalized */
 
         i = bbits + be + (Bias + (P - 1) - 1);
-        x = i > 32  ? word0(d) << 64 - i | word1(d) >> i - 32
-                : word1(d) << 32 - i;
-        dval(d2) = x;
-        word0(d2) -= 31 * Exp_msk1; /* adjust exponent */
+        x = (i > 32) ? (word0(&u) << (64 - i)) | (word1(&u) >> (i - 32))
+                : word1(&u) << (32 - i);
+        dval(&d2) = x;
+        word0(&d2) -= 31 * Exp_msk1; /* adjust exponent */
         i -= (Bias + (P - 1) - 1) + 1;
         denorm = 1;
     }
 #endif
-    ds = (dval(d2) - 1.5) * 0.289529654602168 + 0.1760912590558 + (i * 0.301029995663981);
+    ds = (dval(&d2) - 1.5) * 0.289529654602168 + 0.1760912590558 + (i * 0.301029995663981);
     k = (int)ds;
     if (ds < 0. && ds != k)
         k--;    /* want k = floor(ds) */
     k_check = 1;
     if (k >= 0 && k <= Ten_pmax) {
-        if (dval(d) < tens[k])
+        if (dval(&u) < tens[k])
             k--;
         k_check = 0;
     }
@@ -2059,14 +2013,14 @@ char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
     ilim = ilim1 = -1;
     i = 18;
     ndigits = 0;
-    s = s0 = rv_alloc(i);
+    s = s0 = result;
 
     if (ilim >= 0 && ilim <= Quick_max && try_quick) {
 
         /* Try to get by with floating-point arithmetic. */
 
         i = 0;
-        dval(d2) = dval(d);
+        dval(&d2) = dval(&u);
         k0 = k;
         ilim0 = ilim;
         ieps = 2; /* conservative */
@@ -2076,7 +2030,7 @@ char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
             if (j & Bletch) {
                 /* prevent overflows */
                 j &= Bletch - 1;
-                dval(d) /= bigtens[n_bigtens - 1];
+                dval(&u) /= bigtens[n_bigtens - 1];
                 ieps++;
             }
             for (; j; j >>= 1, i++) {
@@ -2085,32 +2039,33 @@ char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
                     ds *= bigtens[i];
                 }
             }
-            dval(d) /= ds;
+            dval(&u) /= ds;
         } else if ((j1 = -k)) {
-            dval(d) *= tens[j1 & 0xf];
+            dval(&u) *= tens[j1 & 0xf];
             for (j = j1 >> 4; j; j >>= 1, i++) {
                 if (j & 1) {
                     ieps++;
-                    dval(d) *= bigtens[i];
+                    dval(&u) *= bigtens[i];
                 }
             }
         }
-        if (k_check && dval(d) < 1. && ilim > 0) {
+        if (k_check && dval(&u) < 1. && ilim > 0) {
             if (ilim1 <= 0)
                 goto fast_failed;
             ilim = ilim1;
             k--;
-            dval(d) *= 10.;
+            dval(&u) *= 10.;
             ieps++;
         }
-        dval(eps) = (ieps * dval(d)) + 7.;
-        word0(eps) -= (P - 1) * Exp_msk1;
+        dval(&eps) = (ieps * dval(&u)) + 7.;
+        word0(&eps) -= (P - 1) * Exp_msk1;
         if (ilim == 0) {
-            S = mhi = 0;
-            dval(d) -= 5.;
-            if (dval(d) > dval(eps))
+            S.clear();
+            mhi.clear();
+            dval(&u) -= 5.;
+            if (dval(&u) > dval(&eps))
                 goto one_digit;
-            if (dval(d) < -dval(eps))
+            if (dval(&u) < -dval(&eps))
                 goto no_digits;
             goto fast_failed;
         }
@@ -2119,36 +2074,36 @@ char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
             /* Use Steele & White method of only
              * generating digits needed.
              */
-            dval(eps) = (0.5 / tens[ilim - 1]) - dval(eps);
+            dval(&eps) = (0.5 / tens[ilim - 1]) - dval(&eps);
             for (i = 0;;) {
-                L = (long int)dval(d);
-                dval(d) -= L;
+                L = (long int)dval(&u);
+                dval(&u) -= L;
                 *s++ = '0' + (int)L;
-                if (dval(d) < dval(eps))
-                    goto ret1;
-                if (1. - dval(d) < dval(eps))
+                if (dval(&u) < dval(&eps))
+                    goto ret;
+                if (1. - dval(&u) < dval(&eps))
                     goto bump_up;
                 if (++i >= ilim)
                     break;
-                dval(eps) *= 10.;
-                dval(d) *= 10.;
+                dval(&eps) *= 10.;
+                dval(&u) *= 10.;
             }
         } else {
 #endif
             /* Generate ilim digits, then fix them up. */
-            dval(eps) *= tens[ilim - 1];
-            for (i = 1;; i++, dval(d) *= 10.) {
-                L = (int32_t)(dval(d));
-                if (!(dval(d) -= L))
+            dval(&eps) *= tens[ilim - 1];
+            for (i = 1;; i++, dval(&u) *= 10.) {
+                L = (int32_t)(dval(&u));
+                if (!(dval(&u) -= L))
                     ilim = i;
                 *s++ = '0' + (int)L;
                 if (i == ilim) {
-                    if (dval(d) > 0.5 + dval(eps))
+                    if (dval(&u) > 0.5 + dval(&eps))
                         goto bump_up;
-                    else if (dval(d) < 0.5 - dval(eps)) {
+                    else if (dval(&u) < 0.5 - dval(&eps)) {
                         while (*--s == '0') { }
                         s++;
-                        goto ret1;
+                        goto ret;
                     }
                     break;
                 }
@@ -2158,7 +2113,7 @@ char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve)
 #endif
 fast_failed:
         s = s0;
-        dval(d) = dval(d2);
+        dval(&u) = dval(&d2);
         k = k0;
         ilim = ilim0;
     }
@@ -2169,31 +2124,32 @@ fast_failed:
         /* Yes. */
         ds = tens[k];
         if (ndigits < 0 && ilim <= 0) {
-            S = mhi = 0;
-            if (ilim < 0 || dval(d) <= 5 * ds)
+            S.clear();
+            mhi.clear();
+            if (ilim < 0 || dval(&u) <= 5 * ds)
                 goto no_digits;
             goto one_digit;
         }
-        for (i = 1;; i++, dval(d) *= 10.) {
-            L = (int32_t)(dval(d) / ds);
-            dval(d) -= L * ds;
+        for (i = 1;; i++, dval(&u) *= 10.) {
+            L = (int32_t)(dval(&u) / ds);
+            dval(&u) -= L * ds;
 #ifdef Check_FLT_ROUNDS
             /* If FLT_ROUNDS == 2, L will usually be high by 1 */
-            if (dval(d) < 0) {
+            if (dval(&u) < 0) {
                 L--;
-                dval(d) += ds;
+                dval(&u) += ds;
             }
 #endif
             *s++ = '0' + (int)L;
-            if (!dval(d)) {
+            if (!dval(&u)) {
 #ifdef SET_INEXACT
                 inexact = 0;
 #endif
                 break;
             }
             if (i == ilim) {
-                dval(d) += dval(d);
-                if (dval(d) > ds || dval(d) == ds && L & 1) {
+                dval(&u) += dval(&u);
+                if (dval(&u) > ds || (dval(&u) == ds && (L & 1))) {
 bump_up:
                     while (*--s == '9')
                         if (s == s0) {
@@ -2206,12 +2162,13 @@ bump_up:
                 break;
             }
         }
-        goto ret1;
+        goto ret;
     }
 
     m2 = b2;
     m5 = b5;
-    mhi = mlo = 0;
+    mhi.clear();
+    mlo.clear();
     if (leftright) {
         i =
 #ifndef Sudden_Underflow
@@ -2220,7 +2177,7 @@ bump_up:
             1 + P - bbits;
         b2 += i;
         s2 += i;
-        mhi = i2b(1);
+        i2b(mhi, 1);
     }
     if (m2 > 0 && s2 > 0) {
         i = m2 < s2 ? m2 : s2;
@@ -2231,26 +2188,24 @@ bump_up:
     if (b5 > 0) {
         if (leftright) {
             if (m5 > 0) {
-                mhi = pow5mult(mhi, m5);
-                b1 = mult(mhi, b);
-                Bfree(b);
-                b = b1;
+                pow5mult(mhi, m5);
+                mult(b, mhi);
             }
             if ((j = b5 - m5))
-                b = pow5mult(b, j);
+                pow5mult(b, j);
         } else
-            b = pow5mult(b, b5);
+            pow5mult(b, b5);
         }
-    S = i2b(1);
+    i2b(S, 1);
     if (s5 > 0)
-        S = pow5mult(S, s5);
+        pow5mult(S, s5);
 
     /* Check for special case that d is a normalized power of 2. */
 
     spec_case = 0;
-    if (!word1(d) && !(word0(d) & Bndry_mask)
+    if (!word1(&u) && !(word0(&u) & Bndry_mask)
 #ifndef Sudden_Underflow
-     && word0(d) & (Exp_mask & ~Exp_msk1)
+     && word0(&u) & (Exp_mask & ~Exp_msk1)
 #endif
             ) {
         /* The special case */
@@ -2267,10 +2222,10 @@ bump_up:
      * can do shifts and ors to compute the numerator for q.
      */
 #ifdef Pack_32
-    if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds - 1]) : 1) + s2) & 0x1f))
+    if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0x1f))
         i = 32 - i;
 #else
-    if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds - 1]) : 1) + s2) & 0xf))
+    if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0xf))
         i = 16 - i;
 #endif
     if (i > 4) {
@@ -2285,22 +2240,22 @@ bump_up:
         s2 += i;
     }
     if (b2 > 0)
-        b = lshift(b, b2);
+        lshift(b, b2);
     if (s2 > 0)
-        S = lshift(S, s2);
+        lshift(S, s2);
     if (k_check) {
         if (cmp(b,S) < 0) {
             k--;
-            b = multadd(b, 10, 0);    /* we botched the k estimate */
+            multadd(b, 10, 0);    /* we botched the k estimate */
             if (leftright)
-                mhi = multadd(mhi, 10, 0);
+                multadd(mhi, 10, 0);
             ilim = ilim1;
         }
     }
 
     if (leftright) {
         if (m2 > 0)
-            mhi = lshift(mhi, m2);
+            lshift(mhi, m2);
 
         /* Compute mlo -- check for special case
          * that d is a normalized power of 2.
@@ -2308,9 +2263,8 @@ bump_up:
 
         mlo = mhi;
         if (spec_case) {
-            mhi = Balloc(mhi->k);
-            Bcopy(mhi, mlo);
-            mhi = lshift(mhi, Log2P);
+            mhi = mlo;
+            lshift(mhi, Log2P);
         }
 
         for (i = 1;;i++) {
@@ -2319,10 +2273,9 @@ bump_up:
              * that will round to d?
              */
             j = cmp(b, mlo);
-            delta = diff(S, mhi);
-            j1 = delta->sign ? 1 : cmp(b, delta);
-            Bfree(delta);
-            if (j1 == 0 && !(word1(d) & 1)) {
+            diff(delta, S, mhi);
+            j1 = delta.sign ? 1 : cmp(b, delta);
+            if (j1 == 0 && !(word1(&u) & 1)) {
                 if (dig == '9')
                     goto round_9_up;
                 if (j > 0)
@@ -2334,17 +2287,17 @@ bump_up:
                 *s++ = dig;
                 goto ret;
             }
-            if (j < 0 || j == 0 && !(word1(d) & 1)) {
-                if (!b->x[0] && b->wds <= 1) {
+            if (j < 0 || (j == 0 && !(word1(&u) & 1))) {
+                if (!b.words()[0] && b.size() <= 1) {
 #ifdef SET_INEXACT
                     inexact = 0;
 #endif
                     goto accept_dig;
                 }
                 if (j1 > 0) {
-                    b = lshift(b, 1);
+                    lshift(b, 1);
                     j1 = cmp(b, S);
-                    if ((j1 > 0 || j1 == 0 && dig & 1) && dig++ == '9')
+                    if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9')
                         goto round_9_up;
                 }
 accept_dig:
@@ -2363,18 +2316,14 @@ round_9_up:
             *s++ = dig;
             if (i == ilim)
                 break;
-            b = multadd(b, 10, 0);
-            if (mlo == mhi)
-                mlo = mhi = multadd(mhi, 10, 0);
-            else {
-                mlo = multadd(mlo, 10, 0);
-                mhi = multadd(mhi, 10, 0);
-            }
+            multadd(b, 10, 0);
+            multadd(mlo, 10, 0);
+            multadd(mhi, 10, 0);
         }
     } else
         for (i = 1;; i++) {
             *s++ = dig = quorem(b,S) + '0';
-            if (!b->x[0] && b->wds <= 1) {
+            if (!b.words()[0] && b.size() <= 1) {
 #ifdef SET_INEXACT
                 inexact = 0;
 #endif
@@ -2382,14 +2331,14 @@ round_9_up:
             }
             if (i >= ilim)
                 break;
-            b = multadd(b, 10, 0);
+            multadd(b, 10, 0);
         }
 
     /* Round off last digit */
 
-    b = lshift(b, 1);
+    lshift(b, 1);
     j = cmp(b, S);
-    if (j > 0 || j == 0 && dig & 1) {
+    if (j > 0 || (j == 0 && (dig & 1))) {
 roundoff:
         while (*--s == '9')
             if (s == s0) {
@@ -2411,29 +2360,20 @@ one_digit:
     k++;
     goto ret;
 ret:
-    Bfree(S);
-    if (mhi) {
-        if (mlo && mlo != mhi)
-            Bfree(mlo);
-        Bfree(mhi);
-    }
-ret1:
 #ifdef SET_INEXACT
     if (inexact) {
         if (!oldinexact) {
-            word0(d) = Exp_1 + (70 << Exp_shift);
-            word1(d) = 0;
-            dval(d) += 1.;
+            word0(&u) = Exp_1 + (70 << Exp_shift);
+            word1(&u) = 0;
+            dval(&u) += 1.;
         }
     } else if (!oldinexact)
         clear_inexact();
 #endif
-    Bfree(b);
     *s = 0;
     *decpt = k + 1;
     if (rve)
         *rve = s;
-    return s0;
 }
 
 } // namespace WTF
index ed858c06800b2151c10337feed64a1507865c1ee..cbec7c71827cf1f857592e3dc796e392ac10a22e 100644 (file)
@@ -30,8 +30,7 @@ namespace WTF {
     extern WTF::Mutex* s_dtoaP5Mutex;
 
     double strtod(const char* s00, char** se);
-    char* dtoa(double d, int ndigits, int* decpt, int* sign, char** rve);
-    void freedtoa(char* s);
+    void dtoa(char* result, double d, int ndigits, int* decpt, int* sign, char** rve);
 
 } // namespace WTF
 
index a6e061f637421381ddcab4d6a5e645dfb517330d..7624247b6265d4ed360e51bb611ce939f5c78007 100644 (file)
 
 namespace WTF {
 
+void initializeMainThreadPlatform()
+{
+}
+
 static gboolean timeoutFired(gpointer)
 {
     dispatchFunctionsFromMainThread();
@@ -45,5 +49,4 @@ void scheduleDispatchFunctionsOnMainThread()
     g_timeout_add(0, timeoutFired, 0);
 }
 
-
-}
+} // namespace WTF
diff --git a/wtf/gtk/ThreadingGtk.cpp b/wtf/gtk/ThreadingGtk.cpp
new file mode 100644 (file)
index 0000000..b4f4de1
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Threading.h"
+
+#if !USE(PTHREADS)
+
+#include "CurrentTime.h"
+#include "HashMap.h"
+#include "MainThread.h"
+#include "RandomNumberSeed.h"
+
+#include <glib.h>
+#include <limits.h>
+
+namespace WTF {
+
+static Mutex* atomicallyInitializedStaticMutex;
+
+static ThreadIdentifier mainThreadIdentifier;
+
+static Mutex& threadMapMutex()
+{
+    static Mutex mutex;
+    return mutex;
+}
+
+void initializeThreading()
+{
+    if (!g_thread_supported())
+        g_thread_init(NULL);
+    ASSERT(g_thread_supported());
+
+    if (!atomicallyInitializedStaticMutex) {
+        atomicallyInitializedStaticMutex = new Mutex;
+        threadMapMutex();
+        initializeRandomNumberGenerator();
+        mainThreadIdentifier = currentThread();
+        initializeMainThread();
+    }
+}
+
+void lockAtomicallyInitializedStaticMutex()
+{
+    ASSERT(atomicallyInitializedStaticMutex);
+    atomicallyInitializedStaticMutex->lock();
+}
+
+void unlockAtomicallyInitializedStaticMutex()
+{
+    atomicallyInitializedStaticMutex->unlock();
+}
+
+static HashMap<ThreadIdentifier, GThread*>& threadMap()
+{
+    static HashMap<ThreadIdentifier, GThread*> map;
+    return map;
+}
+
+static ThreadIdentifier identifierByGthreadHandle(GThread*& thread)
+{
+    MutexLocker locker(threadMapMutex());
+
+    HashMap<ThreadIdentifier, GThread*>::iterator i = threadMap().begin();
+    for (; i != threadMap().end(); ++i) {
+        if (i->second == thread)
+            return i->first;
+    }
+
+    return 0;
+}
+
+static ThreadIdentifier establishIdentifierForThread(GThread*& thread)
+{
+    ASSERT(!identifierByGthreadHandle(thread));
+
+    MutexLocker locker(threadMapMutex());
+
+    static ThreadIdentifier identifierCount = 1;
+
+    threadMap().add(identifierCount, thread);
+
+    return identifierCount++;
+}
+
+static GThread* threadForIdentifier(ThreadIdentifier id)
+{
+    MutexLocker locker(threadMapMutex());
+
+    return threadMap().get(id);
+}
+
+static void clearThreadForIdentifier(ThreadIdentifier id)
+{
+    MutexLocker locker(threadMapMutex());
+
+    ASSERT(threadMap().contains(id));
+
+    threadMap().remove(id);
+}
+
+ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
+{
+    GThread* thread;
+    if (!(thread = g_thread_create(entryPoint, data, TRUE, 0))) {
+        LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
+        return 0;
+    }
+
+    ThreadIdentifier threadID = establishIdentifierForThread(thread);
+    return threadID;
+}
+
+void setThreadNameInternal(const char*)
+{
+}
+
+int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
+{
+    ASSERT(threadID);
+
+    GThread* thread = threadForIdentifier(threadID);
+
+    void* joinResult = g_thread_join(thread);
+    if (result)
+        *result = joinResult;
+
+    clearThreadForIdentifier(threadID);
+    return 0;
+}
+
+void detachThread(ThreadIdentifier)
+{
+}
+
+ThreadIdentifier currentThread()
+{
+    GThread* currentThread = g_thread_self();
+    if (ThreadIdentifier id = identifierByGthreadHandle(currentThread))
+        return id;
+    return establishIdentifierForThread(currentThread);
+}
+
+bool isMainThread()
+{
+    return currentThread() == mainThreadIdentifier;
+}
+
+Mutex::Mutex()
+    : m_mutex(g_mutex_new())
+{
+}
+
+Mutex::~Mutex()
+{
+}
+
+void Mutex::lock()
+{
+    g_mutex_lock(m_mutex.get());
+}
+
+bool Mutex::tryLock()
+{
+    return g_mutex_trylock(m_mutex.get());
+}
+
+void Mutex::unlock()
+{
+    g_mutex_unlock(m_mutex.get());
+}
+
+ThreadCondition::ThreadCondition()
+    : m_condition(g_cond_new())
+{
+}
+
+ThreadCondition::~ThreadCondition()
+{
+}
+
+void ThreadCondition::wait(Mutex& mutex)
+{
+    g_cond_wait(m_condition.get(), mutex.impl().get());
+}
+
+bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
+{
+    // Time is in the past - return right away.
+    if (absoluteTime < currentTime())
+        return false;
+    
+    // Time is too far in the future for g_cond_timed_wait - wait forever.
+    if (absoluteTime > INT_MAX) {
+        wait(mutex);
+        return true;
+    }
+
+    int timeSeconds = static_cast<int>(absoluteTime);
+    int timeMicroseconds = static_cast<int>((absoluteTime - timeSeconds) * 1000000.0);
+    
+    GTimeVal targetTime;
+    targetTime.tv_sec = timeSeconds;
+    targetTime.tv_usec = timeMicroseconds;
+
+    return g_cond_timed_wait(m_condition.get(), mutex.impl().get(), &targetTime);
+}
+
+void ThreadCondition::signal()
+{
+    g_cond_signal(m_condition.get());
+}
+
+void ThreadCondition::broadcast()
+{
+    g_cond_broadcast(m_condition.get());
+}
+
+
+}
+
+#endif // !USE(PTHREADS)
index a6d9c5b152c91d668dedee2759600720f6511062..3b84fc3bdebc3084aae447f73cb4ce8cb986d679 100644 (file)
@@ -29,8 +29,8 @@
 #import "config.h"
 #import "MainThread.h"
 
-#import "Threading.h"
 #import <Foundation/NSThread.h>
+#import <wtf/Assertions.h>
 
 @interface WTFMainThreadCaller : NSObject {
 }
 
 namespace WTF {
 
+static NSThread* staticMainNSThread = nil;
+static WTFMainThreadCaller* staticMainThreadCaller = nil;
+
+void initializeMainThreadPlatform()
+{
+    ASSERT(!staticMainThreadCaller);
+    staticMainThreadCaller = [[WTFMainThreadCaller alloc] init];
+    ASSERT(!staticMainNSThread);
+    staticMainNSThread = [[NSThread currentThread] retain];
+}
+
 void scheduleDispatchFunctionsOnMainThread()
 {
-    WTFMainThreadCaller *caller = [[WTFMainThreadCaller alloc] init];
-    [caller performSelector:@selector(call) onThread:mainNSThread() withObject:nil waitUntilDone:NO];
-    [caller release];
+    ASSERT(staticMainNSThread);
+    ASSERT(staticMainThreadCaller);
+    [staticMainThreadCaller performSelector:@selector(call) onThread:staticMainNSThread withObject:nil waitUntilDone:NO];
 }
 
 } // namespace WTF
diff --git a/wtf/iphone/ThreadingNSThread.mm b/wtf/iphone/ThreadingNSThread.mm
deleted file mode 100644 (file)
index d12dbfe..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer. 
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution. 
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission. 
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#import "config.h"
-#import "Threading.h"
-
-#import <Foundation/NSThread.h>
-
-namespace WTF {
-
-static NSThread *mainThread;
-
-NSThread *mainNSThread()
-{
-    return mainThread;
-}
-
-void initializeMainNSThread()
-{
-    mainThread = [[NSThread currentThread] retain];
-}
-
-} // namespace WTF
index b04ef0e427b0058f3e6f05e2da01f358132829a0..c79acc16f817362b0ae3b055b24dfa6119d18242 100644 (file)
@@ -30,6 +30,7 @@
 #import "MainThread.h"
 
 #import <Foundation/NSThread.h>
+#import <wtf/Assertions.h>
 
 @interface WTFMainThreadCaller : NSObject {
 }
 
 namespace WTF {
 
+static WTFMainThreadCaller* staticMainThreadCaller = nil;
+
+void initializeMainThreadPlatform()
+{
+    ASSERT(!staticMainThreadCaller);
+    staticMainThreadCaller = [[WTFMainThreadCaller alloc] init];
+}
+
 void scheduleDispatchFunctionsOnMainThread()
 {
-    WTFMainThreadCaller *caller = [[WTFMainThreadCaller alloc] init];
-    [caller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
-    [caller release];
+    ASSERT(staticMainThreadCaller);
+    [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
 }
 
 } // namespace WTF
index 1914600a81d1be8b24361d83a685f5cd95d2b30c..7b2d0f25a83afdd00a701e5556fb19db1e1c62dc 100644 (file)
@@ -58,12 +58,15 @@ void MainThreadInvoker::dispatch()
 
 Q_GLOBAL_STATIC(MainThreadInvoker, webkit_main_thread_invoker)
 
+void initializeMainThreadPlatform()
+{
+}
 
 void scheduleDispatchFunctionsOnMainThread()
 {
     QMetaObject::invokeMethod(webkit_main_thread_invoker(), "dispatch", Qt::QueuedConnection);
 }
 
-}
+} // namespace WTF
 
 #include "MainThreadQt.moc"
diff --git a/wtf/qt/ThreadingQt.cpp b/wtf/qt/ThreadingQt.cpp
new file mode 100644 (file)
index 0000000..1fdd2bb
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer. 
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution. 
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+#include "Threading.h"
+
+#include "CurrentTime.h"
+#include "HashMap.h"
+#include "MainThread.h"
+#include "RandomNumberSeed.h"
+
+#include <QCoreApplication>
+#include <QMutex>
+#include <QThread>
+#include <QWaitCondition>
+
+namespace WTF {
+
+class ThreadPrivate : public QThread {
+public:
+    ThreadPrivate(ThreadFunction entryPoint, void* data);
+    void run();
+    void* getReturnValue() { return m_returnValue; }
+private:
+    void* m_data;
+    ThreadFunction m_entryPoint;
+    void* m_returnValue;
+};
+
+ThreadPrivate::ThreadPrivate(ThreadFunction entryPoint, void* data) 
+    : m_data(data)
+    , m_entryPoint(entryPoint)
+    , m_returnValue(0)
+{
+}
+
+void ThreadPrivate::run()
+{
+    m_returnValue = m_entryPoint(m_data);
+}
+
+
+static Mutex* atomicallyInitializedStaticMutex;
+
+static ThreadIdentifier mainThreadIdentifier;
+
+static Mutex& threadMapMutex()
+{
+    static Mutex mutex;
+    return mutex;
+}
+
+static HashMap<ThreadIdentifier, QThread*>& threadMap()
+{
+    static HashMap<ThreadIdentifier, QThread*> map;
+    return map;
+}
+
+static ThreadIdentifier identifierByQthreadHandle(QThread*& thread)
+{
+    MutexLocker locker(threadMapMutex());
+
+    HashMap<ThreadIdentifier, QThread*>::iterator i = threadMap().begin();
+    for (; i != threadMap().end(); ++i) {
+        if (i->second == thread)
+            return i->first;
+    }
+
+    return 0;
+}
+
+static ThreadIdentifier establishIdentifierForThread(QThread*& thread)
+{
+    ASSERT(!identifierByQthreadHandle(thread));
+
+    MutexLocker locker(threadMapMutex());
+
+    static ThreadIdentifier identifierCount = 1;
+
+    threadMap().add(identifierCount, thread);
+
+    return identifierCount++;
+}
+
+static void clearThreadForIdentifier(ThreadIdentifier id)
+{
+    MutexLocker locker(threadMapMutex());
+
+    ASSERT(threadMap().contains(id));
+
+    threadMap().remove(id);
+}
+
+static QThread* threadForIdentifier(ThreadIdentifier id)
+{
+    MutexLocker locker(threadMapMutex());
+
+    return threadMap().get(id);
+}
+
+void initializeThreading()
+{
+    if (!atomicallyInitializedStaticMutex) {
+        atomicallyInitializedStaticMutex = new Mutex;
+        threadMapMutex();
+        initializeRandomNumberGenerator();
+        QThread* mainThread = QCoreApplication::instance()->thread();
+        mainThreadIdentifier = identifierByQthreadHandle(mainThread);
+        if (!mainThreadIdentifier)
+            mainThreadIdentifier = establishIdentifierForThread(mainThread);
+        initializeMainThread();
+    }
+}
+
+void lockAtomicallyInitializedStaticMutex()
+{
+    ASSERT(atomicallyInitializedStaticMutex);
+    atomicallyInitializedStaticMutex->lock();
+}
+
+void unlockAtomicallyInitializedStaticMutex()
+{
+    atomicallyInitializedStaticMutex->unlock();
+}
+
+ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
+{
+    ThreadPrivate* thread = new ThreadPrivate(entryPoint, data);
+    if (!thread) {
+        LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data);
+        return 0;
+    }
+    thread->start();
+
+    QThread* threadRef = static_cast<QThread*>(thread);
+
+    return establishIdentifierForThread(threadRef);
+}
+
+void setThreadNameInternal(const char*)
+{
+}
+
+int waitForThreadCompletion(ThreadIdentifier threadID, void** result)
+{
+    ASSERT(threadID);
+
+    QThread* thread = threadForIdentifier(threadID);
+
+    bool res = thread->wait();
+
+    clearThreadForIdentifier(threadID);
+    if (result)
+        *result = static_cast<ThreadPrivate*>(thread)->getReturnValue();
+
+    return !res;
+}
+
+void detachThread(ThreadIdentifier)
+{
+}
+
+ThreadIdentifier currentThread()
+{
+    QThread* currentThread = QThread::currentThread();
+    if (ThreadIdentifier id = identifierByQthreadHandle(currentThread))
+        return id;
+    return establishIdentifierForThread(currentThread);
+}
+
+bool isMainThread()
+{
+    return QThread::currentThread() == QCoreApplication::instance()->thread();
+}
+
+Mutex::Mutex()
+    : m_mutex(new QMutex())
+{
+}
+
+Mutex::~Mutex()
+{
+    delete m_mutex;
+}
+
+void Mutex::lock()
+{
+    m_mutex->lock();
+}
+
+bool Mutex::tryLock()
+{
+    return m_mutex->tryLock();
+}
+
+void Mutex::unlock()
+{
+    m_mutex->unlock();
+}
+
+ThreadCondition::ThreadCondition()
+    : m_condition(new QWaitCondition())
+{
+}
+
+ThreadCondition::~ThreadCondition()
+{
+    delete m_condition;
+}
+
+void ThreadCondition::wait(Mutex& mutex)
+{
+    m_condition->wait(mutex.impl());
+}
+
+bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime)
+{
+    double currentTime = WTF::currentTime();
+
+    // Time is in the past - return immediately.
+    if (absoluteTime < currentTime)
+        return false;
+
+    // Time is too far in the future (and would overflow unsigned long) - wait forever.
+    if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) {
+        wait(mutex);
+        return true;
+    }
+
+    double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
+    return m_condition->wait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds));
+}
+
+void ThreadCondition::signal()
+{
+    m_condition->wakeOne();
+}
+
+void ThreadCondition::broadcast()
+{
+    m_condition->wakeAll();
+}
+
+} // namespace WebCore
index e6e8f23fb9c73867d583c60c1f17c16146396dd4..f86a9b7c39a0f03aa012680969afa473e24f9ca5 100644 (file)
@@ -28,6 +28,8 @@
 #include "qt4/UnicodeQt4.h"
 #elif USE(ICU_UNICODE)
 #include <wtf/unicode/icu/UnicodeIcu.h>
+#elif USE(GLIB_UNICODE)
+#include <wtf/unicode/glib/UnicodeGLib.h>
 #else
 #error "Unknown Unicode implementation"
 #endif
diff --git a/wtf/unicode/glib/UnicodeGLib.cpp b/wtf/unicode/glib/UnicodeGLib.cpp
new file mode 100644 (file)
index 0000000..a779b36
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ *  Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ *  Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "UnicodeGLib.h"
+
+namespace WTF {
+namespace Unicode {
+
+UChar32 foldCase(UChar32 ch)
+{
+    GOwnPtr<GError> gerror;
+
+    GOwnPtr<char> utf8char;
+    utf8char.set(g_ucs4_to_utf8(reinterpret_cast<gunichar*>(&ch), 1, 0, 0, &gerror.outPtr()));
+    if (gerror)
+        return ch;
+
+    GOwnPtr<char> utf8caseFolded;
+    utf8caseFolded.set(g_utf8_casefold(utf8char.get(), -1));
+
+    GOwnPtr<gunichar> ucs4Result;
+    ucs4Result.set(g_utf8_to_ucs4_fast(utf8caseFolded.get(), -1, 0));
+
+    return *ucs4Result;
+}
+
+int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
+{
+    *error = false;
+    GOwnPtr<GError> gerror;
+
+    GOwnPtr<char> utf8src;
+    utf8src.set(g_utf16_to_utf8(src, srcLength, 0, 0, &gerror.outPtr()));
+    if (gerror) {
+        *error = true;
+        return -1;
+    }
+
+    GOwnPtr<char> utf8result;
+    utf8result.set(g_utf8_casefold(utf8src.get(), -1));
+
+    long utf16resultLength = -1;
+    GOwnPtr<UChar> utf16result;
+    utf16result.set(g_utf8_to_utf16(utf8result.get(), -1, 0, &utf16resultLength, &gerror.outPtr()));
+    if (gerror) {
+        *error = true;
+        return -1;
+    }
+
+    if (utf16resultLength > resultLength) {
+        *error = true;
+        return utf16resultLength;
+    }
+    memcpy(result, utf16result.get(), utf16resultLength * sizeof(UChar));
+
+    return utf16resultLength;
+}
+
+int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
+{
+    *error = false;
+    GOwnPtr<GError> gerror;
+
+    GOwnPtr<char> utf8src;
+    utf8src.set(g_utf16_to_utf8(src, srcLength, 0, 0, &gerror.outPtr()));
+    if (gerror) {
+        *error = true;
+        return -1;
+    }
+
+    GOwnPtr<char> utf8result;
+    utf8result.set(g_utf8_strdown(utf8src.get(), -1));
+
+    long utf16resultLength = -1;
+    GOwnPtr<UChar> utf16result;
+    utf16result.set(g_utf8_to_utf16(utf8result.get(), -1, 0, &utf16resultLength, &gerror.outPtr()));
+    if (gerror) {
+        *error = true;
+        return -1;
+    }
+
+    if (utf16resultLength > resultLength) {
+        *error = true;
+        return utf16resultLength;
+    }
+    memcpy(result, utf16result.get(), utf16resultLength * sizeof(UChar));
+
+    return utf16resultLength;
+}
+
+int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error)
+{
+    *error = false;
+    GOwnPtr<GError> gerror;
+
+    GOwnPtr<char> utf8src;
+    utf8src.set(g_utf16_to_utf8(src, srcLength, 0, 0, &gerror.outPtr()));
+    if (gerror) {
+        *error = true;
+        return -1;
+    }
+
+    GOwnPtr<char> utf8result;
+    utf8result.set(g_utf8_strup(utf8src.get(), -1));
+
+    long utf16resultLength = -1;
+    GOwnPtr<UChar> utf16result;
+    utf16result.set(g_utf8_to_utf16(utf8result.get(), -1, 0, &utf16resultLength, &gerror.outPtr()));
+    if (gerror) {
+        *error = true;
+        return -1;
+    }
+
+    if (utf16resultLength > resultLength) {
+        *error = true;
+        return utf16resultLength;
+    }
+    memcpy(result, utf16result.get(), utf16resultLength * sizeof(UChar));
+
+    return utf16resultLength;
+}
+
+Direction direction(UChar32 c)
+{
+    PangoBidiType type = pango_bidi_type_for_unichar(c);
+    switch (type) {
+    case PANGO_BIDI_TYPE_L:
+        return LeftToRight;
+    case PANGO_BIDI_TYPE_R:
+        return RightToLeft;
+    case PANGO_BIDI_TYPE_AL:
+        return RightToLeftArabic;
+    case PANGO_BIDI_TYPE_LRE:
+        return LeftToRightEmbedding;
+    case PANGO_BIDI_TYPE_RLE:
+        return RightToLeftEmbedding;
+    case PANGO_BIDI_TYPE_LRO:
+        return LeftToRightOverride;
+    case PANGO_BIDI_TYPE_RLO:
+        return RightToLeftOverride;
+    case PANGO_BIDI_TYPE_PDF:
+        return PopDirectionalFormat;
+    case PANGO_BIDI_TYPE_EN:
+        return EuropeanNumber;
+    case PANGO_BIDI_TYPE_AN:
+        return ArabicNumber;
+    case PANGO_BIDI_TYPE_ES:
+        return EuropeanNumberSeparator;
+    case PANGO_BIDI_TYPE_ET:
+        return EuropeanNumberTerminator;
+    case PANGO_BIDI_TYPE_CS:
+        return CommonNumberSeparator;
+    case PANGO_BIDI_TYPE_NSM:
+        return NonSpacingMark;
+    case PANGO_BIDI_TYPE_BN:
+        return BoundaryNeutral;
+    case PANGO_BIDI_TYPE_B:
+        return BlockSeparator;
+    case PANGO_BIDI_TYPE_S:
+        return SegmentSeparator;
+    case PANGO_BIDI_TYPE_WS:
+        return WhiteSpaceNeutral;
+    default:
+        return OtherNeutral;
+    }
+}
+
+int umemcasecmp(const UChar* a, const UChar* b, int len)
+{
+    GOwnPtr<char> utf8a;
+    GOwnPtr<char> utf8b;
+
+    utf8a.set(g_utf16_to_utf8(a, len, 0, 0, 0));
+    utf8b.set(g_utf16_to_utf8(b, len, 0, 0, 0));
+
+    GOwnPtr<char> foldedA;
+    GOwnPtr<char> foldedB;
+
+    foldedA.set(g_utf8_casefold(utf8a.get(), -1));
+    foldedB.set(g_utf8_casefold(utf8b.get(), -1));
+
+    // FIXME: umemcasecmp needs to mimic u_memcasecmp of icu
+    // from the ICU docs:
+    // "Compare two strings case-insensitively using full case folding.
+    // his is equivalent to u_strcmp(u_strFoldCase(s1, n, options), u_strFoldCase(s2, n, options))."
+    //
+    // So it looks like we don't need the full g_utf8_collate here,
+    // but really a bitwise comparison of casefolded unicode chars (not utf-8 bytes).
+    // As there is no direct equivalent to this icu function in GLib, for now
+    // we'll use g_utf8_collate():
+
+    return g_utf8_collate(foldedA.get(), foldedB.get());
+}
+
+}
+}
diff --git a/wtf/unicode/glib/UnicodeGLib.h b/wtf/unicode/glib/UnicodeGLib.h
new file mode 100644 (file)
index 0000000..c03d3ec
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ *  Copyright (C) 2006 George Staikos <staikos@kde.org>
+ *  Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ *  Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
+ *  Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ *  Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef UnicodeGLib_h
+#define UnicodeGLib_h
+
+#include "UnicodeMacrosFromICU.h"
+#include <wtf/GOwnPtr.h>
+
+#include <glib.h>
+#include <pango/pango.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef uint16_t UChar;
+typedef int32_t UChar32;
+
+namespace WTF {
+namespace Unicode {
+
+enum Direction {
+    LeftToRight,
+    RightToLeft,
+    EuropeanNumber,
+    EuropeanNumberSeparator,
+    EuropeanNumberTerminator,
+    ArabicNumber,
+    CommonNumberSeparator,
+    BlockSeparator,
+    SegmentSeparator,
+    WhiteSpaceNeutral,
+    OtherNeutral,
+    LeftToRightEmbedding,
+    LeftToRightOverride,
+    RightToLeftArabic,
+    RightToLeftEmbedding,
+    RightToLeftOverride,
+    PopDirectionalFormat,
+    NonSpacingMark,
+    BoundaryNeutral
+};
+
+enum DecompositionType {
+    DecompositionNone,
+    DecompositionCanonical,
+    DecompositionCompat,
+    DecompositionCircle,
+    DecompositionFinal,
+    DecompositionFont,
+    DecompositionFraction,
+    DecompositionInitial,
+    DecompositionIsolated,
+    DecompositionMedial,
+    DecompositionNarrow,
+    DecompositionNoBreak,
+    DecompositionSmall,
+    DecompositionSquare,
+    DecompositionSub,
+    DecompositionSuper,
+    DecompositionVertical,
+    DecompositionWide,
+};
+
+enum CharCategory {
+    NoCategory =  0,
+    Other_NotAssigned = U_MASK(G_UNICODE_UNASSIGNED),
+    Letter_Uppercase = U_MASK(G_UNICODE_UPPERCASE_LETTER),
+    Letter_Lowercase = U_MASK(G_UNICODE_LOWERCASE_LETTER),
+    Letter_Titlecase = U_MASK(G_UNICODE_TITLECASE_LETTER),
+    Letter_Modifier = U_MASK(G_UNICODE_MODIFIER_LETTER),
+    Letter_Other = U_MASK(G_UNICODE_OTHER_LETTER),
+
+    Mark_NonSpacing = U_MASK(G_UNICODE_NON_SPACING_MARK),
+    Mark_Enclosing = U_MASK(G_UNICODE_ENCLOSING_MARK),
+    Mark_SpacingCombining = U_MASK(G_UNICODE_COMBINING_MARK),
+
+    Number_DecimalDigit = U_MASK(G_UNICODE_DECIMAL_NUMBER),
+    Number_Letter = U_MASK(G_UNICODE_LETTER_NUMBER),
+    Number_Other = U_MASK(G_UNICODE_OTHER_NUMBER),
+
+    Separator_Space = U_MASK(G_UNICODE_SPACE_SEPARATOR),
+    Separator_Line = U_MASK(G_UNICODE_LINE_SEPARATOR),
+    Separator_Paragraph = U_MASK(G_UNICODE_PARAGRAPH_SEPARATOR),
+
+    Other_Control = U_MASK(G_UNICODE_CONTROL),
+    Other_Format = U_MASK(G_UNICODE_FORMAT),
+    Other_PrivateUse = U_MASK(G_UNICODE_PRIVATE_USE),
+    Other_Surrogate = U_MASK(G_UNICODE_SURROGATE),
+
+    Punctuation_Dash = U_MASK(G_UNICODE_DASH_PUNCTUATION),
+    Punctuation_Open = U_MASK(G_UNICODE_OPEN_PUNCTUATION),
+    Punctuation_Close = U_MASK(G_UNICODE_CLOSE_PUNCTUATION),
+    Punctuation_Connector = U_MASK(G_UNICODE_CONNECT_PUNCTUATION),
+    Punctuation_Other = U_MASK(G_UNICODE_OTHER_PUNCTUATION),
+
+    Symbol_Math = U_MASK(G_UNICODE_MATH_SYMBOL),
+    Symbol_Currency = U_MASK(G_UNICODE_CURRENCY_SYMBOL),
+    Symbol_Modifier = U_MASK(G_UNICODE_MODIFIER_SYMBOL),
+    Symbol_Other = U_MASK(G_UNICODE_OTHER_SYMBOL),
+
+    Punctuation_InitialQuote = U_MASK(G_UNICODE_INITIAL_PUNCTUATION),
+    Punctuation_FinalQuote = U_MASK(G_UNICODE_FINAL_PUNCTUATION)
+};
+
+UChar32 foldCase(UChar32);
+
+int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error);
+
+int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error);
+
+inline UChar32 toLower(UChar32 c)
+{
+    return g_unichar_tolower(c);
+}
+
+inline UChar32 toUpper(UChar32 c)
+{
+    return g_unichar_toupper(c);
+}
+
+int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error);
+
+inline UChar32 toTitleCase(UChar32 c)
+{
+    return g_unichar_totitle(c);
+}
+
+inline bool isArabicChar(UChar32 c)
+{
+    return c >= 0x0600 && c <= 0x06FF;
+}
+
+inline bool isFormatChar(UChar32 c)
+{
+    return g_unichar_type(c) == G_UNICODE_FORMAT;
+}
+
+inline bool isSeparatorSpace(UChar32 c)
+{
+    return g_unichar_type(c) == G_UNICODE_SPACE_SEPARATOR;
+}
+
+inline bool isPrintableChar(UChar32 c)
+{
+    return g_unichar_isprint(c);
+}
+
+inline bool isDigit(UChar32 c)
+{
+    return g_unichar_isdigit(c);
+}
+
+inline bool isPunct(UChar32 c)
+{
+    return g_unichar_ispunct(c);
+}
+
+inline bool hasLineBreakingPropertyComplexContext(UChar32 c)
+{
+    // FIXME
+    return false;
+}
+
+inline bool hasLineBreakingPropertyComplexContextOrIdeographic(UChar32 c)
+{
+    // FIXME
+    return false;
+}
+
+inline UChar32 mirroredChar(UChar32 c)
+{
+    gunichar mirror = 0;
+    g_unichar_get_mirror_char(c, &mirror);
+    return mirror;
+}
+
+inline CharCategory category(UChar32 c)
+{
+    if (c > 0xffff)
+        return NoCategory;
+
+    return (CharCategory) U_MASK(g_unichar_type(c));
+}
+
+Direction direction(UChar32);
+
+inline bool isLower(UChar32 c)
+{
+    return g_unichar_islower(c);
+}
+
+inline int digitValue(UChar32 c)
+{
+    return g_unichar_digit_value(c);
+}
+
+inline uint8_t combiningClass(UChar32 c)
+{
+    // FIXME
+    // return g_unichar_combining_class(c);
+    return 0;
+}
+
+inline DecompositionType decompositionType(UChar32 c)
+{
+    // FIXME
+    return DecompositionNone;
+}
+
+int umemcasecmp(const UChar*, const UChar*, int len);
+
+}
+}
+
+#endif
+
diff --git a/wtf/unicode/glib/UnicodeMacrosFromICU.h b/wtf/unicode/glib/UnicodeMacrosFromICU.h
new file mode 100644 (file)
index 0000000..5d3eca6
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (C) 2006 George Staikos <staikos@kde.org>
+ *  Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com>
+ *  Copyright (C) 2007 Apple Computer, Inc. All rights reserved.
+ *  Copyright (C) 2008 Jürg Billeter <j@bitron.ch>
+ *  Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef UnicodeMacrosFromICU_h
+#define UnicodeMacrosFromICU_h
+
+// some defines from ICU
+
+#define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800)
+#define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00)
+#define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000)
+#define U16_GET_SUPPLEMENTARY(lead, trail) \
+    (((UChar32)(lead)<<10UL)+(UChar32)(trail)-U16_SURROGATE_OFFSET)
+
+#define U16_LEAD(supplementary) (UChar)(((supplementary)>>10)+0xd7c0)
+#define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00)
+
+#define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800)
+#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c)
+#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c)
+#define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0)
+
+#define U16_PREV(s, start, i, c) { \
+    (c)=(s)[--(i)]; \
+    if(U16_IS_TRAIL(c)) { \
+        uint16_t __c2; \
+        if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
+            --(i); \
+            (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
+        } \
+    } \
+}
+
+#define U16_NEXT(s, i, length, c) { \
+    (c)=(s)[(i)++]; \
+    if(U16_IS_LEAD(c)) { \
+        uint16_t __c2; \
+        if((i)<(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \
+            ++(i); \
+            (c)=U16_GET_SUPPLEMENTARY((c), __c2); \
+        } \
+    } \
+}
+
+#define U_MASK(x) ((uint32_t)1<<(x))
+
+#endif
+
index f65e2920fd2f57871c631ad84d97fb2290777234..1531694432f7ff8e7f6adec2ec7db856ba171bb9 100644 (file)
@@ -92,6 +92,17 @@ typedef uint32_t UChar32;
     } \
 }
 
+#define U16_PREV(s, start, i, c) { \
+    (c)=(s)[--(i)]; \
+    if(U16_IS_TRAIL(c)) { \
+        uint16_t __c2; \
+        if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \
+            --(i); \
+            (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \
+        } \
+    } \
+}
+
 #define U_MASK(x) ((uint32_t)1<<(x))
 
 namespace WTF {
index 5f0163c00a3aa69618033ffff4ceff9659c26ef8..9f1eaa68222e2b9e6a6bc299ea5fb74e1b22cc02 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "Assertions.h"
 #include "Threading.h"
-#if !PLATFORM(WIN_CE)
+#if !PLATFORM(WINCE)
 #include <windows.h>
 #endif
 
@@ -50,13 +50,11 @@ LRESULT CALLBACK ThreadingWindowWndProc(HWND hWnd, UINT message, WPARAM wParam,
     return 0;
 }
 
-void initializeMainThread()
+void initializeMainThreadPlatform()
 {
     if (threadingWindowHandle)
         return;
 
-    mainThreadFunctionQueueMutex();
-
     WNDCLASSEX wcex;
     memset(&wcex, 0, sizeof(WNDCLASSEX));
     wcex.cbSize = sizeof(WNDCLASSEX);
@@ -75,4 +73,4 @@ void scheduleDispatchFunctionsOnMainThread()
     PostMessage(threadingWindowHandle, threadingFiredMessage, 0, 0);
 }
 
-} // namespace WebCore
+} // namespace WTF
index 31663311bd077a1c873ecd109c6c930fe9f53a1b..bcd5f0591daa58eda557682996d468c9d896b244 100644 (file)
 
 namespace WTF {
 
-void scheduleDispatchFunctionsOnMainThread()
+void initializeMainThreadPlatform()
 {
 }
 
+void scheduleDispatchFunctionsOnMainThread()
+{
 }
+
+} // namespace WTF
diff --git a/yarr/RegexCompiler.cpp b/yarr/RegexCompiler.cpp
new file mode 100644 (file)
index 0000000..c7b3c81
--- /dev/null
@@ -0,0 +1,728 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "RegexCompiler.h"
+
+#include "RegexInterpreter.h"
+#include "RegexPattern.h"
+#include <wtf/Vector.h>
+
+#if ENABLE(YARR)
+
+using namespace WTF;
+
+namespace JSC { namespace Yarr {
+
+class CharacterClassConstructor {
+public:
+    CharacterClassConstructor(bool isCaseInsensitive = false)
+        : m_isCaseInsensitive(isCaseInsensitive)
+    {
+    }
+    
+    void reset()
+    {
+        m_matches.clear();
+        m_ranges.clear();
+        m_matchesUnicode.clear();
+        m_rangesUnicode.clear();
+    }
+
+    void append(const CharacterClass* other)
+    {
+        for (size_t i = 0; i < other->m_matches.size(); ++i)
+            addSorted(m_matches, other->m_matches[i]);
+        for (size_t i = 0; i < other->m_ranges.size(); ++i)
+            addSortedRange(m_ranges, other->m_ranges[i].begin, other->m_ranges[i].end);
+        for (size_t i = 0; i < other->m_matchesUnicode.size(); ++i)
+            addSorted(m_matchesUnicode, other->m_matchesUnicode[i]);
+        for (size_t i = 0; i < other->m_rangesUnicode.size(); ++i)
+            addSortedRange(m_rangesUnicode, other->m_rangesUnicode[i].begin, other->m_rangesUnicode[i].end);
+    }
+
+    void putChar(UChar ch)
+    {
+        if (ch <= 0x7f) {
+            if (m_isCaseInsensitive && isASCIIAlpha(ch)) {
+                addSorted(m_matches, toASCIIUpper(ch));
+                addSorted(m_matches, toASCIILower(ch));
+            } else
+                addSorted(m_matches, ch);
+        } else {
+            UChar upper, lower;
+            if (m_isCaseInsensitive && ((upper = Unicode::toUpper(ch)) != (lower = Unicode::toLower(ch)))) {
+                addSorted(m_matchesUnicode, upper);
+                addSorted(m_matchesUnicode, lower);
+            } else
+                addSorted(m_matchesUnicode, ch);
+        }
+    }
+
+    // returns true if this character has another case, and 'ch' is the upper case form.
+    static inline bool isUnicodeUpper(UChar ch)
+    {
+        return ch != Unicode::toLower(ch);
+    }
+
+    // returns true if this character has another case, and 'ch' is the lower case form.
+    static inline bool isUnicodeLower(UChar ch)
+    {
+        return ch != Unicode::toUpper(ch);
+    }
+
+    void putRange(UChar lo, UChar hi)
+    {
+        if (lo <= 0x7f) {
+            char asciiLo = lo;
+            char asciiHi = std::min(hi, (UChar)0x7f);
+            addSortedRange(m_ranges, lo, asciiHi);
+            
+            if (m_isCaseInsensitive) {
+                if ((asciiLo <= 'Z') && (asciiHi >= 'A'))
+                    addSortedRange(m_ranges, std::max(asciiLo, 'A')+('a'-'A'), std::min(asciiHi, 'Z')+('a'-'A'));
+                if ((asciiLo <= 'z') && (asciiHi >= 'a'))
+                    addSortedRange(m_ranges, std::max(asciiLo, 'a')+('A'-'a'), std::min(asciiHi, 'z')+('A'-'a'));
+            }
+        }
+        if (hi >= 0x80) {
+            uint32_t unicodeCurr = std::max(lo, (UChar)0x80);
+            addSortedRange(m_rangesUnicode, unicodeCurr, hi);
+            
+            if (m_isCaseInsensitive) {
+                while (unicodeCurr <= hi) {
+                    // If the upper bound of the range (hi) is 0xffff, the increments to
+                    // unicodeCurr in this loop may take it to 0x10000.  This is fine
+                    // (if so we won't re-enter the loop, since the loop condition above
+                    // will definitely fail) - but this does mean we cannot use a UChar
+                    // to represent unicodeCurr, we must use a 32-bit value instead.
+                    ASSERT(unicodeCurr <= 0xffff);
+
+                    if (isUnicodeUpper(unicodeCurr)) {
+                        UChar lowerCaseRangeBegin = Unicode::toLower(unicodeCurr);
+                        UChar lowerCaseRangeEnd = lowerCaseRangeBegin;
+                        while ((++unicodeCurr <= hi) && isUnicodeUpper(unicodeCurr) && (Unicode::toLower(unicodeCurr) == (lowerCaseRangeEnd + 1)))
+                            lowerCaseRangeEnd++;
+                        addSortedRange(m_rangesUnicode, lowerCaseRangeBegin, lowerCaseRangeEnd);
+                    } else if (isUnicodeLower(unicodeCurr)) {
+                        UChar upperCaseRangeBegin = Unicode::toUpper(unicodeCurr);
+                        UChar upperCaseRangeEnd = upperCaseRangeBegin;
+                        while ((++unicodeCurr <= hi) && isUnicodeLower(unicodeCurr) && (Unicode::toUpper(unicodeCurr) == (upperCaseRangeEnd + 1)))
+                            upperCaseRangeEnd++;
+                        addSortedRange(m_rangesUnicode, upperCaseRangeBegin, upperCaseRangeEnd);
+                    } else
+                        ++unicodeCurr;
+                }
+            }
+        }
+    }
+
+    CharacterClass* charClass()
+    {
+        CharacterClass* characterClass = new CharacterClass();
+
+        characterClass->m_matches.append(m_matches);
+        characterClass->m_ranges.append(m_ranges);
+        characterClass->m_matchesUnicode.append(m_matchesUnicode);
+        characterClass->m_rangesUnicode.append(m_rangesUnicode);
+
+        reset();
+
+        return characterClass;
+    }
+
+private:
+    void addSorted(Vector<UChar>& matches, UChar ch)
+    {
+        unsigned pos = 0;
+        unsigned range = matches.size();
+
+        // binary chop, find position to insert char.
+        while (range) {
+            unsigned index = range >> 1;
+
+            int val = matches[pos+index] - ch;
+            if (!val)
+                return;
+            else if (val > 0)
+                range = index;
+            else {
+                pos += (index+1);
+                range -= (index+1);
+            }
+        }
+        
+        if (pos == matches.size())
+            matches.append(ch);
+        else
+            matches.insert(pos, ch);
+    }
+
+    void addSortedRange(Vector<CharacterRange>& ranges, UChar lo, UChar hi)
+    {
+        unsigned end = ranges.size();
+        
+        // Simple linear scan - I doubt there are that many ranges anyway...
+        // feel free to fix this with something faster (eg binary chop).
+        for (unsigned i = 0; i < end; ++i) {
+            // does the new range fall before the current position in the array
+            if (hi < ranges[i].begin) {
+                // optional optimization: concatenate appending ranges? - may not be worthwhile.
+                if (hi == (ranges[i].begin - 1)) {
+                    ranges[i].begin = lo;
+                    return;
+                }
+                ranges.insert(i, CharacterRange(lo, hi));
+                return;
+            }
+            // Okay, since we didn't hit the last case, the end of the new range is definitely at or after the begining
+            // If the new range start at or before the end of the last range, then the overlap (if it starts one after the
+            // end of the last range they concatenate, which is just as good.
+            if (lo <= (ranges[i].end + 1)) {
+                // found an intersect! we'll replace this entry in the array.
+                ranges[i].begin = std::min(ranges[i].begin, lo);
+                ranges[i].end = std::max(ranges[i].end, hi);
+
+                // now check if the new range can subsume any subsequent ranges.
+                unsigned next = i+1;
+                // each iteration of the loop we will either remove something from the list, or break the loop.
+                while (next < ranges.size()) {
+                    if (ranges[next].begin <= (ranges[i].end + 1)) {
+                        // the next entry now overlaps / concatenates this one.
+                        ranges[i].end = std::max(ranges[i].end, ranges[next].end);
+                        ranges.remove(next);
+                    } else
+                        break;
+                }
+                
+                return;
+            }
+        }
+
+        // CharacterRange comes after all existing ranges.
+        ranges.append(CharacterRange(lo, hi));
+    }
+
+    bool m_isCaseInsensitive;
+
+    Vector<UChar> m_matches;
+    Vector<CharacterRange> m_ranges;
+    Vector<UChar> m_matchesUnicode;
+    Vector<CharacterRange> m_rangesUnicode;
+};
+
+
+CharacterClass* newlineCreate()
+{
+    CharacterClass* characterClass = new CharacterClass();
+
+    characterClass->m_matches.append('\n');
+    characterClass->m_matches.append('\r');
+    characterClass->m_matchesUnicode.append(0x2028);
+    characterClass->m_matchesUnicode.append(0x2029);
+    
+    return characterClass;
+}
+
+CharacterClass* digitsCreate()
+{
+    CharacterClass* characterClass = new CharacterClass();
+
+    characterClass->m_ranges.append(CharacterRange('0', '9'));
+    
+    return characterClass;
+}
+
+CharacterClass* spacesCreate()
+{
+    CharacterClass* characterClass = new CharacterClass();
+
+    characterClass->m_matches.append(' ');
+    characterClass->m_ranges.append(CharacterRange('\t', '\r'));
+    characterClass->m_matchesUnicode.append(0x00a0);
+    characterClass->m_matchesUnicode.append(0x1680);
+    characterClass->m_matchesUnicode.append(0x180e);
+    characterClass->m_matchesUnicode.append(0x2028);
+    characterClass->m_matchesUnicode.append(0x2029);
+    characterClass->m_matchesUnicode.append(0x202f);
+    characterClass->m_matchesUnicode.append(0x205f);
+    characterClass->m_matchesUnicode.append(0x3000);
+    characterClass->m_rangesUnicode.append(CharacterRange(0x2000, 0x200a));
+    
+    return characterClass;
+}
+
+CharacterClass* wordcharCreate()
+{
+    CharacterClass* characterClass = new CharacterClass();
+
+    characterClass->m_matches.append('_');
+    characterClass->m_ranges.append(CharacterRange('0', '9'));
+    characterClass->m_ranges.append(CharacterRange('A', 'Z'));
+    characterClass->m_ranges.append(CharacterRange('a', 'z'));
+    
+    return characterClass;
+}
+
+CharacterClass* nondigitsCreate()
+{
+    CharacterClass* characterClass = new CharacterClass();
+
+    characterClass->m_ranges.append(CharacterRange(0, '0' - 1));
+    characterClass->m_ranges.append(CharacterRange('9' + 1, 0x7f));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x80, 0xffff));
+    
+    return characterClass;
+}
+
+CharacterClass* nonspacesCreate()
+{
+    CharacterClass* characterClass = new CharacterClass();
+
+    characterClass->m_ranges.append(CharacterRange(0, '\t' - 1));
+    characterClass->m_ranges.append(CharacterRange('\r' + 1, ' ' - 1));
+    characterClass->m_ranges.append(CharacterRange(' ' + 1, 0x7f));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x0080, 0x009f));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x00a1, 0x167f));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x1681, 0x180d));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x180f, 0x1fff));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x200b, 0x2027));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x202a, 0x202e));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x2030, 0x205e));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x2060, 0x2fff));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x3001, 0xffff));
+    
+    return characterClass;
+}
+
+CharacterClass* nonwordcharCreate()
+{
+    CharacterClass* characterClass = new CharacterClass();
+
+    characterClass->m_matches.append('`');
+    characterClass->m_ranges.append(CharacterRange(0, '0' - 1));
+    characterClass->m_ranges.append(CharacterRange('9' + 1, 'A' - 1));
+    characterClass->m_ranges.append(CharacterRange('Z' + 1, '_' - 1));
+    characterClass->m_ranges.append(CharacterRange('z' + 1, 0x7f));
+    characterClass->m_rangesUnicode.append(CharacterRange(0x80, 0xffff));
+
+    return characterClass;
+}
+
+
+class RegexPatternConstructor {
+public:
+    RegexPatternConstructor(RegexPattern& pattern)
+        : m_pattern(pattern)
+        , m_characterClassConstructor(pattern.m_ignoreCase)
+    {
+    }
+
+    ~RegexPatternConstructor()
+    {
+    }
+
+    void reset()
+    {
+        m_pattern.reset();
+        m_characterClassConstructor.reset();
+    }
+    
+    void assertionBOL()
+    {
+        m_alternative->m_terms.append(PatternTerm::BOL());
+    }
+    void assertionEOL()
+    {
+        m_alternative->m_terms.append(PatternTerm::EOL());
+    }
+    void assertionWordBoundary(bool invert)
+    {
+        m_alternative->m_terms.append(PatternTerm::WordBoundary(invert));
+    }
+
+    void atomPatternCharacter(UChar ch)
+    {
+        // We handle case-insensitive checking of unicode characters which do have both
+        // cases by handling them as if they were defined using a CharacterClass.
+        if (m_pattern.m_ignoreCase && !isASCII(ch) && (Unicode::toUpper(ch) != Unicode::toLower(ch))) {
+            atomCharacterClassBegin();
+            atomCharacterClassAtom(ch);
+            atomCharacterClassEnd();
+        } else
+            m_alternative->m_terms.append(PatternTerm(ch));
+    }
+
+    void atomBuiltInCharacterClass(BuiltInCharacterClassID classID, bool invert)
+    {
+        switch (classID) {
+        case DigitClassID:
+            m_alternative->m_terms.append(PatternTerm(m_pattern.digitsCharacterClass(), invert));
+            break;
+        case SpaceClassID:
+            m_alternative->m_terms.append(PatternTerm(m_pattern.spacesCharacterClass(), invert));
+            break;
+        case WordClassID:
+            m_alternative->m_terms.append(PatternTerm(m_pattern.wordcharCharacterClass(), invert));
+            break;
+        case NewlineClassID:
+            m_alternative->m_terms.append(PatternTerm(m_pattern.newlineCharacterClass(), invert));
+            break;
+        }
+    }
+
+    void atomCharacterClassBegin(bool invert = false)
+    {
+        m_invertCharacterClass = invert;
+    }
+
+    void atomCharacterClassAtom(UChar ch)
+    {
+        m_characterClassConstructor.putChar(ch);
+    }
+
+    void atomCharacterClassRange(UChar begin, UChar end)
+    {
+        m_characterClassConstructor.putRange(begin, end);
+    }
+
+    void atomCharacterClassBuiltIn(BuiltInCharacterClassID classID, bool invert)
+    {
+        ASSERT(classID != NewlineClassID);
+
+        switch (classID) {
+        case DigitClassID:
+            m_characterClassConstructor.append(invert ? m_pattern.nondigitsCharacterClass() : m_pattern.digitsCharacterClass());
+            break;
+        
+        case SpaceClassID:
+            m_characterClassConstructor.append(invert ? m_pattern.nonspacesCharacterClass() : m_pattern.spacesCharacterClass());
+            break;
+        
+        case WordClassID:
+            m_characterClassConstructor.append(invert ? m_pattern.nonwordcharCharacterClass() : m_pattern.wordcharCharacterClass());
+            break;
+        
+        default:
+            ASSERT_NOT_REACHED();
+        }
+    }
+
+    void atomCharacterClassEnd()
+    {
+        CharacterClass* newCharacterClass = m_characterClassConstructor.charClass();
+        m_pattern.m_userCharacterClasses.append(newCharacterClass);
+        m_alternative->m_terms.append(PatternTerm(newCharacterClass, m_invertCharacterClass));
+    }
+
+    void atomParenthesesSubpatternBegin(bool capture = true)
+    {
+        unsigned subpatternId = m_pattern.m_numSubpatterns + 1;
+        if (capture)
+            m_pattern.m_numSubpatterns++;
+
+        PatternDisjunction* parenthesesDisjunction = new PatternDisjunction(m_alternative);
+        m_pattern.m_disjunctions.append(parenthesesDisjunction);
+        m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, capture));
+        m_alternative = parenthesesDisjunction->addNewAlternative();
+    }
+
+    void atomParentheticalAssertionBegin(bool invert = false)
+    {
+        PatternDisjunction* parenthesesDisjunction = new PatternDisjunction(m_alternative);
+        m_pattern.m_disjunctions.append(parenthesesDisjunction);
+        m_alternative->m_terms.append(PatternTerm(PatternTerm::TypeParentheticalAssertion, m_pattern.m_numSubpatterns + 1, parenthesesDisjunction, invert));
+        m_alternative = parenthesesDisjunction->addNewAlternative();
+    }
+
+    void atomParenthesesEnd()
+    {
+        ASSERT(m_alternative->m_parent);
+        ASSERT(m_alternative->m_parent->m_parent);
+        m_alternative = m_alternative->m_parent->m_parent;
+        
+        m_alternative->lastTerm().parentheses.lastSubpatternId = m_pattern.m_numSubpatterns;
+    }
+
+    void atomBackReference(unsigned subpatternId)
+    {
+        ASSERT(subpatternId);
+        m_pattern.m_maxBackReference = std::max(m_pattern.m_maxBackReference, subpatternId);
+
+        if (subpatternId > m_pattern.m_numSubpatterns) {
+            m_alternative->m_terms.append(PatternTerm::ForwardReference());
+            return;
+        }
+
+        PatternAlternative* currentAlternative = m_alternative;
+        ASSERT(currentAlternative);
+
+        // Note to self: if we waited until the AST was baked, we could also remove forwards refs 
+        while ((currentAlternative = currentAlternative->m_parent->m_parent)) {
+            PatternTerm& term = currentAlternative->lastTerm();
+            ASSERT((term.type == PatternTerm::TypeParenthesesSubpattern) || (term.type == PatternTerm::TypeParentheticalAssertion));
+
+            if ((term.type == PatternTerm::TypeParenthesesSubpattern) && term.invertOrCapture && (subpatternId == term.subpatternId)) {
+                m_alternative->m_terms.append(PatternTerm::ForwardReference());
+                return;
+            }
+        }
+
+        m_alternative->m_terms.append(PatternTerm(subpatternId));
+    }
+
+    PatternDisjunction* copyDisjunction(PatternDisjunction* disjunction)
+    {
+        PatternDisjunction* newDisjunction = new PatternDisjunction();
+
+        newDisjunction->m_parent = disjunction->m_parent;
+        for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
+            PatternAlternative* alternative = disjunction->m_alternatives[alt];
+            PatternAlternative* newAlternative = newDisjunction->addNewAlternative();
+            for (unsigned i = 0; i < alternative->m_terms.size(); ++i)
+                newAlternative->m_terms.append(copyTerm(alternative->m_terms[i]));
+        }
+
+        m_pattern.m_disjunctions.append(newDisjunction);
+        return newDisjunction;
+    }
+
+    PatternTerm copyTerm(PatternTerm& term)
+    {
+        if ((term.type != PatternTerm::TypeParenthesesSubpattern) && (term.type != PatternTerm::TypeParentheticalAssertion))
+            return PatternTerm(term);
+
+        PatternTerm termCopy = term;
+        termCopy.parentheses.disjunction = copyDisjunction(termCopy.parentheses.disjunction);
+        return termCopy;
+    }
+
+    void quantifyAtom(unsigned min, unsigned max, bool greedy)
+    {
+        ASSERT(min <= max);
+        ASSERT(m_alternative->m_terms.size());
+
+        if (!max) {
+            m_alternative->removeLastTerm();
+            return;
+        }
+
+        PatternTerm& term = m_alternative->lastTerm();
+        ASSERT(term.type > PatternTerm::TypeAssertionWordBoundary);
+        ASSERT((term.quantityCount == 1) && (term.quantityType == QuantifierFixedCount));
+
+        // For any assertion with a zero minimum, not matching is valid and has no effect,
+        // remove it.  Otherwise, we need to match as least once, but there is no point
+        // matching more than once, so remove the quantifier.  It is not entirely clear
+        // from the spec whether or not this behavior is correct, but I believe this
+        // matches Firefox. :-/
+        if (term.type == PatternTerm::TypeParentheticalAssertion) {
+            if (!min)
+                m_alternative->removeLastTerm();
+            return;
+        }
+
+        if (min == 0)
+            term.quantify(max, greedy   ? QuantifierGreedy : QuantifierNonGreedy);
+        else if (min == max)
+            term.quantify(min, QuantifierFixedCount);
+        else {
+            term.quantify(min, QuantifierFixedCount);
+            m_alternative->m_terms.append(copyTerm(term));
+            // NOTE: this term is interesting from an analysis perspective, in that it can be ignored.....
+            m_alternative->lastTerm().quantify((max == UINT_MAX) ? max : max - min, greedy ? QuantifierGreedy : QuantifierNonGreedy);
+            if (m_alternative->lastTerm().type == PatternTerm::TypeParenthesesSubpattern)
+                m_alternative->lastTerm().parentheses.isCopy = true;
+        }
+    }
+
+    void disjunction()
+    {
+        m_alternative = m_alternative->m_parent->addNewAlternative();
+    }
+
+    void regexBegin()
+    {
+        m_pattern.m_body = new PatternDisjunction();
+        m_alternative = m_pattern.m_body->addNewAlternative();
+        m_pattern.m_disjunctions.append(m_pattern.m_body);
+    }
+    void regexEnd()
+    {
+    }
+    void regexError()
+    {
+    }
+
+    unsigned setupAlternativeOffsets(PatternAlternative* alternative, unsigned currentCallFrameSize, unsigned initialInputPosition)
+    {
+        alternative->m_hasFixedSize = true;
+        unsigned currentInputPosition = initialInputPosition;
+
+        for (unsigned i = 0; i < alternative->m_terms.size(); ++i) {
+            PatternTerm& term = alternative->m_terms[i];
+
+            switch (term.type) {
+            case PatternTerm::TypeAssertionBOL:
+            case PatternTerm::TypeAssertionEOL:
+            case PatternTerm::TypeAssertionWordBoundary:
+                term.inputPosition = currentInputPosition;
+                break;
+
+            case PatternTerm::TypeBackReference:
+                term.inputPosition = currentInputPosition;
+                term.frameLocation = currentCallFrameSize;
+                currentCallFrameSize += RegexStackSpaceForBackTrackInfoBackReference;
+                alternative->m_hasFixedSize = false;
+                break;
+
+            case PatternTerm::TypeForwardReference:
+                break;
+
+            case PatternTerm::TypePatternCharacter:
+                term.inputPosition = currentInputPosition;
+                if (term.quantityType != QuantifierFixedCount) {
+                    term.frameLocation = currentCallFrameSize;
+                    currentCallFrameSize += RegexStackSpaceForBackTrackInfoPatternCharacter;
+                    alternative->m_hasFixedSize = false;
+                } else
+                    currentInputPosition += term.quantityCount;
+                break;
+
+            case PatternTerm::TypeCharacterClass:
+                term.inputPosition = currentInputPosition;
+                if (term.quantityType != QuantifierFixedCount) {
+                    term.frameLocation = currentCallFrameSize;
+                    currentCallFrameSize += RegexStackSpaceForBackTrackInfoCharacterClass;
+                    alternative->m_hasFixedSize = false;
+                } else
+                    currentInputPosition += term.quantityCount;
+                break;
+
+            case PatternTerm::TypeParenthesesSubpattern:
+                // Note: for fixed once parentheses we will ensure at least the minimum is available; others are on their own.
+                term.frameLocation = currentCallFrameSize;
+                if ((term.quantityCount == 1) && !term.parentheses.isCopy) {
+                    if (term.quantityType == QuantifierFixedCount) {
+                        currentCallFrameSize = setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize, currentInputPosition);
+                        currentInputPosition += term.parentheses.disjunction->m_minimumSize;
+                    } else {
+                        currentCallFrameSize += RegexStackSpaceForBackTrackInfoParenthesesOnce;
+                        currentCallFrameSize = setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize, currentInputPosition);
+                    }
+                    term.inputPosition = currentInputPosition;
+                } else {
+                    term.inputPosition = currentInputPosition;
+                    setupDisjunctionOffsets(term.parentheses.disjunction, 0, currentInputPosition);
+                    currentCallFrameSize += RegexStackSpaceForBackTrackInfoParentheses;
+                }
+                // Fixed count of 1 could be accepted, if they have a fixed size *AND* if all alternatives are of the same length.
+                alternative->m_hasFixedSize = false;
+                break;
+
+            case PatternTerm::TypeParentheticalAssertion:
+                term.inputPosition = currentInputPosition;
+                term.frameLocation = currentCallFrameSize;
+                currentCallFrameSize = setupDisjunctionOffsets(term.parentheses.disjunction, currentCallFrameSize + RegexStackSpaceForBackTrackInfoParentheticalAssertion, currentInputPosition);
+                break;
+            }
+        }
+
+        alternative->m_minimumSize = currentInputPosition - initialInputPosition;
+        return currentCallFrameSize;
+    }
+
+    unsigned setupDisjunctionOffsets(PatternDisjunction* disjunction, unsigned initialCallFrameSize, unsigned initialInputPosition)
+    {
+        if ((disjunction != m_pattern.m_body) && (disjunction->m_alternatives.size() > 1))
+            initialCallFrameSize += RegexStackSpaceForBackTrackInfoAlternative;
+
+        unsigned minimumInputSize = UINT_MAX;
+        unsigned maximumCallFrameSize = 0;
+        bool hasFixedSize = true;
+
+        for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
+            PatternAlternative* alternative = disjunction->m_alternatives[alt];
+            unsigned currentAlternativeCallFrameSize = setupAlternativeOffsets(alternative, initialCallFrameSize, initialInputPosition);
+            minimumInputSize = min(minimumInputSize, alternative->m_minimumSize);
+            maximumCallFrameSize = max(maximumCallFrameSize, currentAlternativeCallFrameSize);
+            hasFixedSize &= alternative->m_hasFixedSize;
+        }
+        
+        ASSERT(minimumInputSize != UINT_MAX);
+        ASSERT(maximumCallFrameSize >= initialCallFrameSize);
+
+        disjunction->m_hasFixedSize = hasFixedSize;
+        disjunction->m_minimumSize = minimumInputSize;
+        disjunction->m_callFrameSize = maximumCallFrameSize;
+        return maximumCallFrameSize;
+    }
+
+    void setupOffsets()
+    {
+        setupDisjunctionOffsets(m_pattern.m_body, 0, 0);
+    }
+
+private:
+    RegexPattern& m_pattern;
+    PatternAlternative* m_alternative;
+    CharacterClassConstructor m_characterClassConstructor;
+    bool m_invertCharacterClass;
+};
+
+
+const char* compileRegex(const UString& patternString, RegexPattern& pattern)
+{
+    RegexPatternConstructor constructor(pattern);
+
+    if (const char* error = parse(constructor, patternString))
+        return error;
+    
+    // If the pattern contains illegal backreferences reset & reparse.
+    // Quoting Netscape's "What's new in JavaScript 1.2",
+    //      "Note: if the number of left parentheses is less than the number specified
+    //       in \#, the \# is taken as an octal escape as described in the next row."
+    if (pattern.containsIllegalBackReference()) {
+        unsigned numSubpatterns = pattern.m_numSubpatterns;
+
+        constructor.reset();
+#ifndef NDEBUG
+        const char* error =
+#endif
+            parse(constructor, patternString, numSubpatterns);
+
+        ASSERT(!error);
+        ASSERT(numSubpatterns == pattern.m_numSubpatterns);
+    }
+
+    constructor.setupOffsets();
+
+    return false;
+};
+
+
+} }
+
+#endif
diff --git a/yarr/RegexCompiler.h b/yarr/RegexCompiler.h
new file mode 100644 (file)
index 0000000..3ed2be9
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RegexCompiler_h
+#define RegexCompiler_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(YARR)
+
+#include <wtf/unicode/Unicode.h>
+#include "RegexParser.h"
+#include "RegexPattern.h"
+
+namespace JSC { namespace Yarr {
+
+const char* compileRegex(const UString& patternString, RegexPattern& pattern);
+
+} } // namespace JSC::Yarr
+
+#endif
+
+#endif // RegexCompiler_h
diff --git a/yarr/RegexInterpreter.cpp b/yarr/RegexInterpreter.cpp
new file mode 100644 (file)
index 0000000..b0aae65
--- /dev/null
@@ -0,0 +1,1638 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "RegexInterpreter.h"
+
+#include "RegexCompiler.h"
+#include "RegexPattern.h"
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+#if ENABLE(YARR)
+
+using namespace WTF;
+
+namespace JSC { namespace Yarr {
+
+class Interpreter {
+public:
+    struct ParenthesesDisjunctionContext;
+
+    struct BackTrackInfoPatternCharacter {
+        uintptr_t matchAmount;
+    };
+    struct BackTrackInfoCharacterClass {
+        uintptr_t matchAmount;
+    };
+    struct BackTrackInfoBackReference {
+        uintptr_t begin; // Not really needed for greedy quantifiers.
+        uintptr_t matchAmount; // Not really needed for fixed quantifiers.
+    };
+    struct BackTrackInfoAlternative {
+        uintptr_t offset;
+    };
+    struct BackTrackInfoParentheticalAssertion {
+        uintptr_t begin;
+    };
+    struct BackTrackInfoParenthesesOnce {
+        uintptr_t inParentheses;
+    };
+    struct BackTrackInfoParentheses {
+        uintptr_t matchAmount;
+        ParenthesesDisjunctionContext* lastContext;
+        uintptr_t prevBegin;
+        uintptr_t prevEnd;
+    };
+
+    static inline void appendParenthesesDisjunctionContext(BackTrackInfoParentheses* backTrack, ParenthesesDisjunctionContext* context)
+    {
+        context->next = backTrack->lastContext;
+        backTrack->lastContext = context;
+        ++backTrack->matchAmount;
+    }
+
+    static inline void popParenthesesDisjunctionContext(BackTrackInfoParentheses* backTrack)
+    {
+        ASSERT(backTrack->matchAmount);
+        ASSERT(backTrack->lastContext);
+        backTrack->lastContext = backTrack->lastContext->next;
+        --backTrack->matchAmount;
+    }
+
+    struct DisjunctionContext
+    {
+        DisjunctionContext()
+            : term(0)
+        {
+        }
+        
+        void* operator new(size_t, void* where)
+        {
+            return where;
+        }
+
+        int term;
+        unsigned matchBegin;
+        unsigned matchEnd;
+        uintptr_t frame[1];
+    };
+
+    DisjunctionContext* allocDisjunctionContext(ByteDisjunction* disjunction)
+    {
+        return new(malloc(sizeof(DisjunctionContext) + (disjunction->m_frameSize - 1) * sizeof(uintptr_t))) DisjunctionContext();
+    }
+
+    void freeDisjunctionContext(DisjunctionContext* context)
+    {
+        free(context);
+    }
+
+    struct ParenthesesDisjunctionContext
+    {
+        ParenthesesDisjunctionContext(int* output, ByteTerm& term)
+            : next(0)
+        {
+            unsigned firstSubpatternId = term.atom.subpatternId;
+            unsigned numNestedSubpatterns = term.atom.parenthesesDisjunction->m_numSubpatterns;
+
+            for (unsigned i = 0; i < (numNestedSubpatterns << 1); ++i) {
+                subpatternBackup[i] = output[(firstSubpatternId << 1) + i];
+                output[(firstSubpatternId << 1) + i] = -1;
+            }
+            
+            new(getDisjunctionContext(term)) DisjunctionContext();
+        }
+
+        void* operator new(size_t, void* where)
+        {
+            return where;
+        }
+
+        void restoreOutput(int* output, unsigned firstSubpatternId, unsigned numNestedSubpatterns)
+        {
+            for (unsigned i = 0; i < (numNestedSubpatterns << 1); ++i)
+                output[(firstSubpatternId << 1) + i] = subpatternBackup[i];
+        }
+        
+        DisjunctionContext* getDisjunctionContext(ByteTerm& term)
+        {
+            return reinterpret_cast<DisjunctionContext*>(&(subpatternBackup[term.atom.parenthesesDisjunction->m_numSubpatterns << 1]));
+        }
+
+        ParenthesesDisjunctionContext* next;
+        int subpatternBackup[1];
+    };
+
+    ParenthesesDisjunctionContext* allocParenthesesDisjunctionContext(ByteDisjunction* disjunction, int* output, ByteTerm& term)
+    {
+        return new(malloc(sizeof(ParenthesesDisjunctionContext) + (((term.atom.parenthesesDisjunction->m_numSubpatterns << 1) - 1) * sizeof(int)) + sizeof(DisjunctionContext) + (disjunction->m_frameSize - 1) * sizeof(uintptr_t))) ParenthesesDisjunctionContext(output, term);
+    }
+
+    void freeParenthesesDisjunctionContext(ParenthesesDisjunctionContext* context)
+    {
+        free(context);
+    }
+
+    class InputStream {
+    public:
+        InputStream(const UChar* input, unsigned start, unsigned length)
+            : input(input)
+            , pos(start)
+            , length(length)
+        {
+        }
+
+        void next()
+        {
+            ++pos;
+        }
+
+        void rewind(unsigned amount)
+        {
+            ASSERT(pos >= amount);
+            pos -= amount;
+        }
+
+        int read()
+        {
+            ASSERT(pos < length);
+            if (pos < length)
+                return input[pos];
+            return -1;
+        }
+
+        int readChecked(int position)
+        {
+            ASSERT(position < 0);
+            ASSERT((unsigned)-position <= pos);
+            unsigned p = pos + position;
+            ASSERT(p < length);
+            return input[p];
+        }
+
+        int reread(unsigned from)
+        {
+            ASSERT(from < length);
+            return input[from];
+        }
+
+        int prev()
+        {
+            ASSERT(!(pos > length));
+            if (pos && length)
+                return input[pos - 1];
+            return -1;
+        }
+        
+        unsigned getPos()
+        {
+            return pos;
+        }
+
+        void setPos(unsigned p)
+        {
+            pos = p;
+        }
+        
+        bool atStart()
+        {
+            return pos == 0;
+        }
+
+        bool atEnd()
+        {
+            return pos == length;
+        }
+
+        bool checkInput(int count)
+        {
+            if ((pos + count) <= length) {
+                pos += count;
+                return true;
+            } else
+                return false;
+        }
+
+        void uncheckInput(int count)
+        {
+            pos -= count;
+        }
+
+        bool atStart(int position)
+        {
+            return (pos + position) == 0;
+        }
+
+        bool atEnd(int position)
+        {
+            return (pos + position) == length;
+        }
+
+    private:
+        const UChar* input;
+        unsigned pos;
+        unsigned length;
+    };
+
+    bool testCharacterClass(CharacterClass* characterClass, int ch)
+    {
+        if (ch & 0xFF80) {
+            for (unsigned i = 0; i < characterClass->m_matchesUnicode.size(); ++i)
+                if (ch == characterClass->m_matchesUnicode[i])
+                    return true;
+            for (unsigned i = 0; i < characterClass->m_rangesUnicode.size(); ++i)
+                if ((ch >= characterClass->m_rangesUnicode[i].begin) && (ch <= characterClass->m_rangesUnicode[i].end))
+                    return true;
+        } else {
+            for (unsigned i = 0; i < characterClass->m_matches.size(); ++i)
+                if (ch == characterClass->m_matches[i])
+                    return true;
+            for (unsigned i = 0; i < characterClass->m_ranges.size(); ++i)
+                if ((ch >= characterClass->m_ranges[i].begin) && (ch <= characterClass->m_ranges[i].end))
+                    return true;
+        }
+
+        return false;
+    }
+
+    bool tryConsumeCharacter(int testChar)
+    {
+        if (input.atEnd())
+            return false;
+        
+        int ch = input.read();
+
+        if (pattern->m_ignoreCase ? ((Unicode::toLower(testChar) == ch) || (Unicode::toUpper(testChar) == ch)) : (testChar == ch)) {
+            input.next();
+            return true;
+        }
+        return false;
+    }
+
+    bool checkCharacter(int testChar, int inputPosition)
+    {
+        return testChar == input.readChecked(inputPosition);
+    }
+
+    bool checkCasedCharacter(int loChar, int hiChar, int inputPosition)
+    {
+        int ch = input.readChecked(inputPosition);
+        return (loChar == ch) || (hiChar == ch);
+    }
+
+    bool tryConsumeCharacterClass(CharacterClass* characterClass, bool invert)
+    {
+        if (input.atEnd())
+            return false;
+
+        bool match = testCharacterClass(characterClass, input.read());
+
+        if (invert)
+            match = !match;
+
+        if (match) {
+            input.next();
+            return true;
+        }
+        return false;
+    }
+
+    bool checkCharacterClass(CharacterClass* characterClass, bool invert, int inputPosition)
+    {
+        bool match = testCharacterClass(characterClass, input.readChecked(inputPosition));
+        return invert ? !match : match;
+    }
+
+    bool tryConsumeBackReference(int matchBegin, int matchEnd, int inputOffset)
+    {
+        int matchSize = matchEnd - matchBegin;
+
+        if (!input.checkInput(matchSize))
+            return false;
+
+        for (int i = 0; i < matchSize; ++i) {
+            if (!checkCharacter(input.reread(matchBegin + i), inputOffset - matchSize + i)) {
+                input.uncheckInput(matchSize);
+                return false;
+            }
+        }
+        
+        return true;
+    }
+
+    bool matchAssertionBOL(ByteTerm& term)
+    {
+        return (input.atStart(term.inputPosition)) || (pattern->m_multiline && testCharacterClass(pattern->newlineCharacterClass, input.readChecked(term.inputPosition - 1)));
+    }
+
+    bool matchAssertionEOL(ByteTerm& term)
+    {
+        if (term.inputPosition)
+            return (input.atEnd(term.inputPosition)) || (pattern->m_multiline && testCharacterClass(pattern->newlineCharacterClass, input.readChecked(term.inputPosition)));
+        else
+            return (input.atEnd()) || (pattern->m_multiline && testCharacterClass(pattern->newlineCharacterClass, input.read()));
+    }
+
+    bool matchAssertionWordBoundary(ByteTerm& term)
+    {
+        bool prevIsWordchar = !input.atStart(term.inputPosition) && testCharacterClass(pattern->wordcharCharacterClass, input.readChecked(term.inputPosition - 1));
+        bool readIsWordchar;
+        if (term.inputPosition)
+            readIsWordchar = !input.atEnd(term.inputPosition) && testCharacterClass(pattern->wordcharCharacterClass, input.readChecked(term.inputPosition));
+        else
+            readIsWordchar = !input.atEnd() && testCharacterClass(pattern->wordcharCharacterClass, input.read());
+
+        bool wordBoundary = prevIsWordchar != readIsWordchar;
+        return term.invert() ? !wordBoundary : wordBoundary;
+    }
+
+    bool backtrackPatternCharacter(ByteTerm& term, DisjunctionContext* context)
+    {
+        BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + term.frameLocation);
+
+        switch (term.atom.quantityType) {
+        case QuantifierFixedCount:
+            break;
+
+        case QuantifierGreedy:
+            if (backTrack->matchAmount) {
+                --backTrack->matchAmount;
+                input.uncheckInput(1);
+                return true;
+            }
+            break;
+
+        case QuantifierNonGreedy:
+            if ((backTrack->matchAmount < term.atom.quantityCount) && input.checkInput(1)) {
+                ++backTrack->matchAmount;
+                if (checkCharacter(term.atom.patternCharacter, term.inputPosition - 1))
+                    return true;
+            }
+            input.uncheckInput(backTrack->matchAmount);
+            break;
+        }
+
+        return false;
+    }
+
+    bool backtrackPatternCasedCharacter(ByteTerm& term, DisjunctionContext* context)
+    {
+        BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + term.frameLocation);
+
+        switch (term.atom.quantityType) {
+        case QuantifierFixedCount:
+            break;
+
+        case QuantifierGreedy:
+            if (backTrack->matchAmount) {
+                --backTrack->matchAmount;
+                input.uncheckInput(1);
+                return true;
+            }
+            break;
+
+        case QuantifierNonGreedy:
+            if ((backTrack->matchAmount < term.atom.quantityCount) && input.checkInput(1)) {
+                ++backTrack->matchAmount;
+                if (checkCasedCharacter(term.atom.casedCharacter.lo, term.atom.casedCharacter.hi, term.inputPosition - 1))
+                    return true;
+            }
+            input.uncheckInput(backTrack->matchAmount);
+            break;
+        }
+
+        return false;
+    }
+
+    bool matchCharacterClass(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeCharacterClass);
+        BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + term.frameLocation);
+
+        switch (term.atom.quantityType) {
+        case QuantifierFixedCount: {
+            for (unsigned matchAmount = 0; matchAmount < term.atom.quantityCount; ++matchAmount) {
+                if (!checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition + matchAmount))
+                    return false;
+            }
+            return true;
+        }
+
+        case QuantifierGreedy: {
+            unsigned matchAmount = 0;
+            while ((matchAmount < term.atom.quantityCount) && input.checkInput(1)) {
+                if (!checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition - 1)) {
+                    input.uncheckInput(1);
+                    break;
+                }
+                ++matchAmount;
+            }
+            backTrack->matchAmount = matchAmount;
+
+            return true;
+        }
+
+        case QuantifierNonGreedy:
+            backTrack->matchAmount = 0;
+            return true;
+        }
+
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    bool backtrackCharacterClass(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeCharacterClass);
+        BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + term.frameLocation);
+
+        switch (term.atom.quantityType) {
+        case QuantifierFixedCount:
+            break;
+
+        case QuantifierGreedy:
+            if (backTrack->matchAmount) {
+                --backTrack->matchAmount;
+                input.uncheckInput(1);
+                return true;
+            }
+            break;
+
+        case QuantifierNonGreedy:
+            if ((backTrack->matchAmount < term.atom.quantityCount) && input.checkInput(1)) {
+                ++backTrack->matchAmount;
+                if (checkCharacterClass(term.atom.characterClass, term.invert(), term.inputPosition - 1))
+                    return true;
+            }
+            input.uncheckInput(backTrack->matchAmount);
+            break;
+        }
+
+        return false;
+    }
+
+    bool matchBackReference(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeBackReference);
+        BackTrackInfoBackReference* backTrack = reinterpret_cast<BackTrackInfoBackReference*>(context->frame + term.frameLocation);
+
+        int matchBegin = output[(term.atom.subpatternId << 1)];
+        int matchEnd = output[(term.atom.subpatternId << 1) + 1];
+        ASSERT((matchBegin == -1) == (matchEnd == -1));
+        ASSERT(matchBegin <= matchEnd);
+
+        if (matchBegin == matchEnd)
+            return true;
+
+        switch (term.atom.quantityType) {
+        case QuantifierFixedCount: {
+            backTrack->begin = input.getPos();
+            for (unsigned matchAmount = 0; matchAmount < term.atom.quantityCount; ++matchAmount) {
+                if (!tryConsumeBackReference(matchBegin, matchEnd, term.inputPosition)) {
+                    input.setPos(backTrack->begin);
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        case QuantifierGreedy: {
+            unsigned matchAmount = 0;
+            while ((matchAmount < term.atom.quantityCount) && tryConsumeBackReference(matchBegin, matchEnd, term.inputPosition))
+                ++matchAmount;
+            backTrack->matchAmount = matchAmount;
+            return true;
+        }
+
+        case QuantifierNonGreedy:
+            backTrack->begin = input.getPos();
+            backTrack->matchAmount = 0;
+            return true;
+        }
+
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    bool backtrackBackReference(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeBackReference);
+        BackTrackInfoBackReference* backTrack = reinterpret_cast<BackTrackInfoBackReference*>(context->frame + term.frameLocation);
+
+        int matchBegin = output[(term.atom.subpatternId << 1)];
+        int matchEnd = output[(term.atom.subpatternId << 1) + 1];
+        ASSERT((matchBegin == -1) == (matchEnd == -1));
+        ASSERT(matchBegin <= matchEnd);
+
+        if (matchBegin == matchEnd)
+            return false;
+
+        switch (term.atom.quantityType) {
+        case QuantifierFixedCount:
+            // for quantityCount == 1, could rewind.
+            input.setPos(backTrack->begin);
+            break;
+
+        case QuantifierGreedy:
+            if (backTrack->matchAmount) {
+                --backTrack->matchAmount;
+                input.rewind(matchEnd - matchBegin);
+                return true;
+            }
+            break;
+
+        case QuantifierNonGreedy:
+            if ((backTrack->matchAmount < term.atom.quantityCount) && tryConsumeBackReference(matchBegin, matchEnd, term.inputPosition)) {
+                ++backTrack->matchAmount;
+                return true;
+            } else
+                input.setPos(backTrack->begin);
+            break;
+        }
+
+        return false;
+    }
+
+    void recordParenthesesMatch(ByteTerm& term, ParenthesesDisjunctionContext* context)
+    {
+        if (term.capture()) {
+            unsigned subpatternId = term.atom.subpatternId;
+            output[(subpatternId << 1)] = context->getDisjunctionContext(term)->matchBegin + term.inputPosition;
+            output[(subpatternId << 1) + 1] = context->getDisjunctionContext(term)->matchEnd + term.inputPosition;
+        }
+    }
+    void resetMatches(ByteTerm& term, ParenthesesDisjunctionContext* context)
+    {
+        unsigned firstSubpatternId = term.atom.subpatternId;
+        unsigned count = term.atom.parenthesesDisjunction->m_numSubpatterns;
+        context->restoreOutput(output, firstSubpatternId, count);
+    }
+    void resetAssertionMatches(ByteTerm& term)
+    {
+        unsigned firstSubpatternId = term.atom.subpatternId;
+        unsigned count = term.atom.parenthesesDisjunction->m_numSubpatterns;
+        for (unsigned i = 0; i < (count << 1); ++i)
+            output[(firstSubpatternId << 1) + i] = -1;
+    }
+    bool parenthesesDoBacktrack(ByteTerm& term, BackTrackInfoParentheses* backTrack)
+    {
+        while (backTrack->matchAmount) {
+            ParenthesesDisjunctionContext* context = backTrack->lastContext;
+
+            if (matchDisjunction(term.atom.parenthesesDisjunction, context->getDisjunctionContext(term), true))
+                return true;
+            
+            resetMatches(term, context);
+            freeParenthesesDisjunctionContext(context);
+            popParenthesesDisjunctionContext(backTrack);
+        }
+
+        return false;
+    }
+
+    bool matchParenthesesOnceBegin(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeParenthesesSubpatternOnceBegin);
+        ASSERT(term.atom.quantityCount == 1);
+
+        BackTrackInfoParenthesesOnce* backTrack = reinterpret_cast<BackTrackInfoParenthesesOnce*>(context->frame + term.frameLocation);
+
+        switch (term.atom.quantityType) {
+        case QuantifierGreedy: {
+            // set this speculatively; if we get to the parens end this will be true.
+            backTrack->inParentheses = 1;
+            break;
+        }
+        case QuantifierNonGreedy: {
+            backTrack->inParentheses = 0;
+            context->term += term.atom.parenthesesWidth;
+            return true;
+        }
+        case QuantifierFixedCount:
+            break;
+        }
+
+        if (term.capture()) {
+            unsigned subpatternId = term.atom.subpatternId;
+            output[(subpatternId << 1)] = input.getPos() + term.inputPosition;
+        }
+
+        return true;
+    }
+
+    bool matchParenthesesOnceEnd(ByteTerm& term, DisjunctionContext*)
+    {
+        ASSERT(term.type == ByteTerm::TypeParenthesesSubpatternOnceEnd);
+        ASSERT(term.atom.quantityCount == 1);
+
+        if (term.capture()) {
+            unsigned subpatternId = term.atom.subpatternId;
+            output[(subpatternId << 1) + 1] = input.getPos() + term.inputPosition;
+        }
+        return true;
+    }
+
+    bool backtrackParenthesesOnceBegin(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeParenthesesSubpatternOnceBegin);
+        ASSERT(term.atom.quantityCount == 1);
+
+        BackTrackInfoParenthesesOnce* backTrack = reinterpret_cast<BackTrackInfoParenthesesOnce*>(context->frame + term.frameLocation);
+
+        if (term.capture()) {
+            unsigned subpatternId = term.atom.subpatternId;
+            output[(subpatternId << 1)] = -1;
+            output[(subpatternId << 1) + 1] = -1;
+        }
+
+        switch (term.atom.quantityType) {
+        case QuantifierGreedy:
+            // if we backtrack to this point, there is another chance - try matching nothing.
+            ASSERT(backTrack->inParentheses);
+            backTrack->inParentheses = 0;
+            context->term += term.atom.parenthesesWidth;
+            return true;
+        case QuantifierNonGreedy:
+            ASSERT(backTrack->inParentheses);
+        case QuantifierFixedCount:
+            break;
+        }
+
+        return false;
+    }
+
+    bool backtrackParenthesesOnceEnd(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeParenthesesSubpatternOnceEnd);
+        ASSERT(term.atom.quantityCount == 1);
+
+        BackTrackInfoParenthesesOnce* backTrack = reinterpret_cast<BackTrackInfoParenthesesOnce*>(context->frame + term.frameLocation);
+
+        switch (term.atom.quantityType) {
+        case QuantifierGreedy:
+            if (!backTrack->inParentheses) {
+                context->term -= term.atom.parenthesesWidth;
+                return false;
+            }
+        case QuantifierNonGreedy:
+            if (!backTrack->inParentheses) {
+                // now try to match the parens; set this speculatively.
+                backTrack->inParentheses = 1;
+                if (term.capture()) {
+                    unsigned subpatternId = term.atom.subpatternId;
+                    output[(subpatternId << 1) + 1] = input.getPos() + term.inputPosition;
+                }
+                context->term -= term.atom.parenthesesWidth;
+                return true;
+            }
+        case QuantifierFixedCount:
+            break;
+        }
+
+        return false;
+    }
+
+    bool matchParentheticalAssertionBegin(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeParentheticalAssertionBegin);
+        ASSERT(term.atom.quantityCount == 1);
+
+        BackTrackInfoParentheticalAssertion* backTrack = reinterpret_cast<BackTrackInfoParentheticalAssertion*>(context->frame + term.frameLocation);
+
+        backTrack->begin = input.getPos();
+        return true;
+    }
+
+    bool matchParentheticalAssertionEnd(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeParentheticalAssertionEnd);
+        ASSERT(term.atom.quantityCount == 1);
+
+        BackTrackInfoParentheticalAssertion* backTrack = reinterpret_cast<BackTrackInfoParentheticalAssertion*>(context->frame + term.frameLocation);
+
+        input.setPos(backTrack->begin);
+
+        // We've reached the end of the parens; if they are inverted, this is failure.
+        if (term.invert()) {
+            context->term -= term.atom.parenthesesWidth;
+            return false;
+        }
+
+        return true;
+    }
+
+    bool backtrackParentheticalAssertionBegin(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeParentheticalAssertionBegin);
+        ASSERT(term.atom.quantityCount == 1);
+
+        // We've failed to match parens; if they are inverted, this is win!
+        if (term.invert()) {
+            context->term += term.atom.parenthesesWidth;
+            return true;
+        }
+
+        return false;
+    }
+
+    bool backtrackParentheticalAssertionEnd(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeParentheticalAssertionEnd);
+        ASSERT(term.atom.quantityCount == 1);
+
+        BackTrackInfoParentheticalAssertion* backTrack = reinterpret_cast<BackTrackInfoParentheticalAssertion*>(context->frame + term.frameLocation);
+
+        input.setPos(backTrack->begin);
+
+        context->term -= term.atom.parenthesesWidth;
+        return false;
+    }
+
+    bool matchParentheses(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeParenthesesSubpattern);
+
+        BackTrackInfoParentheses* backTrack = reinterpret_cast<BackTrackInfoParentheses*>(context->frame + term.frameLocation);
+
+        unsigned subpatternId = term.atom.subpatternId;
+        ByteDisjunction* disjunctionBody = term.atom.parenthesesDisjunction;
+
+        backTrack->prevBegin = output[(subpatternId << 1)];
+        backTrack->prevEnd = output[(subpatternId << 1) + 1];
+
+        backTrack->matchAmount = 0;
+        backTrack->lastContext = 0;
+
+        switch (term.atom.quantityType) {
+        case QuantifierFixedCount: {
+            // While we haven't yet reached our fixed limit,
+            while (backTrack->matchAmount < term.atom.quantityCount) {
+                // Try to do a match, and it it succeeds, add it to the list.
+                ParenthesesDisjunctionContext* context = allocParenthesesDisjunctionContext(disjunctionBody, output, term);
+                if (matchDisjunction(disjunctionBody, context->getDisjunctionContext(term)))
+                    appendParenthesesDisjunctionContext(backTrack, context);
+                else {
+                    // The match failed; try to find an alternate point to carry on from.
+                    resetMatches(term, context);
+                    freeParenthesesDisjunctionContext(context);
+                    if (!parenthesesDoBacktrack(term, backTrack))
+                        return false;
+                }
+            }
+
+            ASSERT(backTrack->matchAmount == term.atom.quantityCount);
+            ParenthesesDisjunctionContext* context = backTrack->lastContext;
+            recordParenthesesMatch(term, context);
+            return true;
+        }
+
+        case QuantifierGreedy: {
+            while (backTrack->matchAmount < term.atom.quantityCount) {
+                ParenthesesDisjunctionContext* context = allocParenthesesDisjunctionContext(disjunctionBody, output, term);
+                if (matchNonZeroDisjunction(disjunctionBody, context->getDisjunctionContext(term)))
+                    appendParenthesesDisjunctionContext(backTrack, context);
+                else {
+                    resetMatches(term, context);
+                    freeParenthesesDisjunctionContext(context);
+                    break;
+                }
+            }
+
+            if (backTrack->matchAmount) {
+                ParenthesesDisjunctionContext* context = backTrack->lastContext;
+                recordParenthesesMatch(term, context);
+            }
+            return true;
+        }
+
+        case QuantifierNonGreedy:
+            return true;
+        }
+
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    // Rules for backtracking differ depending on whether this is greedy or non-greedy.
+    //
+    // Greedy matches never should try just adding more - you should already have done
+    // the 'more' cases.  Always backtrack, at least a leetle bit.  However cases where
+    // you backtrack an item off the list needs checking, since we'll never have matched
+    // the one less case.  Tracking forwards, still add as much as possible.
+    //
+    // Non-greedy, we've already done the one less case, so don't match on popping.
+    // We haven't done the one more case, so always try to add that.
+    //
+    bool backtrackParentheses(ByteTerm& term, DisjunctionContext* context)
+    {
+        ASSERT(term.type == ByteTerm::TypeParenthesesSubpattern);
+
+        BackTrackInfoParentheses* backTrack = reinterpret_cast<BackTrackInfoParentheses*>(context->frame + term.frameLocation);
+
+        if (term.capture()) {
+            unsigned subpatternId = term.atom.subpatternId;
+            output[(subpatternId << 1)] = backTrack->prevBegin;
+            output[(subpatternId << 1) + 1] = backTrack->prevEnd;
+        }
+
+        ByteDisjunction* disjunctionBody = term.atom.parenthesesDisjunction;
+
+        switch (term.atom.quantityType) {
+        case QuantifierFixedCount: {
+            ASSERT(backTrack->matchAmount == term.atom.quantityCount);
+
+            ParenthesesDisjunctionContext* context = 0;
+
+            if (!parenthesesDoBacktrack(term, backTrack))
+                return false;
+
+            // While we haven't yet reached our fixed limit,
+            while (backTrack->matchAmount < term.atom.quantityCount) {
+                // Try to do a match, and it it succeeds, add it to the list.
+                context = allocParenthesesDisjunctionContext(disjunctionBody, output, term);
+                if (matchDisjunction(disjunctionBody, context->getDisjunctionContext(term)))
+                    appendParenthesesDisjunctionContext(backTrack, context);
+                else {
+                    // The match failed; try to find an alternate point to carry on from.
+                    resetMatches(term, context);
+                    freeParenthesesDisjunctionContext(context);
+                    if (!parenthesesDoBacktrack(term, backTrack))
+                        return false;
+                }
+            }
+
+            ASSERT(backTrack->matchAmount == term.atom.quantityCount);
+            context = backTrack->lastContext;
+            recordParenthesesMatch(term, context);
+            return true;
+        }
+
+        case QuantifierGreedy: {
+            if (!backTrack->matchAmount)
+                return false;
+
+            ParenthesesDisjunctionContext* context = backTrack->lastContext;
+            if (matchNonZeroDisjunction(disjunctionBody, context->getDisjunctionContext(term), true)) {
+                while (backTrack->matchAmount < term.atom.quantityCount) {
+                    ParenthesesDisjunctionContext* context = allocParenthesesDisjunctionContext(disjunctionBody, output, term);
+                    if (matchNonZeroDisjunction(disjunctionBody, context->getDisjunctionContext(term)))
+                        appendParenthesesDisjunctionContext(backTrack, context);
+                    else {
+                        resetMatches(term, context);
+                        freeParenthesesDisjunctionContext(context);
+                        break;
+                    }
+                }
+            } else {
+                resetMatches(term, context);
+                freeParenthesesDisjunctionContext(context);
+                popParenthesesDisjunctionContext(backTrack);
+            }
+
+            if (backTrack->matchAmount) {
+                ParenthesesDisjunctionContext* context = backTrack->lastContext;
+                recordParenthesesMatch(term, context);
+            }
+            return true;
+        }
+
+        case QuantifierNonGreedy: {
+            // If we've not reached the limit, try to add one more match.
+            if (backTrack->matchAmount < term.atom.quantityCount) {
+                ParenthesesDisjunctionContext* context = allocParenthesesDisjunctionContext(disjunctionBody, output, term);
+                if (matchNonZeroDisjunction(disjunctionBody, context->getDisjunctionContext(term))) {
+                    appendParenthesesDisjunctionContext(backTrack, context);
+                    recordParenthesesMatch(term, context);
+                    return true;
+                } else {
+                    resetMatches(term, context);
+                    freeParenthesesDisjunctionContext(context);
+                }
+            }
+
+            // Nope - okay backtrack looking for an alternative.
+            while (backTrack->matchAmount) {
+                ParenthesesDisjunctionContext* context = backTrack->lastContext;
+                if (matchNonZeroDisjunction(disjunctionBody, context->getDisjunctionContext(term), true)) {
+                    // successful backtrack! we're back in the game!
+                    if (backTrack->matchAmount) {
+                        context = backTrack->lastContext;
+                        recordParenthesesMatch(term, context);
+                    }
+                    return true;
+                }
+                
+                // pop a match off the stack
+                resetMatches(term, context);
+                freeParenthesesDisjunctionContext(context);
+                popParenthesesDisjunctionContext(backTrack);
+            }
+
+            return false;
+        }
+        }
+
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+#define MATCH_NEXT() { ++context->term; goto matchAgain; }
+#define BACKTRACK() { --context->term; goto backtrack; }
+#define currentTerm() (disjunction->terms[context->term])
+    bool matchDisjunction(ByteDisjunction* disjunction, DisjunctionContext* context, bool btrack = false)
+    {
+        if (btrack)
+            BACKTRACK();
+
+        context->matchBegin = input.getPos();
+        context->term = 0;
+
+    matchAgain:
+        ASSERT(context->term < static_cast<int>(disjunction->terms.size()));
+
+        switch (currentTerm().type) {
+        case ByteTerm::TypeSubpatternBegin:
+            MATCH_NEXT();
+        case ByteTerm::TypeSubpatternEnd:
+            context->matchEnd = input.getPos();
+            return true;
+
+        case ByteTerm::TypeBodyAlternativeBegin:
+            MATCH_NEXT();
+        case ByteTerm::TypeBodyAlternativeDisjunction:
+        case ByteTerm::TypeBodyAlternativeEnd:
+            context->matchEnd = input.getPos();
+            return true;
+
+        case ByteTerm::TypeAlternativeBegin:
+            MATCH_NEXT();
+        case ByteTerm::TypeAlternativeDisjunction:
+        case ByteTerm::TypeAlternativeEnd: {
+            int offset = currentTerm().alternative.end;
+            BackTrackInfoAlternative* backTrack = reinterpret_cast<BackTrackInfoAlternative*>(context->frame + currentTerm().frameLocation);
+            backTrack->offset = offset;
+            context->term += offset;
+            MATCH_NEXT();
+        }
+
+        case ByteTerm::TypeAssertionBOL:
+            if (matchAssertionBOL(currentTerm()))
+                MATCH_NEXT();
+            BACKTRACK();
+        case ByteTerm::TypeAssertionEOL:
+            if (matchAssertionEOL(currentTerm()))
+                MATCH_NEXT();
+            BACKTRACK();
+        case ByteTerm::TypeAssertionWordBoundary:
+            if (matchAssertionWordBoundary(currentTerm()))
+                MATCH_NEXT();
+            BACKTRACK();
+
+        case ByteTerm::TypePatternCharacterOnce:
+        case ByteTerm::TypePatternCharacterFixed: {
+            for (unsigned matchAmount = 0; matchAmount < currentTerm().atom.quantityCount; ++matchAmount) {
+                if (!checkCharacter(currentTerm().atom.patternCharacter, currentTerm().inputPosition + matchAmount))
+                    BACKTRACK();
+            }
+            MATCH_NEXT();
+        }
+        case ByteTerm::TypePatternCharacterGreedy: {
+            BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + currentTerm().frameLocation);
+            unsigned matchAmount = 0;
+            while ((matchAmount < currentTerm().atom.quantityCount) && input.checkInput(1)) {
+                if (!checkCharacter(currentTerm().atom.patternCharacter, currentTerm().inputPosition - 1)) {
+                    input.uncheckInput(1);
+                    break;
+                }
+                ++matchAmount;
+            }
+            backTrack->matchAmount = matchAmount;
+
+            MATCH_NEXT();
+        }
+        case ByteTerm::TypePatternCharacterNonGreedy: {
+            BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + currentTerm().frameLocation);
+            backTrack->matchAmount = 0;
+            MATCH_NEXT();
+        }
+
+        case ByteTerm::TypePatternCasedCharacterOnce:
+        case ByteTerm::TypePatternCasedCharacterFixed: {
+            for (unsigned matchAmount = 0; matchAmount < currentTerm().atom.quantityCount; ++matchAmount) {
+                if (!checkCasedCharacter(currentTerm().atom.casedCharacter.lo, currentTerm().atom.casedCharacter.hi, currentTerm().inputPosition + matchAmount))
+                    BACKTRACK();
+            }
+            MATCH_NEXT();
+        }
+        case ByteTerm::TypePatternCasedCharacterGreedy: {
+            BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + currentTerm().frameLocation);
+            unsigned matchAmount = 0;
+            while ((matchAmount < currentTerm().atom.quantityCount) && input.checkInput(1)) {
+                if (!checkCasedCharacter(currentTerm().atom.casedCharacter.lo, currentTerm().atom.casedCharacter.hi, currentTerm().inputPosition - 1)) {
+                    input.uncheckInput(1);
+                    break;
+                }
+                ++matchAmount;
+            }
+            backTrack->matchAmount = matchAmount;
+
+            MATCH_NEXT();
+        }
+        case ByteTerm::TypePatternCasedCharacterNonGreedy: {
+            BackTrackInfoPatternCharacter* backTrack = reinterpret_cast<BackTrackInfoPatternCharacter*>(context->frame + currentTerm().frameLocation);
+            backTrack->matchAmount = 0;
+            MATCH_NEXT();
+        }
+
+        case ByteTerm::TypeCharacterClass:
+            if (matchCharacterClass(currentTerm(), context))
+                MATCH_NEXT();
+            BACKTRACK();
+        case ByteTerm::TypeBackReference:
+            if (matchBackReference(currentTerm(), context))
+                MATCH_NEXT();
+            BACKTRACK();
+        case ByteTerm::TypeParenthesesSubpattern:
+            if (matchParentheses(currentTerm(), context))
+                MATCH_NEXT();
+            BACKTRACK();
+        case ByteTerm::TypeParenthesesSubpatternOnceBegin:
+            if (matchParenthesesOnceBegin(currentTerm(), context))
+                MATCH_NEXT();
+            BACKTRACK();
+        case ByteTerm::TypeParenthesesSubpatternOnceEnd:
+            if (matchParenthesesOnceEnd(currentTerm(), context))
+                MATCH_NEXT();
+            BACKTRACK();
+        case ByteTerm::TypeParentheticalAssertionBegin:
+            if (matchParentheticalAssertionBegin(currentTerm(), context))
+                MATCH_NEXT();
+            BACKTRACK();
+        case ByteTerm::TypeParentheticalAssertionEnd:
+            if (matchParentheticalAssertionEnd(currentTerm(), context))
+                MATCH_NEXT();
+            BACKTRACK();
+
+        case ByteTerm::TypeCheckInput:
+            if (input.checkInput(currentTerm().checkInputCount))
+                MATCH_NEXT();
+            BACKTRACK();
+        }
+
+        // We should never fall-through to here.
+        ASSERT_NOT_REACHED();
+
+    backtrack:
+        ASSERT(context->term < static_cast<int>(disjunction->terms.size()));
+
+        switch (currentTerm().type) {
+        case ByteTerm::TypeSubpatternBegin:
+            return false;
+        case ByteTerm::TypeSubpatternEnd:
+            ASSERT_NOT_REACHED();
+
+        case ByteTerm::TypeBodyAlternativeBegin:
+        case ByteTerm::TypeBodyAlternativeDisjunction: {
+            int offset = currentTerm().alternative.next;
+            context->term += offset;
+            if (offset > 0)
+                MATCH_NEXT();
+
+            if (input.atEnd())
+                return false;
+
+            input.next();
+            context->matchBegin = input.getPos();
+            MATCH_NEXT();
+        }
+        case ByteTerm::TypeBodyAlternativeEnd:
+            ASSERT_NOT_REACHED();
+
+            case ByteTerm::TypeAlternativeBegin:
+            case ByteTerm::TypeAlternativeDisjunction: {
+                int offset = currentTerm().alternative.next;
+                context->term += offset;
+                if (offset > 0)
+                    MATCH_NEXT();
+                BACKTRACK();
+            }
+            case ByteTerm::TypeAlternativeEnd: {
+                // We should never backtrack back into an alternative of the main body of the regex.
+                BackTrackInfoAlternative* backTrack = reinterpret_cast<BackTrackInfoAlternative*>(context->frame + currentTerm().frameLocation);
+                unsigned offset = backTrack->offset;
+                context->term -= offset;
+                BACKTRACK();
+            }
+
+            case ByteTerm::TypeAssertionBOL:
+            case ByteTerm::TypeAssertionEOL:
+            case ByteTerm::TypeAssertionWordBoundary:
+                BACKTRACK();
+
+            case ByteTerm::TypePatternCharacterOnce:
+            case ByteTerm::TypePatternCharacterFixed:
+            case ByteTerm::TypePatternCharacterGreedy:
+            case ByteTerm::TypePatternCharacterNonGreedy:
+                if (backtrackPatternCharacter(currentTerm(), context))
+                    MATCH_NEXT();
+                BACKTRACK();
+            case ByteTerm::TypePatternCasedCharacterOnce:
+            case ByteTerm::TypePatternCasedCharacterFixed:
+            case ByteTerm::TypePatternCasedCharacterGreedy:
+            case ByteTerm::TypePatternCasedCharacterNonGreedy:
+                if (backtrackPatternCasedCharacter(currentTerm(), context))
+                    MATCH_NEXT();
+                BACKTRACK();
+            case ByteTerm::TypeCharacterClass:
+                if (backtrackCharacterClass(currentTerm(), context))
+                    MATCH_NEXT();
+                BACKTRACK();
+            case ByteTerm::TypeBackReference:
+                if (backtrackBackReference(currentTerm(), context))
+                    MATCH_NEXT();
+                BACKTRACK();
+            case ByteTerm::TypeParenthesesSubpattern:
+                if (backtrackParentheses(currentTerm(), context))
+                    MATCH_NEXT();
+                BACKTRACK();
+            case ByteTerm::TypeParenthesesSubpatternOnceBegin:
+                if (backtrackParenthesesOnceBegin(currentTerm(), context))
+                    MATCH_NEXT();
+                BACKTRACK();
+            case ByteTerm::TypeParenthesesSubpatternOnceEnd:
+                if (backtrackParenthesesOnceEnd(currentTerm(), context))
+                    MATCH_NEXT();
+                BACKTRACK();
+            case ByteTerm::TypeParentheticalAssertionBegin:
+                if (backtrackParentheticalAssertionBegin(currentTerm(), context))
+                    MATCH_NEXT();
+                BACKTRACK();
+            case ByteTerm::TypeParentheticalAssertionEnd:
+                if (backtrackParentheticalAssertionEnd(currentTerm(), context))
+                    MATCH_NEXT();
+                BACKTRACK();
+
+            case ByteTerm::TypeCheckInput:
+                input.uncheckInput(currentTerm().checkInputCount);
+                BACKTRACK();
+        }
+
+        ASSERT_NOT_REACHED();
+        return false;
+    }
+
+    bool matchNonZeroDisjunction(ByteDisjunction* disjunction, DisjunctionContext* context, bool btrack = false)
+    {
+        if (matchDisjunction(disjunction, context, btrack)) {
+            while (context->matchBegin == context->matchEnd) {
+                if (!matchDisjunction(disjunction, context, true))
+                    return false;
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    int interpret()
+    {
+        for (unsigned i = 0; i < ((pattern->m_body->m_numSubpatterns + 1) << 1); ++i)
+            output[i] = -1;
+
+        DisjunctionContext* context = allocDisjunctionContext(pattern->m_body.get());
+
+        if (matchDisjunction(pattern->m_body.get(), context)) {
+            output[0] = context->matchBegin;
+            output[1] = context->matchEnd;
+        }
+
+        freeDisjunctionContext(context);
+
+        return output[0];
+    }
+
+    Interpreter(BytecodePattern* pattern, int* output, const UChar* inputChar, unsigned start, unsigned length)
+        : pattern(pattern)
+        , output(output)
+        , input(inputChar, start, length)
+    {
+    }
+
+private:
+    BytecodePattern *pattern;
+    int* output;
+    InputStream input;
+};
+
+
+
+class ByteCompiler {
+    struct ParenthesesStackEntry {
+        unsigned beginTerm;
+        unsigned savedAlternativeIndex;
+        ParenthesesStackEntry(unsigned beginTerm, unsigned savedAlternativeIndex/*, unsigned subpatternId, bool capture = false*/)
+            : beginTerm(beginTerm)
+            , savedAlternativeIndex(savedAlternativeIndex)
+        {
+        }
+    };
+
+public:
+    ByteCompiler(RegexPattern& pattern)
+        : m_pattern(pattern)
+    {
+        bodyDisjunction = 0;
+        currentAlternativeIndex = 0;
+    }
+    
+    BytecodePattern* compile()
+    {
+        regexBegin(m_pattern.m_numSubpatterns, m_pattern.m_body->m_callFrameSize);
+        emitDisjunction(m_pattern.m_body);
+        regexEnd();
+
+        return new BytecodePattern(bodyDisjunction, m_allParenthesesInfo, m_pattern);
+    }
+    
+    void checkInput(unsigned count)
+    {
+        bodyDisjunction->terms.append(ByteTerm::CheckInput(count));
+    }
+
+    void assertionBOL(int inputPosition)
+    {
+        bodyDisjunction->terms.append(ByteTerm::BOL(inputPosition));
+    }
+
+    void assertionEOL(int inputPosition)
+    {
+        bodyDisjunction->terms.append(ByteTerm::EOL(inputPosition));
+    }
+
+    void assertionWordBoundary(bool invert, int inputPosition)
+    {
+        bodyDisjunction->terms.append(ByteTerm::WordBoundary(invert, inputPosition));
+    }
+
+    void atomPatternCharacter(UChar ch, int inputPosition, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType)
+    {
+        if (m_pattern.m_ignoreCase) {
+            UChar lo = Unicode::toLower(ch);
+            UChar hi = Unicode::toUpper(ch);
+            
+            if (lo != hi) {
+                bodyDisjunction->terms.append(ByteTerm(lo, hi, inputPosition, frameLocation, quantityCount, quantityType));
+                return;
+            }
+        }
+
+        bodyDisjunction->terms.append(ByteTerm(ch, inputPosition, frameLocation, quantityCount, quantityType));
+    }
+    
+    void atomCharacterClass(CharacterClass* characterClass, bool invert, int inputPosition, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType)
+    {
+        bodyDisjunction->terms.append(ByteTerm(characterClass, invert, inputPosition));
+
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].atom.quantityCount = quantityCount;
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].atom.quantityType = quantityType;
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = frameLocation;
+    }
+
+    void atomBackReference(unsigned subpatternId, int inputPosition, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType)
+    {
+        ASSERT(subpatternId);
+
+        bodyDisjunction->terms.append(ByteTerm::BackReference(subpatternId, inputPosition));
+
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].atom.quantityCount = quantityCount;
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].atom.quantityType = quantityType;
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = frameLocation;
+    }
+
+    void atomParenthesesSubpatternBegin(unsigned subpatternId, bool capture, int inputPosition, unsigned frameLocation, unsigned alternativeFrameLocation)
+    {
+        int beginTerm = bodyDisjunction->terms.size();
+
+        bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpatternOnceBegin, subpatternId, capture, inputPosition));
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = frameLocation;
+        bodyDisjunction->terms.append(ByteTerm::AlternativeBegin());
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = alternativeFrameLocation;
+
+        m_parenthesesStack.append(ParenthesesStackEntry(beginTerm, currentAlternativeIndex));
+        currentAlternativeIndex = beginTerm + 1;
+    }
+
+    void atomParentheticalAssertionBegin(unsigned subpatternId, bool invert, unsigned frameLocation, unsigned alternativeFrameLocation)
+    {
+        int beginTerm = bodyDisjunction->terms.size();
+
+        bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParentheticalAssertionBegin, subpatternId, invert, 0));
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = frameLocation;
+        bodyDisjunction->terms.append(ByteTerm::AlternativeBegin());
+        bodyDisjunction->terms[bodyDisjunction->terms.size() - 1].frameLocation = alternativeFrameLocation;
+
+        m_parenthesesStack.append(ParenthesesStackEntry(beginTerm, currentAlternativeIndex));
+        currentAlternativeIndex = beginTerm + 1;
+    }
+
+    unsigned popParenthesesStack()
+    {
+        ASSERT(m_parenthesesStack.size());
+        int stackEnd = m_parenthesesStack.size() - 1;
+        unsigned beginTerm = m_parenthesesStack[stackEnd].beginTerm;
+        currentAlternativeIndex = m_parenthesesStack[stackEnd].savedAlternativeIndex;
+        m_parenthesesStack.shrink(stackEnd);
+
+        ASSERT(beginTerm < bodyDisjunction->terms.size());
+        ASSERT(currentAlternativeIndex < bodyDisjunction->terms.size());
+        
+        return beginTerm;
+    }
+
+#ifndef NDEBUG
+    void dumpDisjunction(ByteDisjunction* disjunction)
+    {
+        printf("ByteDisjunction(%p):\n\t", disjunction);
+        for (unsigned i = 0; i < disjunction->terms.size(); ++i)
+            printf("{ %d } ", disjunction->terms[i].type);
+        printf("\n");
+    }
+#endif
+
+    void closeAlternative(int beginTerm)
+    {
+        int origBeginTerm = beginTerm;
+        ASSERT(bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeAlternativeBegin);
+        int endIndex = bodyDisjunction->terms.size();
+
+        unsigned frameLocation = bodyDisjunction->terms[beginTerm].frameLocation;
+
+        if (!bodyDisjunction->terms[beginTerm].alternative.next)
+            bodyDisjunction->terms.remove(beginTerm);
+        else {
+            while (bodyDisjunction->terms[beginTerm].alternative.next) {
+                beginTerm += bodyDisjunction->terms[beginTerm].alternative.next;
+                ASSERT(bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeAlternativeDisjunction);
+                bodyDisjunction->terms[beginTerm].alternative.end = endIndex - beginTerm;
+                bodyDisjunction->terms[beginTerm].frameLocation = frameLocation;
+            }
+            
+            bodyDisjunction->terms[beginTerm].alternative.next = origBeginTerm - beginTerm;
+
+            bodyDisjunction->terms.append(ByteTerm::AlternativeEnd());
+            bodyDisjunction->terms[endIndex].frameLocation = frameLocation;
+        }
+    }
+
+    void closeBodyAlternative()
+    {
+        int beginTerm = 0;
+        int origBeginTerm = 0;
+        ASSERT(bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeBodyAlternativeBegin);
+        int endIndex = bodyDisjunction->terms.size();
+
+        unsigned frameLocation = bodyDisjunction->terms[beginTerm].frameLocation;
+
+        while (bodyDisjunction->terms[beginTerm].alternative.next) {
+            beginTerm += bodyDisjunction->terms[beginTerm].alternative.next;
+            ASSERT(bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeBodyAlternativeDisjunction);
+            bodyDisjunction->terms[beginTerm].alternative.end = endIndex - beginTerm;
+            bodyDisjunction->terms[beginTerm].frameLocation = frameLocation;
+        }
+        
+        bodyDisjunction->terms[beginTerm].alternative.next = origBeginTerm - beginTerm;
+
+        bodyDisjunction->terms.append(ByteTerm::BodyAlternativeEnd());
+        bodyDisjunction->terms[endIndex].frameLocation = frameLocation;
+    }
+
+    void atomParenthesesEnd(bool doInline, unsigned lastSubpatternId, int inputPosition, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType, unsigned callFrameSize = 0)
+    {
+        unsigned beginTerm = popParenthesesStack();
+        closeAlternative(beginTerm + 1);
+        unsigned endTerm = bodyDisjunction->terms.size();
+
+        bool isAssertion = bodyDisjunction->terms[beginTerm].type == ByteTerm::TypeParentheticalAssertionBegin;
+        bool invertOrCapture = bodyDisjunction->terms[beginTerm].invertOrCapture;
+        unsigned subpatternId = bodyDisjunction->terms[beginTerm].atom.subpatternId;
+
+        bodyDisjunction->terms.append(ByteTerm(isAssertion ? ByteTerm::TypeParentheticalAssertionEnd : ByteTerm::TypeParenthesesSubpatternOnceEnd, subpatternId, invertOrCapture, inputPosition));
+        bodyDisjunction->terms[beginTerm].atom.parenthesesWidth = endTerm - beginTerm;
+        bodyDisjunction->terms[endTerm].atom.parenthesesWidth = endTerm - beginTerm;
+        bodyDisjunction->terms[endTerm].frameLocation = frameLocation;
+
+        if (doInline) {
+            bodyDisjunction->terms[beginTerm].atom.quantityCount = quantityCount;
+            bodyDisjunction->terms[beginTerm].atom.quantityType = quantityType;
+            bodyDisjunction->terms[endTerm].atom.quantityCount = quantityCount;
+            bodyDisjunction->terms[endTerm].atom.quantityType = quantityType;
+        } else {
+            ByteTerm& parenthesesBegin = bodyDisjunction->terms[beginTerm];
+            ASSERT(parenthesesBegin.type == ByteTerm::TypeParenthesesSubpatternOnceBegin);
+
+            bool invertOrCapture = parenthesesBegin.invertOrCapture;
+            unsigned subpatternId = parenthesesBegin.atom.subpatternId;
+
+            unsigned numSubpatterns = lastSubpatternId - subpatternId + 1;
+            ByteDisjunction* parenthesesDisjunction = new ByteDisjunction(numSubpatterns, callFrameSize);
+
+            parenthesesDisjunction->terms.append(ByteTerm::SubpatternBegin());
+            for (unsigned termInParentheses = beginTerm + 1; termInParentheses < endTerm; ++termInParentheses)
+                parenthesesDisjunction->terms.append(bodyDisjunction->terms[termInParentheses]);
+            parenthesesDisjunction->terms.append(ByteTerm::SubpatternEnd());
+
+            bodyDisjunction->terms.shrink(beginTerm);
+
+            m_allParenthesesInfo.append(parenthesesDisjunction);
+            bodyDisjunction->terms.append(ByteTerm(ByteTerm::TypeParenthesesSubpattern, subpatternId, parenthesesDisjunction, invertOrCapture, inputPosition));
+
+            bodyDisjunction->terms[beginTerm].atom.quantityCount = quantityCount;
+            bodyDisjunction->terms[beginTerm].atom.quantityType = quantityType;
+            bodyDisjunction->terms[beginTerm].frameLocation = frameLocation;
+        }
+    }
+
+    void regexBegin(unsigned numSubpatterns, unsigned callFrameSize)
+    {
+        bodyDisjunction = new ByteDisjunction(numSubpatterns, callFrameSize);
+        bodyDisjunction->terms.append(ByteTerm::BodyAlternativeBegin());
+        bodyDisjunction->terms[0].frameLocation = 0;
+        currentAlternativeIndex = 0;
+    }
+
+    void regexEnd()
+    {
+        closeBodyAlternative();
+    }
+
+    void alterantiveBodyDisjunction()
+    {
+        int newAlternativeIndex = bodyDisjunction->terms.size();
+        bodyDisjunction->terms[currentAlternativeIndex].alternative.next = newAlternativeIndex - currentAlternativeIndex;
+        bodyDisjunction->terms.append(ByteTerm::BodyAlternativeDisjunction());
+
+        currentAlternativeIndex = newAlternativeIndex;
+    }
+
+    void alterantiveDisjunction()
+    {
+        int newAlternativeIndex = bodyDisjunction->terms.size();
+        bodyDisjunction->terms[currentAlternativeIndex].alternative.next = newAlternativeIndex - currentAlternativeIndex;
+        bodyDisjunction->terms.append(ByteTerm::AlternativeDisjunction());
+
+        currentAlternativeIndex = newAlternativeIndex;
+    }
+
+    void emitDisjunction(PatternDisjunction* disjunction, unsigned inputCountAlreadyChecked = 0, unsigned parenthesesInputCountAlreadyChecked = 0)
+    {
+        for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
+            unsigned currentCountAlreadyChecked = inputCountAlreadyChecked;
+        
+            if (alt) {
+                if (disjunction == m_pattern.m_body)
+                    alterantiveBodyDisjunction();
+                else
+                    alterantiveDisjunction();
+            }
+
+            PatternAlternative* alternative = disjunction->m_alternatives[alt];
+            unsigned minimumSize = alternative->m_minimumSize;
+
+            ASSERT(minimumSize >= parenthesesInputCountAlreadyChecked);
+            unsigned countToCheck = minimumSize - parenthesesInputCountAlreadyChecked;
+            if (countToCheck)
+                checkInput(countToCheck);
+            currentCountAlreadyChecked += countToCheck;
+
+            for (unsigned i = 0; i < alternative->m_terms.size(); ++i) {
+                PatternTerm& term = alternative->m_terms[i];
+
+                switch (term.type) {
+                case PatternTerm::TypeAssertionBOL:
+                    assertionBOL(term.inputPosition - currentCountAlreadyChecked);
+                    break;
+
+                case PatternTerm::TypeAssertionEOL:
+                    assertionEOL(term.inputPosition - currentCountAlreadyChecked);
+                    break;
+
+                case PatternTerm::TypeAssertionWordBoundary:
+                    assertionWordBoundary(term.invertOrCapture, term.inputPosition - currentCountAlreadyChecked);
+                    break;
+
+                case PatternTerm::TypePatternCharacter:
+                    atomPatternCharacter(term.patternCharacter, term.inputPosition - currentCountAlreadyChecked, term.frameLocation, term.quantityCount, term.quantityType);
+                    break;
+
+                case PatternTerm::TypeCharacterClass:
+                    atomCharacterClass(term.characterClass, term.invertOrCapture, term.inputPosition - currentCountAlreadyChecked, term.frameLocation, term.quantityCount, term.quantityType);
+                    break;
+
+                case PatternTerm::TypeBackReference:
+                    atomBackReference(term.subpatternId, term.inputPosition - currentCountAlreadyChecked, term.frameLocation, term.quantityCount, term.quantityType);
+                        break;
+
+                case PatternTerm::TypeForwardReference:
+                    break;
+
+                case PatternTerm::TypeParenthesesSubpattern: {
+                    unsigned disjunctionAlreadyCheckedCount = 0;
+                    if ((term.quantityCount == 1) && !term.parentheses.isCopy) {
+                        if (term.quantityType == QuantifierFixedCount) {
+                            disjunctionAlreadyCheckedCount = term.parentheses.disjunction->m_minimumSize;
+                            unsigned delegateEndInputOffset = term.inputPosition - currentCountAlreadyChecked;
+                            atomParenthesesSubpatternBegin(term.parentheses.subpatternId, term.invertOrCapture, delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, term.frameLocation);
+                            emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, term.parentheses.disjunction->m_minimumSize);
+                            atomParenthesesEnd(true, term.parentheses.lastSubpatternId, delegateEndInputOffset, term.frameLocation, term.quantityCount, term.quantityType, term.parentheses.disjunction->m_callFrameSize);
+                        } else {
+                            unsigned delegateEndInputOffset = term.inputPosition - currentCountAlreadyChecked;
+                            atomParenthesesSubpatternBegin(term.parentheses.subpatternId, term.invertOrCapture, delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, term.frameLocation + RegexStackSpaceForBackTrackInfoParenthesesOnce);
+                            emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0);
+                            atomParenthesesEnd(true, term.parentheses.lastSubpatternId, delegateEndInputOffset, term.frameLocation, term.quantityCount, term.quantityType, term.parentheses.disjunction->m_callFrameSize);
+                        }
+                    } else {
+                        unsigned delegateEndInputOffset = term.inputPosition - currentCountAlreadyChecked;
+                        atomParenthesesSubpatternBegin(term.parentheses.subpatternId, term.invertOrCapture, delegateEndInputOffset - disjunctionAlreadyCheckedCount, term.frameLocation, 0);
+                        emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0);
+                        atomParenthesesEnd(false, term.parentheses.lastSubpatternId, delegateEndInputOffset, term.frameLocation, term.quantityCount, term.quantityType, term.parentheses.disjunction->m_callFrameSize);
+                    }
+                    break;
+                }
+
+                case PatternTerm::TypeParentheticalAssertion: {
+                    unsigned alternativeFrameLocation = term.inputPosition + RegexStackSpaceForBackTrackInfoParentheticalAssertion;
+                    
+                    atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invertOrCapture, term.frameLocation, alternativeFrameLocation);
+                    emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0);
+                    atomParenthesesEnd(true, term.parentheses.lastSubpatternId, 0, term.frameLocation, term.quantityCount, term.quantityType);
+                    break;
+                }
+                }
+            }
+        }
+    }
+
+private:
+    RegexPattern& m_pattern;
+    ByteDisjunction* bodyDisjunction;
+    unsigned currentAlternativeIndex;
+    Vector<ParenthesesStackEntry> m_parenthesesStack;
+    Vector<ByteDisjunction*> m_allParenthesesInfo;
+};
+
+
+BytecodePattern* byteCompileRegex(const UString& patternString, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline)
+{
+    RegexPattern pattern(ignoreCase, multiline);
+
+    if ((error = compileRegex(patternString, pattern)))
+        return 0;
+
+    numSubpatterns = pattern.m_numSubpatterns;
+
+    return ByteCompiler(pattern).compile();
+}
+
+int interpretRegex(BytecodePattern* regex, const UChar* input, unsigned start, unsigned length, int* output)
+{
+    return Interpreter(regex, output, input, start, length).interpret();
+}
+
+
+COMPILE_ASSERT(sizeof(Interpreter::BackTrackInfoPatternCharacter) == (RegexStackSpaceForBackTrackInfoPatternCharacter * sizeof(uintptr_t)), CheckRegexStackSpaceForBackTrackInfoPatternCharacter);
+COMPILE_ASSERT(sizeof(Interpreter::BackTrackInfoCharacterClass) == (RegexStackSpaceForBackTrackInfoCharacterClass * sizeof(uintptr_t)), CheckRegexStackSpaceForBackTrackInfoCharacterClass);
+COMPILE_ASSERT(sizeof(Interpreter::BackTrackInfoBackReference) == (RegexStackSpaceForBackTrackInfoBackReference * sizeof(uintptr_t)), CheckRegexStackSpaceForBackTrackInfoBackReference);
+COMPILE_ASSERT(sizeof(Interpreter::BackTrackInfoAlternative) == (RegexStackSpaceForBackTrackInfoAlternative * sizeof(uintptr_t)), CheckRegexStackSpaceForBackTrackInfoAlternative);
+COMPILE_ASSERT(sizeof(Interpreter::BackTrackInfoParentheticalAssertion) == (RegexStackSpaceForBackTrackInfoParentheticalAssertion * sizeof(uintptr_t)), CheckRegexStackSpaceForBackTrackInfoParentheticalAssertion);
+COMPILE_ASSERT(sizeof(Interpreter::BackTrackInfoParenthesesOnce) == (RegexStackSpaceForBackTrackInfoParenthesesOnce * sizeof(uintptr_t)), CheckRegexStackSpaceForBackTrackInfoParenthesesOnce);
+COMPILE_ASSERT(sizeof(Interpreter::BackTrackInfoParentheses) == (RegexStackSpaceForBackTrackInfoParentheses * sizeof(uintptr_t)), CheckRegexStackSpaceForBackTrackInfoParentheses);
+
+
+} }
+
+#endif
diff --git a/yarr/RegexInterpreter.h b/yarr/RegexInterpreter.h
new file mode 100644 (file)
index 0000000..a8c122a
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RegexInterpreter_h
+#define RegexInterpreter_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(YARR)
+
+#include <wtf/unicode/Unicode.h>
+#include "RegexParser.h"
+#include "RegexPattern.h"
+
+namespace JSC { namespace Yarr {
+
+class ByteDisjunction;
+
+struct ByteTerm {
+    enum Type {
+        TypeBodyAlternativeBegin,
+        TypeBodyAlternativeDisjunction,
+        TypeBodyAlternativeEnd,
+        TypeAlternativeBegin,
+        TypeAlternativeDisjunction,
+        TypeAlternativeEnd,
+        TypeSubpatternBegin,
+        TypeSubpatternEnd,
+        TypeAssertionBOL,
+        TypeAssertionEOL,
+        TypeAssertionWordBoundary,
+        TypePatternCharacterOnce,
+        TypePatternCharacterFixed,
+        TypePatternCharacterGreedy,
+        TypePatternCharacterNonGreedy,
+        TypePatternCasedCharacterOnce,
+        TypePatternCasedCharacterFixed,
+        TypePatternCasedCharacterGreedy,
+        TypePatternCasedCharacterNonGreedy,
+        TypeCharacterClass,
+        TypeBackReference,
+        TypeParenthesesSubpattern,
+        TypeParenthesesSubpatternOnceBegin,
+        TypeParenthesesSubpatternOnceEnd,
+        TypeParentheticalAssertionBegin,
+        TypeParentheticalAssertionEnd,
+        TypeCheckInput,
+    } type;
+    bool invertOrCapture;
+    union {
+        struct {
+            union {
+                UChar patternCharacter;
+                struct {
+                    UChar lo;
+                    UChar hi;
+                } casedCharacter;
+                CharacterClass* characterClass;
+                unsigned subpatternId;
+            };
+            union {
+                ByteDisjunction* parenthesesDisjunction;
+                unsigned parenthesesWidth;
+            };
+            QuantifierType quantityType;
+            unsigned quantityCount;
+        } atom;
+        struct {
+            int next;
+            int end;
+        } alternative;
+        unsigned checkInputCount;
+    };
+    unsigned frameLocation;
+    int inputPosition;
+
+    ByteTerm(UChar ch, int inputPos, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType)
+        : frameLocation(frameLocation)
+    {
+        switch (quantityType) {
+        case QuantifierFixedCount:
+            type = (quantityCount == 1) ? ByteTerm::TypePatternCharacterOnce : ByteTerm::TypePatternCharacterFixed;
+            break;
+        case QuantifierGreedy:
+            type = ByteTerm::TypePatternCharacterGreedy;
+            break;
+        case QuantifierNonGreedy:
+            type = ByteTerm::TypePatternCharacterNonGreedy;
+            break;
+        }
+
+        atom.patternCharacter = ch;
+        atom.quantityType = quantityType;
+        atom.quantityCount = quantityCount;
+        inputPosition = inputPos;
+    }
+
+    ByteTerm(UChar lo, UChar hi, int inputPos, unsigned frameLocation, unsigned quantityCount, QuantifierType quantityType)
+        : frameLocation(frameLocation)
+    {
+        switch (quantityType) {
+        case QuantifierFixedCount:
+            type = (quantityCount == 1) ? ByteTerm::TypePatternCasedCharacterOnce : ByteTerm::TypePatternCasedCharacterFixed;
+            break;
+        case QuantifierGreedy:
+            type = ByteTerm::TypePatternCasedCharacterGreedy;
+            break;
+        case QuantifierNonGreedy:
+            type = ByteTerm::TypePatternCasedCharacterNonGreedy;
+            break;
+        }
+
+        atom.casedCharacter.lo = lo;
+        atom.casedCharacter.hi = hi;
+        atom.quantityType = quantityType;
+        atom.quantityCount = quantityCount;
+        inputPosition = inputPos;
+    }
+
+    ByteTerm(CharacterClass* characterClass, bool invert, int inputPos)
+        : type(ByteTerm::TypeCharacterClass)
+        , invertOrCapture(invert)
+    {
+        atom.characterClass = characterClass;
+        atom.quantityType = QuantifierFixedCount;
+        atom.quantityCount = 1;
+        inputPosition = inputPos;
+    }
+
+    ByteTerm(Type type, unsigned subpatternId, ByteDisjunction* parenthesesInfo, bool invertOrCapture, int inputPos)
+        : type(type)
+        , invertOrCapture(invertOrCapture)
+    {
+        atom.subpatternId = subpatternId;
+        atom.parenthesesDisjunction = parenthesesInfo;
+        atom.quantityType = QuantifierFixedCount;
+        atom.quantityCount = 1;
+        inputPosition = inputPos;
+    }
+    
+    ByteTerm(Type type, bool invert = false)
+        : type(type)
+        , invertOrCapture(invert)
+    {
+        atom.quantityType = QuantifierFixedCount;
+        atom.quantityCount = 1;
+    }
+
+    ByteTerm(Type type, unsigned subpatternId, bool invertOrCapture, int inputPos)
+        : type(type)
+        , invertOrCapture(invertOrCapture)
+    {
+        atom.subpatternId = subpatternId;
+        atom.quantityType = QuantifierFixedCount;
+        atom.quantityCount = 1;
+        inputPosition = inputPos;
+    }
+
+    static ByteTerm BOL(int inputPos)
+    {
+        ByteTerm term(TypeAssertionBOL);
+        term.inputPosition = inputPos;
+        return term;
+    }
+
+    static ByteTerm CheckInput(unsigned count)
+    {
+        ByteTerm term(TypeCheckInput);
+        term.checkInputCount = count;
+        return term;
+    }
+
+    static ByteTerm EOL(int inputPos)
+    {
+        ByteTerm term(TypeAssertionEOL);
+        term.inputPosition = inputPos;
+        return term;
+    }
+
+    static ByteTerm WordBoundary(bool invert, int inputPos)
+    {
+        ByteTerm term(TypeAssertionWordBoundary, invert);
+        term.inputPosition = inputPos;
+        return term;
+    }
+    
+    static ByteTerm BackReference(unsigned subpatternId, int inputPos)
+    {
+        return ByteTerm(TypeBackReference, subpatternId, false, inputPos);
+    }
+
+    static ByteTerm BodyAlternativeBegin()
+    {
+        ByteTerm term(TypeBodyAlternativeBegin);
+        term.alternative.next = 0;
+        term.alternative.end = 0;
+        return term;
+    }
+
+    static ByteTerm BodyAlternativeDisjunction()
+    {
+        ByteTerm term(TypeBodyAlternativeDisjunction);
+        term.alternative.next = 0;
+        term.alternative.end = 0;
+        return term;
+    }
+
+    static ByteTerm BodyAlternativeEnd()
+    {
+        ByteTerm term(TypeBodyAlternativeEnd);
+        term.alternative.next = 0;
+        term.alternative.end = 0;
+        return term;
+    }
+
+    static ByteTerm AlternativeBegin()
+    {
+        ByteTerm term(TypeAlternativeBegin);
+        term.alternative.next = 0;
+        term.alternative.end = 0;
+        return term;
+    }
+
+    static ByteTerm AlternativeDisjunction()
+    {
+        ByteTerm term(TypeAlternativeDisjunction);
+        term.alternative.next = 0;
+        term.alternative.end = 0;
+        return term;
+    }
+
+    static ByteTerm AlternativeEnd()
+    {
+        ByteTerm term(TypeAlternativeEnd);
+        term.alternative.next = 0;
+        term.alternative.end = 0;
+        return term;
+    }
+
+    static ByteTerm SubpatternBegin()
+    {
+        return ByteTerm(TypeSubpatternBegin);
+    }
+
+    static ByteTerm SubpatternEnd()
+    {
+        return ByteTerm(TypeSubpatternEnd);
+    }
+
+    bool invert()
+    {
+        return invertOrCapture;
+    }
+
+    bool capture()
+    {
+        return invertOrCapture;
+    }
+};
+
+class ByteDisjunction {
+public:
+    ByteDisjunction(unsigned numSubpatterns, unsigned frameSize)
+        : m_numSubpatterns(numSubpatterns)
+        , m_frameSize(frameSize)
+    {
+    }
+
+    Vector<ByteTerm> terms;
+    unsigned m_numSubpatterns;
+    unsigned m_frameSize;
+};
+
+struct BytecodePattern {
+    BytecodePattern(ByteDisjunction* body, Vector<ByteDisjunction*> allParenthesesInfo, RegexPattern& pattern)
+        : m_body(body)
+        , m_ignoreCase(pattern.m_ignoreCase)
+        , m_multiline(pattern.m_multiline)
+    {
+        newlineCharacterClass = pattern.newlineCharacterClass();
+        wordcharCharacterClass = pattern.wordcharCharacterClass();
+
+        m_allParenthesesInfo.append(allParenthesesInfo);
+        m_userCharacterClasses.append(pattern.m_userCharacterClasses);
+        // 'Steal' the RegexPattern's CharacterClasses!  We clear its
+        // array, so that it won't delete them on destruction.  We'll
+        // take responsibility for that.
+        pattern.m_userCharacterClasses.clear();
+    }
+
+    ~BytecodePattern()
+    {
+        deleteAllValues(m_allParenthesesInfo);
+        deleteAllValues(m_userCharacterClasses);
+    }
+
+    OwnPtr<ByteDisjunction> m_body;
+    bool m_ignoreCase;
+    bool m_multiline;
+    
+    CharacterClass* newlineCharacterClass;
+    CharacterClass* wordcharCharacterClass;
+private:
+    Vector<ByteDisjunction*> m_allParenthesesInfo;
+    Vector<CharacterClass*> m_userCharacterClasses;
+};
+
+BytecodePattern* byteCompileRegex(const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase = false, bool multiline = false);
+int interpretRegex(BytecodePattern* v_regex, const UChar* input, unsigned start, unsigned length, int* output);
+
+} } // namespace JSC::Yarr
+
+#endif
+
+#endif // RegexInterpreter_h
diff --git a/yarr/RegexJIT.cpp b/yarr/RegexJIT.cpp
new file mode 100644 (file)
index 0000000..8e3640a
--- /dev/null
@@ -0,0 +1,1417 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "RegexJIT.h"
+
+#include "ASCIICType.h"
+#include "JSGlobalData.h"
+#include "LinkBuffer.h"
+#include "MacroAssembler.h"
+#include "RegexCompiler.h"
+
+#include "pcre.h" // temporary, remove when fallback is removed.
+
+#if ENABLE(YARR_JIT)
+
+using namespace WTF;
+
+namespace JSC { namespace Yarr {
+
+
+class RegexGenerator : private MacroAssembler {
+    friend void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline);
+
+#if PLATFORM_ARM_ARCH(7)
+    static const RegisterID input = ARM::r0;
+    static const RegisterID index = ARM::r1;
+    static const RegisterID length = ARM::r2;
+
+    static const RegisterID output = ARM::r4;
+    static const RegisterID regT0 = ARM::r5;
+    static const RegisterID regT1 = ARM::r6;
+
+    static const RegisterID returnRegister = ARM::r0;
+#endif
+#if PLATFORM(X86)
+    static const RegisterID input = X86::eax;
+    static const RegisterID index = X86::edx;
+    static const RegisterID length = X86::ecx;
+    static const RegisterID output = X86::edi;
+
+    static const RegisterID regT0 = X86::ebx;
+    static const RegisterID regT1 = X86::esi;
+
+    static const RegisterID returnRegister = X86::eax;
+#endif
+#if PLATFORM(X86_64)
+    static const RegisterID input = X86::edi;
+    static const RegisterID index = X86::esi;
+    static const RegisterID length = X86::edx;
+    static const RegisterID output = X86::ecx;
+
+    static const RegisterID regT0 = X86::eax;
+    static const RegisterID regT1 = X86::ebx;
+
+    static const RegisterID returnRegister = X86::eax;
+#endif
+
+    void optimizeAlternative(PatternAlternative* alternative)
+    {
+        if (!alternative->m_terms.size())
+            return;
+
+        for (unsigned i = 0; i < alternative->m_terms.size() - 1; ++i) {
+            PatternTerm& term = alternative->m_terms[i];
+            PatternTerm& nextTerm = alternative->m_terms[i + 1];
+
+            if ((term.type == PatternTerm::TypeCharacterClass)
+                && (term.quantityType == QuantifierFixedCount)
+                && (nextTerm.type == PatternTerm::TypePatternCharacter)
+                && (nextTerm.quantityType == QuantifierFixedCount)) {
+                PatternTerm termCopy = term;
+                alternative->m_terms[i] = nextTerm;
+                alternative->m_terms[i + 1] = termCopy;
+            }
+        }
+    }
+
+    void matchCharacterClassRange(RegisterID character, JumpList& failures, JumpList& matchDest, const CharacterRange* ranges, unsigned count, unsigned* matchIndex, const UChar* matches, unsigned matchCount)
+    {
+        do {
+            // pick which range we're going to generate
+            int which = count >> 1;
+            char lo = ranges[which].begin;
+            char hi = ranges[which].end;
+            
+            // check if there are any ranges or matches below lo.  If not, just jl to failure -
+            // if there is anything else to check, check that first, if it falls through jmp to failure.
+            if ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {
+                Jump loOrAbove = branch32(GreaterThanOrEqual, character, Imm32((unsigned short)lo));
+                
+                // generate code for all ranges before this one
+                if (which)
+                    matchCharacterClassRange(character, failures, matchDest, ranges, which, matchIndex, matches, matchCount);
+                
+                while ((*matchIndex < matchCount) && (matches[*matchIndex] < lo)) {
+                    matchDest.append(branch32(Equal, character, Imm32((unsigned short)matches[*matchIndex])));
+                    ++*matchIndex;
+                }
+                failures.append(jump());
+
+                loOrAbove.link(this);
+            } else if (which) {
+                Jump loOrAbove = branch32(GreaterThanOrEqual, character, Imm32((unsigned short)lo));
+
+                matchCharacterClassRange(character, failures, matchDest, ranges, which, matchIndex, matches, matchCount);
+                failures.append(jump());
+
+                loOrAbove.link(this);
+            } else
+                failures.append(branch32(LessThan, character, Imm32((unsigned short)lo)));
+
+            while ((*matchIndex < matchCount) && (matches[*matchIndex] <= hi))
+                ++*matchIndex;
+
+            matchDest.append(branch32(LessThanOrEqual, character, Imm32((unsigned short)hi)));
+            // fall through to here, the value is above hi.
+
+            // shuffle along & loop around if there are any more matches to handle.
+            unsigned next = which + 1;
+            ranges += next;
+            count -= next;
+        } while (count);
+    }
+
+    void matchCharacterClass(RegisterID character, JumpList& matchDest, const CharacterClass* charClass)
+    {
+        Jump unicodeFail;
+        if (charClass->m_matchesUnicode.size() || charClass->m_rangesUnicode.size()) {
+            Jump isAscii = branch32(LessThanOrEqual, character, Imm32(0x7f));
+        
+            if (charClass->m_matchesUnicode.size()) {
+                for (unsigned i = 0; i < charClass->m_matchesUnicode.size(); ++i) {
+                    UChar ch = charClass->m_matchesUnicode[i];
+                    matchDest.append(branch32(Equal, character, Imm32(ch)));
+                }
+            }
+            
+            if (charClass->m_rangesUnicode.size()) {
+                for (unsigned i = 0; i < charClass->m_rangesUnicode.size(); ++i) {
+                    UChar lo = charClass->m_rangesUnicode[i].begin;
+                    UChar hi = charClass->m_rangesUnicode[i].end;
+                    
+                    Jump below = branch32(LessThan, character, Imm32(lo));
+                    matchDest.append(branch32(LessThanOrEqual, character, Imm32(hi)));
+                    below.link(this);
+                }
+            }
+
+            unicodeFail = jump();
+            isAscii.link(this);
+        }
+
+        if (charClass->m_ranges.size()) {
+            unsigned matchIndex = 0;
+            JumpList failures; 
+            matchCharacterClassRange(character, failures, matchDest, charClass->m_ranges.begin(), charClass->m_ranges.size(), &matchIndex, charClass->m_matches.begin(), charClass->m_matches.size());
+            while (matchIndex < charClass->m_matches.size())
+                matchDest.append(branch32(Equal, character, Imm32((unsigned short)charClass->m_matches[matchIndex++])));
+
+            failures.link(this);
+        } else if (charClass->m_matches.size()) {
+            // optimization: gather 'a','A' etc back together, can mask & test once.
+            Vector<char> matchesAZaz;
+
+            for (unsigned i = 0; i < charClass->m_matches.size(); ++i) {
+                char ch = charClass->m_matches[i];
+                if (m_pattern.m_ignoreCase) {
+                    if (isASCIILower(ch)) {
+                        matchesAZaz.append(ch);
+                        continue;
+                    }
+                    if (isASCIIUpper(ch))
+                        continue;
+                }
+                matchDest.append(branch32(Equal, character, Imm32((unsigned short)ch)));
+            }
+
+            if (unsigned countAZaz = matchesAZaz.size()) {
+                or32(Imm32(32), character);
+                for (unsigned i = 0; i < countAZaz; ++i)
+                    matchDest.append(branch32(Equal, character, Imm32(matchesAZaz[i])));
+            }
+        }
+
+        if (charClass->m_matchesUnicode.size() || charClass->m_rangesUnicode.size())
+            unicodeFail.link(this);
+    }
+
+    // Jumps if input not available; will have (incorrectly) incremented already!
+    Jump jumpIfNoAvailableInput(unsigned countToCheck)
+    {
+        add32(Imm32(countToCheck), index);
+        return branch32(Above, index, length);
+    }
+
+    Jump jumpIfAvailableInput(unsigned countToCheck)
+    {
+        add32(Imm32(countToCheck), index);
+        return branch32(BelowOrEqual, index, length);
+    }
+
+    Jump checkInput()
+    {
+        return branch32(BelowOrEqual, index, length);
+    }
+
+    Jump atEndOfInput()
+    {
+        return branch32(Equal, index, length);
+    }
+
+    Jump notAtEndOfInput()
+    {
+        return branch32(NotEqual, index, length);
+    }
+
+    Jump jumpIfCharEquals(UChar ch, int inputPosition)
+    {
+        return branch16(Equal, BaseIndex(input, index, TimesTwo, inputPosition * sizeof(UChar)), Imm32(ch));
+    }
+
+    Jump jumpIfCharNotEquals(UChar ch, int inputPosition)
+    {
+        return branch16(NotEqual, BaseIndex(input, index, TimesTwo, inputPosition * sizeof(UChar)), Imm32(ch));
+    }
+
+    void readCharacter(int inputPosition, RegisterID reg)
+    {
+        load16(BaseIndex(input, index, TimesTwo, inputPosition * sizeof(UChar)), reg);
+    }
+
+    void storeToFrame(RegisterID reg, unsigned frameLocation)
+    {
+        poke(reg, frameLocation);
+    }
+
+    void storeToFrame(Imm32 imm, unsigned frameLocation)
+    {
+        poke(imm, frameLocation);
+    }
+
+    DataLabelPtr storeToFrameWithPatch(unsigned frameLocation)
+    {
+        return storePtrWithPatch(ImmPtr(0), Address(stackPointerRegister, frameLocation * sizeof(void*)));
+    }
+
+    void loadFromFrame(unsigned frameLocation, RegisterID reg)
+    {
+        peek(reg, frameLocation);
+    }
+
+    void loadFromFrameAndJump(unsigned frameLocation)
+    {
+        jump(Address(stackPointerRegister, frameLocation * sizeof(void*)));
+    }
+
+    struct AlternativeBacktrackRecord {
+        DataLabelPtr dataLabel;
+        Label backtrackLocation;
+
+        AlternativeBacktrackRecord(DataLabelPtr dataLabel, Label backtrackLocation)
+            : dataLabel(dataLabel)
+            , backtrackLocation(backtrackLocation)
+        {
+        }
+    };
+
+    struct TermGenerationState {
+        TermGenerationState(PatternDisjunction* disjunction, unsigned checkedTotal)
+            : disjunction(disjunction)
+            , checkedTotal(checkedTotal)
+        {
+        }
+
+        void resetAlternative()
+        {
+            isBackTrackGenerated = false;
+            alt = 0;
+        }
+        bool alternativeValid()
+        {
+            return alt < disjunction->m_alternatives.size();
+        }
+        void nextAlternative()
+        {
+            ++alt;
+        }
+        PatternAlternative* alternative()
+        {
+            return disjunction->m_alternatives[alt];
+        }
+
+        void resetTerm()
+        {
+            ASSERT(alternativeValid());
+            t = 0;
+        }
+        bool termValid()
+        {
+            ASSERT(alternativeValid());
+            return t < alternative()->m_terms.size();
+        }
+        void nextTerm()
+        {
+            ASSERT(alternativeValid());
+            ++t;
+        }
+        PatternTerm& term()
+        {
+            ASSERT(alternativeValid());
+            return alternative()->m_terms[t];
+        }
+
+        PatternTerm& lookaheadTerm()
+        {
+            ASSERT(alternativeValid());
+            ASSERT((t + 1) < alternative()->m_terms.size());
+            return alternative()->m_terms[t + 1];
+        }
+        bool isSinglePatternCharacterLookaheadTerm()
+        {
+            ASSERT(alternativeValid());
+            return ((t + 1) < alternative()->m_terms.size())
+                && (lookaheadTerm().type == PatternTerm::TypePatternCharacter)
+                && (lookaheadTerm().quantityType == QuantifierFixedCount)
+                && (lookaheadTerm().quantityCount == 1);
+        }
+
+        int inputOffset()
+        {
+            return term().inputPosition - checkedTotal;
+        }
+
+        void jumpToBacktrack(Jump jump, MacroAssembler* masm)
+        {
+            if (isBackTrackGenerated)
+                jump.linkTo(backtrackLabel, masm);
+            else
+                backTrackJumps.append(jump);
+        }
+        void jumpToBacktrack(JumpList& jumps, MacroAssembler* masm)
+        {
+            if (isBackTrackGenerated)
+                jumps.linkTo(backtrackLabel, masm);
+            else
+                backTrackJumps.append(jumps);
+        }
+        bool plantJumpToBacktrackIfExists(MacroAssembler* masm)
+        {
+            if (isBackTrackGenerated) {
+                masm->jump(backtrackLabel);
+                return true;
+            }
+            return false;
+        }
+        void addBacktrackJump(Jump jump)
+        {
+            backTrackJumps.append(jump);
+        }
+        void setBacktrackGenerated(Label label)
+        {
+            isBackTrackGenerated = true;
+            backtrackLabel = label;
+        }
+        void linkAlternativeBacktracks(MacroAssembler* masm)
+        {
+            isBackTrackGenerated = false;
+            backTrackJumps.link(masm);
+        }
+        void linkAlternativeBacktracksTo(Label label, MacroAssembler* masm)
+        {
+            isBackTrackGenerated = false;
+            backTrackJumps.linkTo(label, masm);
+        }
+        void propagateBacktrackingFrom(TermGenerationState& nestedParenthesesState, MacroAssembler* masm)
+        {
+            jumpToBacktrack(nestedParenthesesState.backTrackJumps, masm);
+            if (nestedParenthesesState.isBackTrackGenerated)
+                setBacktrackGenerated(nestedParenthesesState.backtrackLabel);
+        }
+
+        PatternDisjunction* disjunction;
+        int checkedTotal;
+    private:
+        unsigned alt;
+        unsigned t;
+        JumpList backTrackJumps;
+        Label backtrackLabel;
+        bool isBackTrackGenerated;
+    };
+
+    void generateAssertionBOL(TermGenerationState& state)
+    {
+        PatternTerm& term = state.term();
+
+        if (m_pattern.m_multiline) {
+            const RegisterID character = regT0;
+
+            JumpList matchDest;
+            if (!term.inputPosition)
+                matchDest.append(branch32(Equal, index, Imm32(state.checkedTotal)));
+
+            readCharacter(state.inputOffset() - 1, character);
+            matchCharacterClass(character, matchDest, m_pattern.newlineCharacterClass());
+            state.jumpToBacktrack(jump(), this);
+
+            matchDest.link(this);
+        } else {
+            // Erk, really should poison out these alternatives early. :-/
+            if (term.inputPosition)
+                state.jumpToBacktrack(jump(), this);
+            else
+                state.jumpToBacktrack(branch32(NotEqual, index, Imm32(state.checkedTotal)), this);
+        }
+    }
+
+    void generateAssertionEOL(TermGenerationState& state)
+    {
+        PatternTerm& term = state.term();
+
+        if (m_pattern.m_multiline) {
+            const RegisterID character = regT0;
+
+            JumpList matchDest;
+            if (term.inputPosition == state.checkedTotal)
+                matchDest.append(atEndOfInput());
+
+            readCharacter(state.inputOffset(), character);
+            matchCharacterClass(character, matchDest, m_pattern.newlineCharacterClass());
+            state.jumpToBacktrack(jump(), this);
+
+            matchDest.link(this);
+        } else {
+            if (term.inputPosition == state.checkedTotal)
+                state.jumpToBacktrack(notAtEndOfInput(), this);
+            // Erk, really should poison out these alternatives early. :-/
+            else
+                state.jumpToBacktrack(jump(), this);
+        }
+    }
+
+    // Also falls though on nextIsNotWordChar.
+    void matchAssertionWordchar(TermGenerationState& state, JumpList& nextIsWordChar, JumpList& nextIsNotWordChar)
+    {
+        const RegisterID character = regT0;
+        PatternTerm& term = state.term();
+
+        if (term.inputPosition == state.checkedTotal)
+            nextIsNotWordChar.append(atEndOfInput());
+
+        readCharacter(state.inputOffset(), character);
+        matchCharacterClass(character, nextIsWordChar, m_pattern.wordcharCharacterClass());
+    }
+
+    void generateAssertionWordBoundary(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        PatternTerm& term = state.term();
+
+        Jump atBegin;
+        JumpList matchDest;
+        if (!term.inputPosition)
+            atBegin = branch32(Equal, index, Imm32(state.checkedTotal));
+        readCharacter(state.inputOffset() - 1, character);
+        matchCharacterClass(character, matchDest, m_pattern.wordcharCharacterClass());
+        if (!term.inputPosition)
+            atBegin.link(this);
+
+        // We fall through to here if the last character was not a wordchar.
+        JumpList nonWordCharThenWordChar;
+        JumpList nonWordCharThenNonWordChar;
+        if (term.invertOrCapture) {
+            matchAssertionWordchar(state, nonWordCharThenNonWordChar, nonWordCharThenWordChar);
+            nonWordCharThenWordChar.append(jump());
+        } else {
+            matchAssertionWordchar(state, nonWordCharThenWordChar, nonWordCharThenNonWordChar);
+            nonWordCharThenNonWordChar.append(jump());
+        }
+        state.jumpToBacktrack(nonWordCharThenNonWordChar, this);
+
+        // We jump here if the last character was a wordchar.
+        matchDest.link(this);
+        JumpList wordCharThenWordChar;
+        JumpList wordCharThenNonWordChar;
+        if (term.invertOrCapture) {
+            matchAssertionWordchar(state, wordCharThenNonWordChar, wordCharThenWordChar);
+            wordCharThenWordChar.append(jump());
+        } else {
+            matchAssertionWordchar(state, wordCharThenWordChar, wordCharThenNonWordChar);
+            // This can fall-though!
+        }
+
+        state.jumpToBacktrack(wordCharThenWordChar, this);
+        
+        nonWordCharThenWordChar.link(this);
+        wordCharThenNonWordChar.link(this);
+    }
+
+    void generatePatternCharacterSingle(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        UChar ch = state.term().patternCharacter;
+
+        if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
+            readCharacter(state.inputOffset(), character);
+            or32(Imm32(32), character);
+            state.jumpToBacktrack(branch32(NotEqual, character, Imm32(Unicode::toLower(ch))), this);
+        } else {
+            ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
+            state.jumpToBacktrack(jumpIfCharNotEquals(ch, state.inputOffset()), this);
+        }
+    }
+
+    void generatePatternCharacterPair(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        UChar ch1 = state.term().patternCharacter;
+        UChar ch2 = state.lookaheadTerm().patternCharacter;
+
+        int mask = 0;
+        int chPair = ch1 | (ch2 << 16);
+        
+        if (m_pattern.m_ignoreCase) {
+            if (isASCIIAlpha(ch1))
+                mask |= 32;
+            if (isASCIIAlpha(ch2))
+                mask |= 32 << 16;
+        }
+
+        if (mask) {
+            load32(BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), character);
+            or32(Imm32(mask), character);
+            state.jumpToBacktrack(branch32(NotEqual, character, Imm32(chPair | mask)), this);
+        } else
+            state.jumpToBacktrack(branch32(NotEqual, BaseIndex(input, index, TimesTwo, state.inputOffset() * sizeof(UChar)), Imm32(chPair)), this);
+    }
+
+    void generatePatternCharacterFixed(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        const RegisterID countRegister = regT1;
+        PatternTerm& term = state.term();
+        UChar ch = term.patternCharacter;
+
+        move(index, countRegister);
+        sub32(Imm32(term.quantityCount), countRegister);
+
+        Label loop(this);
+        if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
+            load16(BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), character);
+            or32(Imm32(32), character);
+            state.jumpToBacktrack(branch32(NotEqual, character, Imm32(Unicode::toLower(ch))), this);
+        } else {
+            ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
+            state.jumpToBacktrack(branch16(NotEqual, BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), Imm32(ch)), this);
+        }
+        add32(Imm32(1), countRegister);
+        branch32(NotEqual, countRegister, index).linkTo(loop, this);
+    }
+
+    void generatePatternCharacterGreedy(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        const RegisterID countRegister = regT1;
+        PatternTerm& term = state.term();
+        UChar ch = term.patternCharacter;
+    
+        move(Imm32(0), countRegister);
+
+        JumpList failures;
+        Label loop(this);
+        failures.append(atEndOfInput());
+        if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
+            readCharacter(state.inputOffset(), character);
+            or32(Imm32(32), character);
+            failures.append(branch32(NotEqual, character, Imm32(Unicode::toLower(ch))));
+        } else {
+            ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
+            failures.append(jumpIfCharNotEquals(ch, state.inputOffset()));
+        }
+        add32(Imm32(1), countRegister);
+        add32(Imm32(1), index);
+        branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this);
+        failures.append(jump());
+
+        Label backtrackBegin(this);
+        loadFromFrame(term.frameLocation, countRegister);
+        state.jumpToBacktrack(branchTest32(Zero, countRegister), this);
+        sub32(Imm32(1), countRegister);
+        sub32(Imm32(1), index);
+
+        failures.link(this);
+
+        storeToFrame(countRegister, term.frameLocation);
+
+        state.setBacktrackGenerated(backtrackBegin);
+    }
+
+    void generatePatternCharacterNonGreedy(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        const RegisterID countRegister = regT1;
+        PatternTerm& term = state.term();
+        UChar ch = term.patternCharacter;
+    
+        move(Imm32(0), countRegister);
+
+        Jump firstTimeDoNothing = jump();
+
+        Label hardFail(this);
+        sub32(countRegister, index);
+        state.jumpToBacktrack(jump(), this);
+
+        Label backtrackBegin(this);
+        loadFromFrame(term.frameLocation, countRegister);
+
+        atEndOfInput().linkTo(hardFail, this);
+        branch32(Equal, countRegister, Imm32(term.quantityCount), hardFail);
+        if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
+            readCharacter(state.inputOffset(), character);
+            or32(Imm32(32), character);
+            branch32(NotEqual, character, Imm32(Unicode::toLower(ch))).linkTo(hardFail, this);
+        } else {
+            ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
+            jumpIfCharNotEquals(ch, state.inputOffset()).linkTo(hardFail, this);
+        }
+
+        add32(Imm32(1), countRegister);
+        add32(Imm32(1), index);
+
+        firstTimeDoNothing.link(this);
+        storeToFrame(countRegister, term.frameLocation);
+
+        state.setBacktrackGenerated(backtrackBegin);
+    }
+
+    void generateCharacterClassSingle(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        PatternTerm& term = state.term();
+
+        JumpList matchDest;
+        readCharacter(state.inputOffset(), character);
+        matchCharacterClass(character, matchDest, term.characterClass);
+
+        if (term.invertOrCapture)
+            state.jumpToBacktrack(matchDest, this);
+        else {
+            state.jumpToBacktrack(jump(), this);
+            matchDest.link(this);
+        }
+    }
+
+    void generateCharacterClassFixed(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        const RegisterID countRegister = regT1;
+        PatternTerm& term = state.term();
+
+        move(index, countRegister);
+        sub32(Imm32(term.quantityCount), countRegister);
+
+        Label loop(this);
+        JumpList matchDest;
+        load16(BaseIndex(input, countRegister, TimesTwo, (state.inputOffset() + term.quantityCount) * sizeof(UChar)), character);
+        matchCharacterClass(character, matchDest, term.characterClass);
+
+        if (term.invertOrCapture)
+            state.jumpToBacktrack(matchDest, this);
+        else {
+            state.jumpToBacktrack(jump(), this);
+            matchDest.link(this);
+        }
+
+        add32(Imm32(1), countRegister);
+        branch32(NotEqual, countRegister, index).linkTo(loop, this);
+    }
+
+    void generateCharacterClassGreedy(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        const RegisterID countRegister = regT1;
+        PatternTerm& term = state.term();
+    
+        move(Imm32(0), countRegister);
+
+        JumpList failures;
+        Label loop(this);
+        failures.append(atEndOfInput());
+
+        if (term.invertOrCapture) {
+            readCharacter(state.inputOffset(), character);
+            matchCharacterClass(character, failures, term.characterClass);
+        } else {
+            JumpList matchDest;
+            readCharacter(state.inputOffset(), character);
+            matchCharacterClass(character, matchDest, term.characterClass);
+            failures.append(jump());
+            matchDest.link(this);
+        }
+
+        add32(Imm32(1), countRegister);
+        add32(Imm32(1), index);
+        branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this);
+        failures.append(jump());
+
+        Label backtrackBegin(this);
+        loadFromFrame(term.frameLocation, countRegister);
+        state.jumpToBacktrack(branchTest32(Zero, countRegister), this);
+        sub32(Imm32(1), countRegister);
+        sub32(Imm32(1), index);
+
+        failures.link(this);
+
+        storeToFrame(countRegister, term.frameLocation);
+
+        state.setBacktrackGenerated(backtrackBegin);
+    }
+
+    void generateCharacterClassNonGreedy(TermGenerationState& state)
+    {
+        const RegisterID character = regT0;
+        const RegisterID countRegister = regT1;
+        PatternTerm& term = state.term();
+    
+        move(Imm32(0), countRegister);
+
+        Jump firstTimeDoNothing = jump();
+
+        Label hardFail(this);
+        sub32(countRegister, index);
+        state.jumpToBacktrack(jump(), this);
+
+        Label backtrackBegin(this);
+        loadFromFrame(term.frameLocation, countRegister);
+
+        atEndOfInput().linkTo(hardFail, this);
+        branch32(Equal, countRegister, Imm32(term.quantityCount), hardFail);
+
+        JumpList matchDest;
+        readCharacter(state.inputOffset(), character);
+        matchCharacterClass(character, matchDest, term.characterClass);
+
+        if (term.invertOrCapture)
+            matchDest.linkTo(hardFail, this);
+        else {
+            jump(hardFail);
+            matchDest.link(this);
+        }
+
+        add32(Imm32(1), countRegister);
+        add32(Imm32(1), index);
+
+        firstTimeDoNothing.link(this);
+        storeToFrame(countRegister, term.frameLocation);
+
+        state.setBacktrackGenerated(backtrackBegin);
+    }
+
+    void generateParenthesesDisjunction(PatternTerm& parenthesesTerm, TermGenerationState& state, unsigned alternativeFrameLocation)
+    {
+        ASSERT((parenthesesTerm.type == PatternTerm::TypeParenthesesSubpattern) || (parenthesesTerm.type == PatternTerm::TypeParentheticalAssertion));
+        ASSERT(parenthesesTerm.quantityCount == 1);
+    
+        PatternDisjunction* disjunction = parenthesesTerm.parentheses.disjunction;
+        unsigned preCheckedCount = ((parenthesesTerm.quantityType == QuantifierFixedCount) && (parenthesesTerm.type != PatternTerm::TypeParentheticalAssertion)) ? disjunction->m_minimumSize : 0;
+
+        if (disjunction->m_alternatives.size() == 1) {
+            state.resetAlternative();
+            ASSERT(state.alternativeValid());
+            PatternAlternative* alternative = state.alternative();
+            optimizeAlternative(alternative);
+
+            int countToCheck = alternative->m_minimumSize - preCheckedCount;
+            if (countToCheck) {
+                ASSERT((parenthesesTerm.type == PatternTerm::TypeParentheticalAssertion) || (parenthesesTerm.quantityType != QuantifierFixedCount));
+
+                // FIXME: This is quite horrible.  The call to 'plantJumpToBacktrackIfExists'
+                // will be forced to always trampoline into here, just to decrement the index.
+                // Ick. 
+                Jump skip = jump();
+
+                Label backtrackBegin(this);
+                sub32(Imm32(countToCheck), index);
+                state.addBacktrackJump(jump());
+                
+                skip.link(this);
+
+                state.setBacktrackGenerated(backtrackBegin);
+
+                state.jumpToBacktrack(jumpIfNoAvailableInput(countToCheck), this);
+                state.checkedTotal += countToCheck;
+            }
+
+            for (state.resetTerm(); state.termValid(); state.nextTerm())
+                generateTerm(state);
+
+            state.checkedTotal -= countToCheck;
+        } else {
+            JumpList successes;
+
+            for (state.resetAlternative(); state.alternativeValid(); state.nextAlternative()) {
+
+                PatternAlternative* alternative = state.alternative();
+                optimizeAlternative(alternative);
+
+                ASSERT(alternative->m_minimumSize >= preCheckedCount);
+                int countToCheck = alternative->m_minimumSize - preCheckedCount;
+                if (countToCheck) {
+                    state.addBacktrackJump(jumpIfNoAvailableInput(countToCheck));
+                    state.checkedTotal += countToCheck;
+                }
+
+                for (state.resetTerm(); state.termValid(); state.nextTerm())
+                    generateTerm(state);
+
+                // Matched an alternative.
+                DataLabelPtr dataLabel = storeToFrameWithPatch(alternativeFrameLocation);
+                successes.append(jump());
+
+                // Alternative did not match.
+                Label backtrackLocation(this);
+                
+                // Can we backtrack the alternative? - if so, do so.  If not, just fall through to the next one.
+                state.plantJumpToBacktrackIfExists(this);
+                
+                state.linkAlternativeBacktracks(this);
+
+                if (countToCheck) {
+                    sub32(Imm32(countToCheck), index);
+                    state.checkedTotal -= countToCheck;
+                }
+
+                m_backtrackRecords.append(AlternativeBacktrackRecord(dataLabel, backtrackLocation));
+            }
+            // We fall through to here when the last alternative fails.
+            // Add a backtrack out of here for the parenthese handling code to link up.
+            state.addBacktrackJump(jump());
+
+            // Generate a trampoline for the parens code to backtrack to, to retry the
+            // next alternative.
+            state.setBacktrackGenerated(label());
+            loadFromFrameAndJump(alternativeFrameLocation);
+
+            // FIXME: both of the above hooks are a little inefficient, in that you
+            // may end up trampolining here, just to trampoline back out to the
+            // parentheses code, or vice versa.  We can probably eliminate a jump
+            // by restructuring, but coding this way for now for simplicity during
+            // development.
+
+            successes.link(this);
+        }
+    }
+
+    void generateParenthesesSingle(TermGenerationState& state)
+    {
+        const RegisterID indexTemporary = regT0;
+        PatternTerm& term = state.term();
+        PatternDisjunction* disjunction = term.parentheses.disjunction;
+        ASSERT(term.quantityCount == 1);
+
+        unsigned preCheckedCount = ((term.quantityCount == 1) && (term.quantityType == QuantifierFixedCount)) ? disjunction->m_minimumSize : 0;
+
+        unsigned parenthesesFrameLocation = term.frameLocation;
+        unsigned alternativeFrameLocation = parenthesesFrameLocation;
+        if (term.quantityType != QuantifierFixedCount)
+            alternativeFrameLocation += RegexStackSpaceForBackTrackInfoParenthesesOnce;
+
+        // optimized case - no capture & no quantifier can be handled in a light-weight manner.
+        if (!term.invertOrCapture && (term.quantityType == QuantifierFixedCount)) {
+            TermGenerationState parenthesesState(disjunction, state.checkedTotal);
+            generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation);
+            // this expects that any backtracks back out of the parentheses will be in the
+            // parenthesesState's backTrackJumps vector, and that if they need backtracking
+            // they will have set an entry point on the parenthesesState's backtrackLabel.
+            state.propagateBacktrackingFrom(parenthesesState, this);
+        } else {
+            Jump nonGreedySkipParentheses;
+            Label nonGreedyTryParentheses;
+            if (term.quantityType == QuantifierGreedy)
+                storeToFrame(Imm32(1), parenthesesFrameLocation);
+            else if (term.quantityType == QuantifierNonGreedy) {
+                storeToFrame(Imm32(0), parenthesesFrameLocation);
+                nonGreedySkipParentheses = jump();
+                nonGreedyTryParentheses = label();
+                storeToFrame(Imm32(1), parenthesesFrameLocation);
+            }
+
+            // store the match start index
+            if (term.invertOrCapture) {
+                int inputOffset = state.inputOffset() - preCheckedCount;
+                if (inputOffset) {
+                    move(index, indexTemporary);
+                    add32(Imm32(inputOffset), indexTemporary);
+                    store32(indexTemporary, Address(output, (term.parentheses.subpatternId << 1) * sizeof(int)));
+                } else
+                    store32(index, Address(output, (term.parentheses.subpatternId << 1) * sizeof(int)));
+            }
+
+            // generate the body of the parentheses
+            TermGenerationState parenthesesState(disjunction, state.checkedTotal);
+            generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation);
+
+            // store the match end index
+            if (term.invertOrCapture) {
+                int inputOffset = state.inputOffset();
+                if (inputOffset) {
+                    move(index, indexTemporary);
+                    add32(Imm32(state.inputOffset()), indexTemporary);
+                    store32(indexTemporary, Address(output, ((term.parentheses.subpatternId << 1) + 1) * sizeof(int)));
+                } else
+                    store32(index, Address(output, ((term.parentheses.subpatternId << 1) + 1) * sizeof(int)));
+            }
+            Jump success = jump();
+
+            // A failure AFTER the parens jumps here
+            Label backtrackFromAfterParens(this);
+
+            if (term.quantityType == QuantifierGreedy) {
+                // If this is zero we have now tested with both with and without the parens.
+                loadFromFrame(parenthesesFrameLocation, indexTemporary);
+                state.jumpToBacktrack(branchTest32(Zero, indexTemporary), this);
+            } else if (term.quantityType == QuantifierNonGreedy) {
+                // If this is zero we have now tested with both with and without the parens.
+                loadFromFrame(parenthesesFrameLocation, indexTemporary);
+                branchTest32(Zero, indexTemporary).linkTo(nonGreedyTryParentheses, this);
+            }
+
+            parenthesesState.plantJumpToBacktrackIfExists(this);
+            // A failure WITHIN the parens jumps here
+            parenthesesState.linkAlternativeBacktracks(this);
+            if (term.invertOrCapture) {
+                store32(Imm32(-1), Address(output, (term.parentheses.subpatternId << 1) * sizeof(int)));
+                store32(Imm32(-1), Address(output, ((term.parentheses.subpatternId << 1) + 1) * sizeof(int)));
+            }
+
+            if (term.quantityType == QuantifierGreedy)
+                storeToFrame(Imm32(0), parenthesesFrameLocation);
+            else
+                state.jumpToBacktrack(jump(), this);
+
+            state.setBacktrackGenerated(backtrackFromAfterParens);
+            if (term.quantityType == QuantifierNonGreedy)
+                nonGreedySkipParentheses.link(this);
+            success.link(this);
+        }
+    }
+
+    void generateParentheticalAssertion(TermGenerationState& state)
+    {
+        PatternTerm& term = state.term();
+        PatternDisjunction* disjunction = term.parentheses.disjunction;
+        ASSERT(term.quantityCount == 1);
+        ASSERT(term.quantityType == QuantifierFixedCount);
+
+        unsigned parenthesesFrameLocation = term.frameLocation;
+        unsigned alternativeFrameLocation = parenthesesFrameLocation + RegexStackSpaceForBackTrackInfoParentheticalAssertion;
+
+        int countCheckedAfterAssertion = state.checkedTotal - term.inputPosition;
+
+        if (term.invertOrCapture) {
+            // Inverted case
+            storeToFrame(index, parenthesesFrameLocation);
+
+            state.checkedTotal -= countCheckedAfterAssertion;
+            if (countCheckedAfterAssertion)
+                sub32(Imm32(countCheckedAfterAssertion), index);
+
+            TermGenerationState parenthesesState(disjunction, state.checkedTotal);
+            generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation);
+            // Success! - which means - Fail!
+            loadFromFrame(parenthesesFrameLocation, index);
+            state.jumpToBacktrack(jump(), this);
+
+            // And fail means success.
+            parenthesesState.linkAlternativeBacktracks(this);
+            loadFromFrame(parenthesesFrameLocation, index);
+
+            state.checkedTotal += countCheckedAfterAssertion;
+        } else {
+            // Normal case
+            storeToFrame(index, parenthesesFrameLocation);
+
+            state.checkedTotal -= countCheckedAfterAssertion;
+            if (countCheckedAfterAssertion)
+                sub32(Imm32(countCheckedAfterAssertion), index);
+
+            TermGenerationState parenthesesState(disjunction, state.checkedTotal);
+            generateParenthesesDisjunction(state.term(), parenthesesState, alternativeFrameLocation);
+            // Success! - which means - Success!
+            loadFromFrame(parenthesesFrameLocation, index);
+            Jump success = jump();
+
+            parenthesesState.linkAlternativeBacktracks(this);
+            loadFromFrame(parenthesesFrameLocation, index);
+            state.jumpToBacktrack(jump(), this);
+
+            success.link(this);
+
+            state.checkedTotal += countCheckedAfterAssertion;
+        }
+    }
+
+    void generateTerm(TermGenerationState& state)
+    {
+        PatternTerm& term = state.term();
+
+        switch (term.type) {
+        case PatternTerm::TypeAssertionBOL:
+            generateAssertionBOL(state);
+            break;
+        
+        case PatternTerm::TypeAssertionEOL:
+            generateAssertionEOL(state);
+            break;
+        
+        case PatternTerm::TypeAssertionWordBoundary:
+            generateAssertionWordBoundary(state);
+            break;
+        
+        case PatternTerm::TypePatternCharacter:
+            switch (term.quantityType) {
+            case QuantifierFixedCount:
+                if (term.quantityCount == 1) {
+                    if (state.isSinglePatternCharacterLookaheadTerm() && (state.lookaheadTerm().inputPosition == (term.inputPosition + 1))) {
+                        generatePatternCharacterPair(state);
+                        state.nextTerm();
+                    } else
+                        generatePatternCharacterSingle(state);
+                } else
+                    generatePatternCharacterFixed(state);
+                break;
+            case QuantifierGreedy:
+                generatePatternCharacterGreedy(state);
+                break;
+            case QuantifierNonGreedy:
+                generatePatternCharacterNonGreedy(state);
+                break;
+            }
+            break;
+
+        case PatternTerm::TypeCharacterClass:
+            switch (term.quantityType) {
+            case QuantifierFixedCount:
+                if (term.quantityCount == 1)
+                    generateCharacterClassSingle(state);
+                else
+                    generateCharacterClassFixed(state);
+                break;
+            case QuantifierGreedy:
+                generateCharacterClassGreedy(state);
+                break;
+            case QuantifierNonGreedy:
+                generateCharacterClassNonGreedy(state);
+                break;
+            }
+            break;
+
+        case PatternTerm::TypeBackReference:
+            m_generationFailed = true;
+            break;
+
+        case PatternTerm::TypeForwardReference:
+            break;
+
+        case PatternTerm::TypeParenthesesSubpattern:
+            if ((term.quantityCount == 1) && !term.parentheses.isCopy)
+                generateParenthesesSingle(state);
+            else
+                m_generationFailed = true;
+            break;
+
+        case PatternTerm::TypeParentheticalAssertion:
+            generateParentheticalAssertion(state);
+            break;
+        }
+    }
+
+    void generateDisjunction(PatternDisjunction* disjunction)
+    {
+        TermGenerationState state(disjunction, 0);
+        state.resetAlternative();
+
+        // Plant a check to see if there is sufficient input available to run the first alternative.
+        // Jumping back to the label 'firstAlternative' will get to this check, jumping to
+        // 'firstAlternativeInputChecked' will jump directly to matching the alternative having
+        // skipped this check.
+
+        Label firstAlternative(this);
+
+        // check availability for the next alternative
+        int countCheckedForCurrentAlternative = 0;
+        int countToCheckForFirstAlternative = 0;
+        bool hasShorterAlternatives = false;
+        JumpList notEnoughInputForPreviousAlternative;
+
+        if (state.alternativeValid()) {
+            PatternAlternative* alternative = state.alternative();
+            countToCheckForFirstAlternative = alternative->m_minimumSize;
+            state.checkedTotal += countToCheckForFirstAlternative;
+            if (countToCheckForFirstAlternative)
+                notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForFirstAlternative));
+            countCheckedForCurrentAlternative = countToCheckForFirstAlternative;
+        }
+
+        Label firstAlternativeInputChecked(this);
+
+        while (state.alternativeValid()) {
+            // Track whether any alternatives are shorter than the first one.
+            hasShorterAlternatives = hasShorterAlternatives || (countCheckedForCurrentAlternative < countToCheckForFirstAlternative);
+
+            PatternAlternative* alternative = state.alternative();
+            optimizeAlternative(alternative);
+
+            for (state.resetTerm(); state.termValid(); state.nextTerm())
+                generateTerm(state);
+
+            // If we get here, the alternative matched.
+            if (m_pattern.m_body->m_callFrameSize)
+                addPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);
+            
+            ASSERT(index != returnRegister);
+            if (m_pattern.m_body->m_hasFixedSize) {
+                move(index, returnRegister);
+                if (alternative->m_minimumSize)
+                    sub32(Imm32(alternative->m_minimumSize), returnRegister);
+            } else
+                pop(returnRegister);
+            store32(index, Address(output, 4));
+            store32(returnRegister, output);
+
+            generateReturn();
+
+            state.nextAlternative();
+
+            // if there are any more alternatives, plant the check for input before looping.
+            if (state.alternativeValid()) {
+                PatternAlternative* nextAlternative = state.alternative();
+                int countToCheckForNextAlternative = nextAlternative->m_minimumSize;
+
+                if (countCheckedForCurrentAlternative > countToCheckForNextAlternative) { // CASE 1: current alternative was longer than the next one.
+                    // If we get here, there the last input checked failed.
+                    notEnoughInputForPreviousAlternative.link(this);
+
+                    // Check if sufficent input available to run the next alternative 
+                    notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
+                    // We are now in the correct state to enter the next alternative; this add is only required
+                    // to mirror and revert operation of the sub32, just below.
+                    add32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
+
+                    // If we get here, there the last input checked passed.
+                    state.linkAlternativeBacktracks(this);
+                    // No need to check if we can run the next alternative, since it is shorter -
+                    // just update index.
+                    sub32(Imm32(countCheckedForCurrentAlternative - countToCheckForNextAlternative), index);
+                } else if (countCheckedForCurrentAlternative < countToCheckForNextAlternative) { // CASE 2: next alternative is longer than the current one.
+                    // If we get here, there the last input checked failed.
+                    // If there is insufficient input to run the current alternative, and the next alternative is longer,
+                    // then there is definitely not enough input to run it - don't even check. Just adjust index, as if
+                    // we had checked.
+                    notEnoughInputForPreviousAlternative.link(this);
+                    add32(Imm32(countToCheckForNextAlternative - countCheckedForCurrentAlternative), index);
+                    notEnoughInputForPreviousAlternative.append(jump());
+
+                    // The next alternative is longer than the current one; check the difference.
+                    state.linkAlternativeBacktracks(this);
+                    notEnoughInputForPreviousAlternative.append(jumpIfNoAvailableInput(countToCheckForNextAlternative - countCheckedForCurrentAlternative));
+                } else { // CASE 3: Both alternatives are the same length.
+                    ASSERT(countCheckedForCurrentAlternative == countToCheckForNextAlternative);
+
+                    // If the next alterative is the same length as this one, then no need to check the input -
+                    // if there was sufficent input to run the current alternative then there is sufficient
+                    // input to run the next one; if not, there isn't.
+                    state.linkAlternativeBacktracks(this);
+                }
+
+                state.checkedTotal -= countCheckedForCurrentAlternative;
+                countCheckedForCurrentAlternative = countToCheckForNextAlternative;
+                state.checkedTotal += countCheckedForCurrentAlternative;
+            }
+        }
+        
+        // If we get here, all Alternatives failed...
+
+        state.checkedTotal -= countCheckedForCurrentAlternative;
+
+        // How much more input need there be to be able to retry from the first alternative?
+        // examples:
+        //   /yarr_jit/ or /wrec|pcre/
+        //     In these examples we need check for one more input before looping.
+        //   /yarr_jit|pcre/
+        //     In this case we need check for 5 more input to loop (+4 to allow for the first alterative
+        //     being four longer than the last alternative checked, and another +1 to effectively move
+        //     the start position along by one).
+        //   /yarr|rules/ or /wrec|notsomuch/
+        //     In these examples, provided that there was sufficient input to have just been matching for
+        //     the second alternative we can loop without checking for available input (since the second
+        //     alternative is longer than the first).  In the latter example we need to decrement index
+        //     (by 4) so the start position is only progressed by 1 from the last iteration.
+        int incrementForNextIter = (countToCheckForFirstAlternative - countCheckedForCurrentAlternative) + 1;
+
+        // First, deal with the cases where there was sufficient input to try the last alternative.
+        if (incrementForNextIter > 0) // We need to check for more input anyway, fall through to the checking below.
+            state.linkAlternativeBacktracks(this);
+        else if (m_pattern.m_body->m_hasFixedSize && !incrementForNextIter) // No need to update anything, link these backtracks straight to the to pof the loop!
+            state.linkAlternativeBacktracksTo(firstAlternativeInputChecked, this);
+        else { // no need to check the input, but we do have some bookkeeping to do first.
+            state.linkAlternativeBacktracks(this);
+
+            // Where necessary update our preserved start position.
+            if (!m_pattern.m_body->m_hasFixedSize) {
+                move(index, regT0);
+                sub32(Imm32(countCheckedForCurrentAlternative - 1), regT0);
+                poke(regT0, m_pattern.m_body->m_callFrameSize);
+            }
+
+            // Update index if necessary, and loop (without checking).
+            if (incrementForNextIter)
+                add32(Imm32(incrementForNextIter), index);
+            jump().linkTo(firstAlternativeInputChecked, this);
+        }
+
+        notEnoughInputForPreviousAlternative.link(this);
+        // Update our idea of the start position, if we're tracking this.
+        if (!m_pattern.m_body->m_hasFixedSize) {
+            if (countCheckedForCurrentAlternative - 1) {
+                move(index, regT0);
+                sub32(Imm32(countCheckedForCurrentAlternative - 1), regT0);
+                poke(regT0, m_pattern.m_body->m_callFrameSize);
+            } else
+                poke(index, m_pattern.m_body->m_callFrameSize);
+        }
+        // Check if there is sufficent input to run the first alternative again.
+        jumpIfAvailableInput(incrementForNextIter).linkTo(firstAlternativeInputChecked, this);
+        // No - insufficent input to run the first alteranative, are there any other alternatives we
+        // might need to check?  If so, the last check will have left the index incremented by
+        // (countToCheckForFirstAlternative + 1), so we need test whether countToCheckForFirstAlternative
+        // LESS input is available, to have the effect of just progressing the start position by 1
+        // from the last iteration.  If this check passes we can just jump up to the check associated
+        // with the first alternative in the loop.  This is a bit sad, since we'll end up trying the
+        // first alternative again, and this check will fail (otherwise the check planted just above
+        // here would have passed).  This is a bit sad, however it saves trying to do something more
+        // complex here in compilation, and in the common case we should end up coallescing the checks.
+        //
+        // FIXME: a nice improvement here may be to stop trying to match sooner, based on the least
+        // of the minimum-alterantive-lengths.  E.g. if I have two alternatives of length 200 and 150,
+        // and a string of length 100, we'll end up looping index from 0 to 100, checking whether there
+        // is sufficient input to run either alternative (constantly failing).  If there had been only
+        // one alternative, or if the shorter alternative had come first, we would have terminated
+        // immediately. :-/
+        if (hasShorterAlternatives)
+            jumpIfAvailableInput(-countToCheckForFirstAlternative).linkTo(firstAlternative, this);
+        // index will now be a bit garbled (depending on whether 'hasShorterAlternatives' is true,
+        // it has either been incremented by 1 or by (countToCheckForFirstAlternative + 1) ... 
+        // but since we're about to return a failure this doesn't really matter!)
+
+        unsigned frameSize = m_pattern.m_body->m_callFrameSize;
+        if (!m_pattern.m_body->m_hasFixedSize)
+            ++frameSize;
+        if (frameSize)
+            addPtr(Imm32(frameSize * sizeof(void*)), stackPointerRegister);
+
+        move(Imm32(-1), returnRegister);
+
+        generateReturn();
+    }
+
+    void generateEnter()
+    {
+#if PLATFORM(X86_64)
+        push(X86::ebp);
+        move(stackPointerRegister, X86::ebp);
+        push(X86::ebx);
+#elif PLATFORM(X86)
+        push(X86::ebp);
+        move(stackPointerRegister, X86::ebp);
+        // TODO: do we need spill registers to fill the output pointer if there are no sub captures?
+        push(X86::ebx);
+        push(X86::edi);
+        push(X86::esi);
+        // load output into edi (2 = saved ebp + return address).
+    #if COMPILER(MSVC)
+        loadPtr(Address(X86::ebp, 2 * sizeof(void*)), input);
+        loadPtr(Address(X86::ebp, 3 * sizeof(void*)), index);
+        loadPtr(Address(X86::ebp, 4 * sizeof(void*)), length);
+        loadPtr(Address(X86::ebp, 5 * sizeof(void*)), output);
+    #else
+        loadPtr(Address(X86::ebp, 2 * sizeof(void*)), output);
+    #endif
+#elif PLATFORM_ARM_ARCH(7)
+        push(ARM::r4);
+        push(ARM::r5);
+        push(ARM::r6);
+        move(ARM::r3, output);
+#endif
+    }
+
+    void generateReturn()
+    {
+#if PLATFORM(X86_64)
+        pop(X86::ebx);
+        pop(X86::ebp);
+#elif PLATFORM(X86)
+        pop(X86::esi);
+        pop(X86::edi);
+        pop(X86::ebx);
+        pop(X86::ebp);
+#elif PLATFORM_ARM_ARCH(7)
+        pop(ARM::r6);
+        pop(ARM::r5);
+        pop(ARM::r4);
+#endif
+        ret();
+    }
+
+public:
+    RegexGenerator(RegexPattern& pattern)
+        : m_pattern(pattern)
+        , m_generationFailed(false)
+    {
+    }
+
+    void generate()
+    {
+        generateEnter();
+
+        // TODO: do I really want this on the stack?
+        if (!m_pattern.m_body->m_hasFixedSize)
+            push(index);
+
+        if (m_pattern.m_body->m_callFrameSize)
+            subPtr(Imm32(m_pattern.m_body->m_callFrameSize * sizeof(void*)), stackPointerRegister);
+
+        generateDisjunction(m_pattern.m_body);
+    }
+
+    void compile(JSGlobalData* globalData, RegexCodeBlock& jitObject)
+    {
+        generate();
+
+        LinkBuffer patchBuffer(this, globalData->executableAllocator.poolForSize(size()));
+
+        for (unsigned i = 0; i < m_backtrackRecords.size(); ++i)
+            patchBuffer.patch(m_backtrackRecords[i].dataLabel, patchBuffer.locationOf(m_backtrackRecords[i].backtrackLocation));
+
+        jitObject.set(patchBuffer.finalizeCode());
+    }
+
+    bool generationFailed()
+    {
+        return m_generationFailed;
+    }
+
+private:
+    RegexPattern& m_pattern;
+    Vector<AlternativeBacktrackRecord> m_backtrackRecords;
+    bool m_generationFailed;
+};
+
+void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& patternString, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline)
+{
+    RegexPattern pattern(ignoreCase, multiline);
+
+    if ((error = compileRegex(patternString, pattern)))
+        return;
+
+    numSubpatterns = pattern.m_numSubpatterns;
+
+    RegexGenerator generator(pattern);
+    generator.compile(globalData, jitObject);
+
+    if (generator.generationFailed()) {
+        JSRegExpIgnoreCaseOption ignoreCaseOption = ignoreCase ? JSRegExpIgnoreCase : JSRegExpDoNotIgnoreCase;
+        JSRegExpMultilineOption multilineOption = multiline ? JSRegExpMultiline : JSRegExpSingleLine;
+        jitObject.setFallback(jsRegExpCompile(reinterpret_cast<const UChar*>(patternString.data()), patternString.size(), ignoreCaseOption, multilineOption, &numSubpatterns, &error));
+    }
+}
+
+int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize)
+{
+    if (JSRegExp* fallback = jitObject.getFallback())
+        return (jsRegExpExecute(fallback, input, length, start, output, outputArraySize) < 0) ? -1 : output[0];
+
+    return jitObject.execute(input, start, length, output);
+}
+
+}}
+
+#endif
+
+
+
+
+
diff --git a/yarr/RegexJIT.h b/yarr/RegexJIT.h
new file mode 100644 (file)
index 0000000..5b0df9d
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RegexJIT_h
+#define RegexJIT_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(YARR_JIT)
+
+#include "MacroAssembler.h"
+#include "RegexPattern.h"
+#include <UString.h>
+
+#include <pcre.h>
+struct JSRegExp; // temporary, remove when fallback is removed.
+
+#if PLATFORM(X86) && !COMPILER(MSVC)
+#define YARR_CALL __attribute__ ((regparm (3)))
+#else
+#define YARR_CALL
+#endif
+
+namespace JSC {
+
+class JSGlobalData;
+class ExecutablePool;
+
+namespace Yarr {
+
+class RegexCodeBlock {
+    typedef int (*RegexJITCode)(const UChar* input, unsigned start, unsigned length, int* output) YARR_CALL;
+
+public:
+    RegexCodeBlock()
+        : m_fallback(0)
+    {
+    }
+
+    ~RegexCodeBlock()
+    {
+        if (m_fallback)
+            jsRegExpFree(m_fallback);
+    }
+
+    JSRegExp* getFallback() { return m_fallback; }
+    void setFallback(JSRegExp* fallback) { m_fallback = fallback; }
+
+    bool operator!() { return !m_ref.m_code.executableAddress(); }
+    void set(MacroAssembler::CodeRef ref) { m_ref = ref; }
+
+    int execute(const UChar* input, unsigned start, unsigned length, int* output)
+    {
+        return reinterpret_cast<RegexJITCode>(m_ref.m_code.executableAddress())(input, start, length, output);
+    }
+
+private:
+    MacroAssembler::CodeRef m_ref;
+    JSRegExp* m_fallback;
+};
+
+void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase = false, bool multiline = false);
+int executeRegex(RegexCodeBlock& jitObject, const UChar* input, unsigned start, unsigned length, int* output, int outputArraySize);
+
+} } // namespace JSC::Yarr
+
+#endif
+
+#endif // RegexJIT_h
diff --git a/yarr/RegexParser.h b/yarr/RegexParser.h
new file mode 100644 (file)
index 0000000..64e8463
--- /dev/null
@@ -0,0 +1,854 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RegexParser_h
+#define RegexParser_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(YARR)
+
+#include <UString.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/unicode/Unicode.h>
+#include <limits.h>
+
+namespace JSC { namespace Yarr {
+
+enum BuiltInCharacterClassID {
+    DigitClassID,
+    SpaceClassID,
+    WordClassID,
+    NewlineClassID,
+};
+
+// The Parser class should not be used directly - only via the Yarr::parse() method.
+template<class Delegate>
+class Parser {
+private:
+    template<class FriendDelegate>
+    friend const char* parse(FriendDelegate& delegate, const UString& pattern, unsigned backReferenceLimit);
+
+    enum ErrorCode {
+        NoError,
+        PatternTooLarge,
+        QuantifierOutOfOrder,
+        QuantifierWithoutAtom,
+        MissingParentheses,
+        ParenthesesUnmatched,
+        ParenthesesTypeInvalid,
+        CharacterClassUnmatched,
+        CharacterClassOutOfOrder,
+        EscapeUnterminated,
+        NumberOfErrorCodes
+    };
+
+    /*
+     * CharacterClassParserDelegate:
+     *
+     * The class CharacterClassParserDelegate is used in the parsing of character
+     * classes.  This class handles detection of character ranges.  This class
+     * implements enough of the delegate interface such that it can be passed to
+     * parseEscape() as an EscapeDelegate.  This allows parseEscape() to be reused
+     * to perform the parsing of escape characters in character sets.
+     */
+    class CharacterClassParserDelegate {
+    public:
+        CharacterClassParserDelegate(Delegate& delegate, ErrorCode& err)
+            : m_delegate(delegate)
+            , m_err(err)
+            , m_state(empty)
+        {
+        }
+
+        /*
+         * begin():
+         *
+         * Called at beginning of construction.
+         */
+        void begin(bool invert)
+        {
+            m_delegate.atomCharacterClassBegin(invert);
+        }
+
+        /*
+         * atomPatternCharacterUnescaped():
+         *
+         * This method is called directly from parseCharacterClass(), to report a new
+         * pattern character token.  This method differs from atomPatternCharacter(),
+         * which will be called from parseEscape(), since a hypen provided via this
+         * method may be indicating a character range, but a hyphen parsed by
+         * parseEscape() cannot be interpreted as doing so.
+         */
+        void atomPatternCharacterUnescaped(UChar ch)
+        {
+            switch (m_state) {
+            case empty:
+                m_character = ch;
+                m_state = cachedCharacter;
+                break;
+
+            case cachedCharacter:
+                if (ch == '-')
+                    m_state = cachedCharacterHyphen;
+                else {
+                    m_delegate.atomCharacterClassAtom(m_character);
+                    m_character = ch;
+                }
+                break;
+
+            case cachedCharacterHyphen:
+                if (ch >= m_character)
+                    m_delegate.atomCharacterClassRange(m_character, ch);
+                else
+                    m_err = CharacterClassOutOfOrder;
+                m_state = empty;
+            }
+        }
+
+        /*
+         * atomPatternCharacter():
+         *
+         * Adds a pattern character, called by parseEscape(), as such will not
+         * interpret a hyphen as indicating a character range.
+         */
+        void atomPatternCharacter(UChar ch)
+        {
+            // Flush if a character is already pending to prevent the
+            // hyphen from begin interpreted as indicating a range.
+            if((ch == '-') && (m_state == cachedCharacter))
+                flush();
+
+            atomPatternCharacterUnescaped(ch);
+        }
+
+        /*
+         * atomBuiltInCharacterClass():
+         *
+         * Adds a built-in character class, called by parseEscape().
+         */
+        void atomBuiltInCharacterClass(BuiltInCharacterClassID classID, bool invert)
+        {
+            flush();
+            m_delegate.atomCharacterClassBuiltIn(classID, invert);
+        }
+
+        /*
+         * end():
+         *
+         * Called at end of construction.
+         */
+        void end()
+        {
+            flush();
+            m_delegate.atomCharacterClassEnd();
+        }
+
+        // parseEscape() should never call these delegate methods when
+        // invoked with inCharacterClass set.
+        void assertionWordBoundary(bool) { ASSERT_NOT_REACHED(); }
+        void atomBackReference(unsigned) { ASSERT_NOT_REACHED(); }
+
+    private:
+        void flush()
+        {
+            if (m_state != empty) // either cachedCharacter or cachedCharacterHyphen
+                m_delegate.atomCharacterClassAtom(m_character);
+            if (m_state == cachedCharacterHyphen)
+                m_delegate.atomCharacterClassAtom('-');
+            m_state = empty;
+        }
+    
+        Delegate& m_delegate;
+        ErrorCode& m_err;
+        enum CharacterClassConstructionState {
+            empty,
+            cachedCharacter,
+            cachedCharacterHyphen,
+        } m_state;
+        UChar m_character;
+    };
+
+    Parser(Delegate& delegate, const UString& pattern, unsigned backReferenceLimit)
+        : m_delegate(delegate)
+        , m_backReferenceLimit(backReferenceLimit)
+        , m_err(NoError)
+        , m_data(pattern.data())
+        , m_size(pattern.size())
+        , m_index(0)
+        , m_parenthesesNestingDepth(0)
+    {
+    }
+    
+    /*
+     * parseEscape():
+     *
+     * Helper for parseTokens() AND parseCharacterClass().
+     * Unlike the other parser methods, this function does not report tokens
+     * directly to the member delegate (m_delegate), instead tokens are
+     * emitted to the delegate provided as an argument.  In the case of atom
+     * escapes, parseTokens() will call parseEscape() passing m_delegate as
+     * an argument, and as such the escape will be reported to the delegate.
+     *
+     * However this method may also be used by parseCharacterClass(), in which
+     * case a CharacterClassParserDelegate will be passed as the delegate that
+     * tokens should be added to.  A boolean flag is also provided to indicate
+     * whether that an escape in a CharacterClass is being parsed (some parsing
+     * rules change in this context).
+     *
+     * The boolean value returned by this method indicates whether the token
+     * parsed was an atom (outside of a characted class \b and \B will be
+     * interpreted as assertions).
+     */
+    template<bool inCharacterClass, class EscapeDelegate>
+    bool parseEscape(EscapeDelegate& delegate)
+    {
+        ASSERT(!m_err);
+        ASSERT(peek() == '\\');
+        consume();
+
+        if (atEndOfPattern()) {
+            m_err = EscapeUnterminated;
+            return false;
+        }
+
+        switch (peek()) {
+        // Assertions
+        case 'b':
+            consume();
+            if (inCharacterClass)
+                delegate.atomPatternCharacter('\b');
+            else {
+                delegate.assertionWordBoundary(false);
+                return false;
+            }
+            break;
+        case 'B':
+            consume();
+            if (inCharacterClass)
+                delegate.atomPatternCharacter('B');
+            else {
+                delegate.assertionWordBoundary(true);
+                return false;
+            }
+            break;
+
+        // CharacterClassEscape
+        case 'd':
+            consume();
+            delegate.atomBuiltInCharacterClass(DigitClassID, false);
+            break;
+        case 's':
+            consume();
+            delegate.atomBuiltInCharacterClass(SpaceClassID, false);
+            break;
+        case 'w':
+            consume();
+            delegate.atomBuiltInCharacterClass(WordClassID, false);
+            break;
+        case 'D':
+            consume();
+            delegate.atomBuiltInCharacterClass(DigitClassID, true);
+            break;
+        case 'S':
+            consume();
+            delegate.atomBuiltInCharacterClass(SpaceClassID, true);
+            break;
+        case 'W':
+            consume();
+            delegate.atomBuiltInCharacterClass(WordClassID, true);
+            break;
+
+        // DecimalEscape
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9': {
+            // To match Firefox, we parse an invalid backreference in the range [1-7] as an octal escape.
+            // First, try to parse this as backreference.
+            if (!inCharacterClass) {
+                ParseState state = saveState();
+
+                unsigned backReference = consumeNumber();
+                if (backReference <= m_backReferenceLimit) {
+                    delegate.atomBackReference(backReference);
+                    break;
+                }
+
+                restoreState(state);
+            }
+            
+            // Not a backreference, and not octal.
+            if (peek() >= '8') {
+                delegate.atomPatternCharacter('\\');
+                break;
+            }
+
+            // Fall-through to handle this as an octal escape.
+        }
+
+        // Octal escape
+        case '0':
+            delegate.atomPatternCharacter(consumeOctal());
+            break;
+
+        // ControlEscape
+        case 'f':
+            consume();
+            delegate.atomPatternCharacter('\f');
+            break;
+        case 'n':
+            consume();
+            delegate.atomPatternCharacter('\n');
+            break;
+        case 'r':
+            consume();
+            delegate.atomPatternCharacter('\r');
+            break;
+        case 't':
+            consume();
+            delegate.atomPatternCharacter('\t');
+            break;
+        case 'v':
+            consume();
+            delegate.atomPatternCharacter('\v');
+            break;
+
+        // ControlLetter
+        case 'c': {
+            ParseState state = saveState();
+            consume();
+            if (!atEndOfPattern()) {
+                int control = consume();
+
+                // To match Firefox, inside a character class, we also accept numbers and '_' as control characters.
+                if (inCharacterClass ? WTF::isASCIIAlphanumeric(control) || (control == '_') : WTF::isASCIIAlpha(control)) {
+                    delegate.atomPatternCharacter(control & 0x1f);
+                    break;
+                }
+            }
+            restoreState(state);
+            delegate.atomPatternCharacter('\\');
+            break;
+        }
+
+        // HexEscape
+        case 'x': {
+            consume();
+            int x = tryConsumeHex(2);
+            if (x == -1)
+                delegate.atomPatternCharacter('x');
+            else
+                delegate.atomPatternCharacter(x);
+            break;
+        }
+
+        // UnicodeEscape
+        case 'u': {
+            consume();
+            int u = tryConsumeHex(4);
+            if (u == -1)
+                delegate.atomPatternCharacter('u');
+            else
+                delegate.atomPatternCharacter(u);
+            break;
+        }
+
+        // IdentityEscape
+        default:
+            delegate.atomPatternCharacter(consume());
+        }
+        
+        return true;
+    }
+
+    /*
+     * parseAtomEscape(), parseCharacterClassEscape():
+     *
+     * These methods alias to parseEscape().
+     */
+    bool parseAtomEscape()
+    {
+        return parseEscape<false>(m_delegate);
+    }
+    void parseCharacterClassEscape(CharacterClassParserDelegate& delegate)
+    {
+        parseEscape<true>(delegate);
+    }
+
+    /*
+     * parseCharacterClass():
+     *
+     * Helper for parseTokens(); calls dirctly and indirectly (via parseCharacterClassEscape)
+     * to an instance of CharacterClassParserDelegate, to describe the character class to the
+     * delegate.
+     */
+    void parseCharacterClass()
+    {
+        ASSERT(!m_err);
+        ASSERT(peek() == '[');
+        consume();
+
+        CharacterClassParserDelegate characterClassConstructor(m_delegate, m_err);
+
+        characterClassConstructor.begin(tryConsume('^'));
+
+        while (!atEndOfPattern()) {
+            switch (peek()) {
+            case ']':
+                consume();
+                characterClassConstructor.end();
+                return;
+
+            case '\\':
+                parseCharacterClassEscape(characterClassConstructor);
+                break;
+
+            default:
+                characterClassConstructor.atomPatternCharacterUnescaped(consume());
+            }
+
+            if (m_err)
+                return;
+        }
+
+        m_err = CharacterClassUnmatched;
+    }
+
+    /*
+     * parseParenthesesBegin():
+     *
+     * Helper for parseTokens(); checks for parentheses types other than regular capturing subpatterns.
+     */
+    void parseParenthesesBegin()
+    {
+        ASSERT(!m_err);
+        ASSERT(peek() == '(');
+        consume();
+
+        if (tryConsume('?')) {
+            if (atEndOfPattern()) {
+                m_err = ParenthesesTypeInvalid;
+                return;
+            }
+
+            switch (consume()) {
+            case ':':
+                m_delegate.atomParenthesesSubpatternBegin(false);
+                break;
+            
+            case '=':
+                m_delegate.atomParentheticalAssertionBegin();
+                break;
+
+            case '!':
+                m_delegate.atomParentheticalAssertionBegin(true);
+                break;
+            
+            default:
+                m_err = ParenthesesTypeInvalid;
+            }
+        } else
+            m_delegate.atomParenthesesSubpatternBegin();
+
+        ++m_parenthesesNestingDepth;
+    }
+
+    /*
+     * parseParenthesesEnd():
+     *
+     * Helper for parseTokens(); checks for parse errors (due to unmatched parentheses).
+     */
+    void parseParenthesesEnd()
+    {
+        ASSERT(!m_err);
+        ASSERT(peek() == ')');
+        consume();
+
+        if (m_parenthesesNestingDepth > 0)
+            m_delegate.atomParenthesesEnd();
+        else
+            m_err = ParenthesesUnmatched;
+
+        --m_parenthesesNestingDepth;
+    }
+
+    /*
+     * parseQuantifier():
+     *
+     * Helper for parseTokens(); checks for parse errors and non-greedy quantifiers.
+     */
+    void parseQuantifier(bool lastTokenWasAnAtom, unsigned min, unsigned max)
+    {
+        ASSERT(!m_err);
+        ASSERT(min <= max);
+
+        if (lastTokenWasAnAtom)
+            m_delegate.quantifyAtom(min, max, !tryConsume('?'));
+        else
+            m_err = QuantifierWithoutAtom;
+    }
+
+    /*
+     * parseTokens():
+     *
+     * This method loops over the input pattern reporting tokens to the delegate.
+     * The method returns when a parse error is detected, or the end of the pattern
+     * is reached.  One piece of state is tracked around the loop, which is whether
+     * the last token passed to the delegate was an atom (this is necessary to detect
+     * a parse error when a quantifier provided without an atom to quantify).
+     */
+    void parseTokens()
+    {
+        bool lastTokenWasAnAtom = false;
+
+        while (!atEndOfPattern()) {
+            switch (peek()) {
+            case '|':
+                consume();
+                m_delegate.disjunction();
+                lastTokenWasAnAtom = false;
+                break;
+
+            case '(':
+                parseParenthesesBegin();
+                lastTokenWasAnAtom = false;
+                break;
+
+            case ')':
+                parseParenthesesEnd();
+                lastTokenWasAnAtom = true;
+                break;
+
+            case '^':
+                consume();
+                m_delegate.assertionBOL();
+                lastTokenWasAnAtom = false;
+                break;
+
+            case '$':
+                consume();
+                m_delegate.assertionEOL();
+                lastTokenWasAnAtom = false;
+                break;
+
+            case '.':
+                consume();
+                m_delegate.atomBuiltInCharacterClass(NewlineClassID, true);
+                lastTokenWasAnAtom = true;
+                break;
+
+            case '[':
+                parseCharacterClass();
+                lastTokenWasAnAtom = true;
+                break;
+
+            case '\\':
+                lastTokenWasAnAtom = parseAtomEscape();
+                break;
+
+            case '*':
+                consume();
+                parseQuantifier(lastTokenWasAnAtom, 0, UINT_MAX);
+                lastTokenWasAnAtom = false;
+                break;
+
+            case '+':
+                consume();
+                parseQuantifier(lastTokenWasAnAtom, 1, UINT_MAX);
+                lastTokenWasAnAtom = false;
+                break;
+
+            case '?':
+                consume();
+                parseQuantifier(lastTokenWasAnAtom, 0, 1);
+                lastTokenWasAnAtom = false;
+                break;
+
+            case '{': {
+                ParseState state = saveState();
+
+                consume();
+                if (peekIsDigit()) {
+                    unsigned min = consumeNumber();
+                    unsigned max = min;
+                    
+                    if (tryConsume(','))
+                        max = peekIsDigit() ? consumeNumber() : UINT_MAX;
+
+                    if (tryConsume('}')) {
+                        if (min <= max)
+                            parseQuantifier(lastTokenWasAnAtom, min, max);
+                        else
+                            m_err = QuantifierOutOfOrder;
+                        lastTokenWasAnAtom = false;
+                        break;
+                    }
+                }
+
+                restoreState(state);
+            } // if we did not find a complete quantifer, fall through to the default case.
+
+            default:
+                m_delegate.atomPatternCharacter(consume());
+                lastTokenWasAnAtom = true;
+            }
+
+            if (m_err)
+                return;
+        }
+
+        if (m_parenthesesNestingDepth > 0)
+            m_err = MissingParentheses;
+    }
+
+    /*
+     * parse():
+     *
+     * This method calls regexBegin(), calls parseTokens() to parse over the input
+     * patterns, calls regexEnd() or regexError() as appropriate, and converts any
+     * error code to a const char* for a result.
+     */
+    const char* parse()
+    {
+        m_delegate.regexBegin();
+
+        if (m_size > MAX_PATTERN_SIZE)
+            m_err = PatternTooLarge;
+        else
+            parseTokens();
+        ASSERT(atEndOfPattern() || m_err);
+
+        if (m_err)
+            m_delegate.regexError();
+        else
+            m_delegate.regexEnd();
+
+        // The order of this array must match the ErrorCode enum.
+        static const char* errorMessages[NumberOfErrorCodes] = {
+            0, // NoError
+            "regular expression too large",
+            "numbers out of order in {} quantifier",
+            "nothing to repeat",
+            "missing )",
+            "unmatched parentheses",
+            "unrecognized character after (?",
+            "missing terminating ] for character class",
+            "range out of order in character class",
+            "\\ at end of pattern"
+        };
+
+        return errorMessages[m_err];
+    }
+
+
+    // Misc helper functions:
+
+    typedef unsigned ParseState;
+    
+    ParseState saveState()
+    {
+        return m_index;
+    }
+
+    void restoreState(ParseState state)
+    {
+        m_index = state;
+    }
+
+    bool atEndOfPattern()
+    {
+        ASSERT(m_index <= m_size);
+        return m_index == m_size;
+    }
+
+    int peek()
+    {
+        ASSERT(m_index < m_size);
+        return m_data[m_index];
+    }
+
+    bool peekIsDigit()
+    {
+        return !atEndOfPattern() && WTF::isASCIIDigit(peek());
+    }
+
+    unsigned peekDigit()
+    {
+        ASSERT(peekIsDigit());
+        return peek() - '0';
+    }
+
+    int consume()
+    {
+        ASSERT(m_index < m_size);
+        return m_data[m_index++];
+    }
+
+    unsigned consumeDigit()
+    {
+        ASSERT(peekIsDigit());
+        return consume() - '0';
+    }
+
+    unsigned consumeNumber()
+    {
+        unsigned n = consumeDigit();
+        // check for overflow.
+        for (unsigned newValue; peekIsDigit() && ((newValue = n * 10 + peekDigit()) >= n); ) {
+            n = newValue;
+            consume();
+        }
+        return n;
+    }
+
+    unsigned consumeOctal()
+    {
+        ASSERT(WTF::isASCIIOctalDigit(peek()));
+
+        unsigned n = consumeDigit();
+        while (n < 32 && !atEndOfPattern() && WTF::isASCIIOctalDigit(peek()))
+            n = n * 8 + consumeDigit();
+        return n;
+    }
+
+    bool tryConsume(UChar ch)
+    {
+        if (atEndOfPattern() || (m_data[m_index] != ch))
+            return false;
+        ++m_index;
+        return true;
+    }
+
+    int tryConsumeHex(int count)
+    {
+        ParseState state = saveState();
+
+        int n = 0;
+        while (count--) {
+            if (atEndOfPattern() || !WTF::isASCIIHexDigit(peek())) {
+                restoreState(state);
+                return -1;
+            }
+            n = (n << 4) | WTF::toASCIIHexValue(consume());
+        }
+        return n;
+    }
+
+    Delegate& m_delegate;
+    unsigned m_backReferenceLimit;
+    ErrorCode m_err;
+    const UChar* m_data;
+    unsigned m_size;
+    unsigned m_index;
+    unsigned m_parenthesesNestingDepth;
+
+    // Derived by empirical testing of compile time in PCRE and WREC.
+    static const unsigned MAX_PATTERN_SIZE = 1024 * 1024;
+};
+
+/*
+ * Yarr::parse():
+ *
+ * The parse method is passed a pattern to be parsed and a delegate upon which
+ * callbacks will be made to record the parsed tokens forming the regex.
+ * Yarr::parse() returns null on success, or a const C string providing an error
+ * message where a parse error occurs.
+ *
+ * The Delegate must implement the following interface:
+ *
+ *    void assertionBOL();
+ *    void assertionEOL();
+ *    void assertionWordBoundary(bool invert);
+ *
+ *    void atomPatternCharacter(UChar ch);
+ *    void atomBuiltInCharacterClass(BuiltInCharacterClassID classID, bool invert);
+ *    void atomCharacterClassBegin(bool invert)
+ *    void atomCharacterClassAtom(UChar ch)
+ *    void atomCharacterClassRange(UChar begin, UChar end)
+ *    void atomCharacterClassBuiltIn(BuiltInCharacterClassID classID, bool invert)
+ *    void atomCharacterClassEnd()
+ *    void atomParenthesesSubpatternBegin(bool capture = true);
+ *    void atomParentheticalAssertionBegin(bool invert = false);
+ *    void atomParenthesesEnd();
+ *    void atomBackReference(unsigned subpatternId);
+ *
+ *    void quantifyAtom(unsigned min, unsigned max, bool greedy);
+ *
+ *    void disjunction();
+ *
+ *    void regexBegin();
+ *    void regexEnd();
+ *    void regexError();
+ *
+ * Before any call recording tokens are made, regexBegin() will be called on the
+ * delegate once.  Once parsing is complete either regexEnd() or regexError() will
+ * be called, as appropriate.
+ *
+ * The regular expression is described by a sequence of assertion*() and atom*()
+ * callbacks to the delegate, describing the terms in the regular expression.
+ * Following an atom a quantifyAtom() call may occur to indicate that the previous
+ * atom should be quantified.  In the case of atoms described across multiple
+ * calls (parentheses and character classes) the call to quantifyAtom() will come
+ * after the call to the atom*End() method, never after atom*Begin().
+ *
+ * Character classes may either be described by a single call to
+ * atomBuiltInCharacterClass(), or by a sequence of atomCharacterClass*() calls.
+ * In the latter case, ...Begin() will be called, followed by a sequence of
+ * calls to ...Atom(), ...Range(), and ...BuiltIn(), followed by a call to ...End().
+ *
+ * Sequences of atoms and assertions are broken into alternatives via calls to
+ * disjunction().  Assertions, atoms, and disjunctions emitted between calls to
+ * atomParenthesesBegin() and atomParenthesesEnd() form the body of a subpattern.
+ * atomParenthesesBegin() is passed a subpatternId.  In the case of a regular
+ * capturing subpattern, this will be the subpatternId associated with these
+ * parentheses, and will also by definition be the lowest subpatternId of these
+ * parentheses and of any nested paretheses.  The atomParenthesesEnd() method
+ * is passed the subpatternId of the last capturing subexpression nested within
+ * these paretheses.  In the case of a capturing subpattern with no nested
+ * capturing subpatterns, the same subpatternId will be passed to the begin and
+ * end functions.  In the case of non-capturing subpatterns the subpatternId
+ * passed to the begin method is also the first possible subpatternId that might
+ * be nested within these paretheses.  If a set of non-capturing parentheses does
+ * not contain any capturing subpatterns, then the subpatternId passed to begin
+ * will be greater than the subpatternId passed to end.
+ */
+
+template<class Delegate>
+const char* parse(Delegate& delegate, const UString& pattern, unsigned backReferenceLimit = UINT_MAX)
+{
+    return Parser<Delegate>(delegate, pattern, backReferenceLimit).parse();
+}
+
+} } // namespace JSC::Yarr
+
+#endif
+
+#endif // RegexParser_h
diff --git a/yarr/RegexPattern.h b/yarr/RegexPattern.h
new file mode 100644 (file)
index 0000000..fb1b0ab
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RegexPattern_h
+#define RegexPattern_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(YARR)
+
+#include <wtf/Vector.h>
+#include <wtf/unicode/Unicode.h>
+
+
+namespace JSC { namespace Yarr {
+
+#define RegexStackSpaceForBackTrackInfoPatternCharacter 1 // Only for !fixed quantifiers.
+#define RegexStackSpaceForBackTrackInfoCharacterClass 1 // Only for !fixed quantifiers.
+#define RegexStackSpaceForBackTrackInfoBackReference 2
+#define RegexStackSpaceForBackTrackInfoAlternative 1 // One per alternative.
+#define RegexStackSpaceForBackTrackInfoParentheticalAssertion 1
+#define RegexStackSpaceForBackTrackInfoParenthesesOnce 1 // Only for !fixed quantifiers.
+#define RegexStackSpaceForBackTrackInfoParentheses 4
+
+struct PatternDisjunction;
+
+struct CharacterRange {
+    UChar begin;
+    UChar end;
+
+    CharacterRange(UChar begin, UChar end)
+        : begin(begin)
+        , end(end)
+    {
+    }
+};
+
+struct CharacterClass {
+    Vector<UChar> m_matches;
+    Vector<CharacterRange> m_ranges;
+    Vector<UChar> m_matchesUnicode;
+    Vector<CharacterRange> m_rangesUnicode;
+};
+
+enum QuantifierType {
+    QuantifierFixedCount,
+    QuantifierGreedy,
+    QuantifierNonGreedy,
+};
+
+struct PatternTerm {
+    enum Type {
+        TypeAssertionBOL,
+        TypeAssertionEOL,
+        TypeAssertionWordBoundary,
+        TypePatternCharacter,
+        TypeCharacterClass,
+        TypeBackReference,
+        TypeForwardReference,
+        TypeParenthesesSubpattern,
+        TypeParentheticalAssertion,
+    } type;
+    bool invertOrCapture;
+    union {
+        UChar patternCharacter;
+        CharacterClass* characterClass;
+        unsigned subpatternId;
+        struct {
+            PatternDisjunction* disjunction;
+            unsigned subpatternId;
+            unsigned lastSubpatternId;
+            bool isCopy;
+        } parentheses;
+    };
+    QuantifierType quantityType;
+    unsigned quantityCount;
+    int inputPosition;
+    unsigned frameLocation;
+
+    PatternTerm(UChar ch)
+        : type(PatternTerm::TypePatternCharacter)
+    {
+        patternCharacter = ch;
+        quantityType = QuantifierFixedCount;
+        quantityCount = 1;
+    }
+
+    PatternTerm(CharacterClass* charClass, bool invert)
+        : type(PatternTerm::TypeCharacterClass)
+        , invertOrCapture(invert)
+    {
+        characterClass = charClass;
+        quantityType = QuantifierFixedCount;
+        quantityCount = 1;
+    }
+
+    PatternTerm(Type type, unsigned subpatternId, PatternDisjunction* disjunction, bool invertOrCapture)
+        : type(type)
+        , invertOrCapture(invertOrCapture)
+    {
+        parentheses.disjunction = disjunction;
+        parentheses.subpatternId = subpatternId;
+        parentheses.isCopy = false;
+        quantityType = QuantifierFixedCount;
+        quantityCount = 1;
+    }
+    
+    PatternTerm(Type type, bool invert = false)
+        : type(type)
+        , invertOrCapture(invert)
+    {
+        quantityType = QuantifierFixedCount;
+        quantityCount = 1;
+    }
+
+    PatternTerm(unsigned spatternId)
+        : type(TypeBackReference)
+        , invertOrCapture(invertOrCapture)
+    {
+        subpatternId = spatternId;
+        quantityType = QuantifierFixedCount;
+        quantityCount = 1;
+    }
+
+    static PatternTerm ForwardReference()
+    {
+        return PatternTerm(TypeForwardReference);
+    }
+
+    static PatternTerm BOL()
+    {
+        return PatternTerm(TypeAssertionBOL);
+    }
+
+    static PatternTerm EOL()
+    {
+        return PatternTerm(TypeAssertionEOL);
+    }
+
+    static PatternTerm WordBoundary(bool invert)
+    {
+        return PatternTerm(TypeAssertionWordBoundary, invert);
+    }
+    
+    bool invert()
+    {
+        return invertOrCapture;
+    }
+
+    bool capture()
+    {
+        return invertOrCapture;
+    }
+    
+    void quantify(unsigned count, QuantifierType type)
+    {
+        quantityCount = count;
+        quantityType = type;
+    }
+};
+
+struct PatternAlternative {
+    PatternAlternative(PatternDisjunction* disjunction)
+        : m_parent(disjunction)
+    {
+    }
+
+    PatternTerm& lastTerm()
+    {
+        ASSERT(m_terms.size());
+        return m_terms[m_terms.size() - 1];
+    }
+    
+    void removeLastTerm()
+    {
+        ASSERT(m_terms.size());
+        m_terms.shrink(m_terms.size() - 1);
+    }
+
+    Vector<PatternTerm> m_terms;
+    PatternDisjunction* m_parent;
+    unsigned m_minimumSize;
+    bool m_hasFixedSize;
+};
+
+struct PatternDisjunction {
+    PatternDisjunction(PatternAlternative* parent = 0)
+        : m_parent(parent)
+    {
+    }
+    
+    ~PatternDisjunction()
+    {
+        deleteAllValues(m_alternatives);
+    }
+
+    PatternAlternative* addNewAlternative()
+    {
+        PatternAlternative* alternative = new PatternAlternative(this);
+        m_alternatives.append(alternative);
+        return alternative;
+    }
+
+    Vector<PatternAlternative*> m_alternatives;
+    PatternAlternative* m_parent;
+    unsigned m_minimumSize;
+    unsigned m_callFrameSize;
+    bool m_hasFixedSize;
+};
+
+// You probably don't want to be calling these functions directly
+// (please to be calling newlineCharacterClass() et al on your
+// friendly neighborhood RegexPattern instance to get nicely
+// cached copies).
+CharacterClass* newlineCreate();
+CharacterClass* digitsCreate();
+CharacterClass* spacesCreate();
+CharacterClass* wordcharCreate();
+CharacterClass* nondigitsCreate();
+CharacterClass* nonspacesCreate();
+CharacterClass* nonwordcharCreate();
+
+struct RegexPattern {
+    RegexPattern(bool ignoreCase, bool multiline)
+        : m_ignoreCase(ignoreCase)
+        , m_multiline(multiline)
+        , m_numSubpatterns(0)
+        , m_maxBackReference(0)
+        , newlineCached(0)
+        , digitsCached(0)
+        , spacesCached(0)
+        , wordcharCached(0)
+        , nondigitsCached(0)
+        , nonspacesCached(0)
+        , nonwordcharCached(0)
+    {
+    }
+
+    ~RegexPattern()
+    {
+        deleteAllValues(m_disjunctions);
+        deleteAllValues(m_userCharacterClasses);
+    }
+
+    void reset()
+    {
+        m_numSubpatterns = 0;
+        m_maxBackReference = 0;
+
+        newlineCached = 0;
+        digitsCached = 0;
+        spacesCached = 0;
+        wordcharCached = 0;
+        nondigitsCached = 0;
+        nonspacesCached = 0;
+        nonwordcharCached = 0;
+
+        deleteAllValues(m_disjunctions);
+        m_disjunctions.clear();
+        deleteAllValues(m_userCharacterClasses);
+        m_userCharacterClasses.clear();
+    }
+
+    bool containsIllegalBackReference()
+    {
+        return m_maxBackReference > m_numSubpatterns;
+    }
+
+    CharacterClass* newlineCharacterClass()
+    {
+        if (!newlineCached)
+            m_userCharacterClasses.append(newlineCached = newlineCreate());
+        return newlineCached;
+    }
+    CharacterClass* digitsCharacterClass()
+    {
+        if (!digitsCached)
+            m_userCharacterClasses.append(digitsCached = digitsCreate());
+        return digitsCached;
+    }
+    CharacterClass* spacesCharacterClass()
+    {
+        if (!spacesCached)
+            m_userCharacterClasses.append(spacesCached = spacesCreate());
+        return spacesCached;
+    }
+    CharacterClass* wordcharCharacterClass()
+    {
+        if (!wordcharCached)
+            m_userCharacterClasses.append(wordcharCached = wordcharCreate());
+        return wordcharCached;
+    }
+    CharacterClass* nondigitsCharacterClass()
+    {
+        if (!nondigitsCached)
+            m_userCharacterClasses.append(nondigitsCached = nondigitsCreate());
+        return nondigitsCached;
+    }
+    CharacterClass* nonspacesCharacterClass()
+    {
+        if (!nonspacesCached)
+            m_userCharacterClasses.append(nonspacesCached = nonspacesCreate());
+        return nonspacesCached;
+    }
+    CharacterClass* nonwordcharCharacterClass()
+    {
+        if (!nonwordcharCached)
+            m_userCharacterClasses.append(nonwordcharCached = nonwordcharCreate());
+        return nonwordcharCached;
+    }
+
+    bool m_ignoreCase;
+    bool m_multiline;
+    unsigned m_numSubpatterns;
+    unsigned m_maxBackReference;
+    PatternDisjunction* m_body;
+    Vector<PatternDisjunction*, 4> m_disjunctions;
+    Vector<CharacterClass*> m_userCharacterClasses;
+
+private:
+    CharacterClass* newlineCached;
+    CharacterClass* digitsCached;
+    CharacterClass* spacesCached;
+    CharacterClass* wordcharCached;
+    CharacterClass* nondigitsCached;
+    CharacterClass* nonspacesCached;
+    CharacterClass* nonwordcharCached;
+};
+
+} } // namespace JSC::Yarr
+
+#endif
+
+#endif // RegexPattern_h